mybatis-plus中wrapper条件查询(跨表),权限设定

    技术2022-07-11  90

    因为是第一次做真实大型项目吧,涉及到功能的权限需要用到mybatis-plus中一些东西,写博客总结一下。

    跨表查询

    首选需求:撇开需求说功能都是扯犊子,需求就是完成条件查询,然后根据用户的部门号,同一级别只能查询自己的,上级可以看到下级的 先去mapper里面完成配置文件 我在这里写一个对比的事情 这是我们普通的功能实现

    <select id="queryPageMap" resultType="map" parameterType="map"> SELECT a.id AS id, a.task_type AS taskType, a.task_id AS taskId, a.operate_unit_id AS operateUnitId, a.regulatory_unit_id AS regulatoryUnitId, a.sign_unit_id AS signUnitId, a.road_code AS roadCode, a.pile_start AS pileStart, a.pile_end AS pileEnd, a.problem_desc AS problemDesc, a.deal_require AS dealRequire, a.end_date AS endDate, a.sign_unit_id AS signUnitId, a.sign_person_id AS signPersonId, a.sign_date AS signDate, a.state AS state, a.creator AS creator, a.create_date AS createDate, a.updater AS updater, a.update_date AS updateDate, b.code AS code, ( SELECT d.NAME FROM sys_dept d WHERE a.sign_unit_id = d.id ) AS signName, d.NAME as regulatoryName, con.name as operateName, u.name as userName, ( SELECT u.username FROM sys_user u WHERE a.creator = u.id ) AS creatorName, ( SELECT u.username FROM sys_user u WHERE a.updater = u.id ) AS updateName, b.maintenance_type_id as maintenanceTypeId FROM model_defec_rectification_notice a LEFT JOIN model_production_plan b ON b.id = a.task_id LEFT JOIN sys_dept d ON a.regulatory_unit_id = d.id LEFT JOIN base_construction_unit con ON a.operate_unit_id = con.id LEFT JOIN sys_role u ON a.sign_person_id = u.id WHERE 1 =1 <if test="id != null and id != ''"> and a.id=#{id} </if> <if test="taskId != null and taskId != ''"> and a.task_id=#{taskId} </if> <if test="regulatoryUnitId != null and regulatoryUnitId != ''"> and a.regulatory_unit_id=#{regulatoryUnitId} </if> <if test="operateUnitId != null and operateUnitId != ''"> and a.operate_unit_id=#{operateUnitId} </if> <if test="pileStart != null and pileStart !=''"> and (a.pile_start >= #{pileStart} or a.pile_end >= #{pileStart}) </if> <if test="pileEnd != null and pileEnd !=''"> and (a.pile_start <= #{pileEnd} or a.pile_end <= #{pileEnd}) </if> <if test="signUnitId != null and signUnitId != ''"> and a.sign_unit_id=#{signUnitId} </if> <if test="signPersonId != null and signPersonId != ''"> and a.sign_person_id=#{signPersonId} </if> <if test="state != null and state != ''"> and a.state=#{state} </if> limit #{offset},#{sizee} </select>

    上面是我一个比较简单的条件查询,通过join到各个表,然后选择条件查询,然后最后做一个分页 然后下面是使用mybatis-plus之后的查询和分页 首选也是在mapper里面

    <select id="queryPageMaps" resultType="map" parameterType="map"> SELECT a.id AS id, a.task_type AS taskType, a.task_id AS taskId, a.operate_unit_id AS operateUnitId, a.regulatory_unit_id AS regulatoryUnitId, a.road_code AS roadCode, a.pile_start AS pileStart, a.pile_end AS pileEnd, a.problem_desc AS problemDesc, a.deal_require AS dealRequire, a.end_date AS endDate, a.sign_unit_id AS signUnitId, a.sign_person_id AS signPersonId, a.sign_date AS signDate, a.state AS state, a.creator AS creator, a.create_date AS createDate, a.updater AS updater, a.update_date AS updateDate, b.code AS code, ( SELECT d.NAME FROM sys_dept d WHERE a.sign_unit_id = d.id ) AS signName, d.NAME as regulatoryName, con.name as operateName, u.name as userName, ( SELECT u.username FROM sys_user u WHERE a.creator = u.id ) AS creatorName, ( SELECT u.username FROM sys_user u WHERE a.updater = u.id ) AS updateName, b.maintenance_type_id as maintenanceTypeId FROM model_defec_rectification_notice a LEFT JOIN model_production_plan b ON b.id = a.task_id LEFT JOIN sys_dept d ON a.regulatory_unit_id = d.id LEFT JOIN base_construction_unit con ON a.operate_unit_id = con.id LEFT JOIN sys_role u ON a.sign_person_id = u.id ${ew.customSqlSegment} </select>

    就是和普通的相比的话就是将where的条件给省略了放在了方法里面,使用${ew.customSqlSegment}来代替,下面是一个比较好用的mybatis插件,可以直接找到制定的方法,直接可以从java里面方法到mapper的配置文件

    @CustomizeDataFilter(deptId = "sign_unit_id") public IPage<Map> getListByParam1(Map<String, Object> params) { Map<String,Object> res = new HashMap<>(); try { IPage<Map> page = this.getPage(params, Map.class); QueryWrapper<ModelDefecRectificationNoticeEntity> query = new QueryWrapper(); query.and(params.get("taskId")!=null&&!"".equals(params.get("taskId")),t ->t.eq(Objects.nonNull(params.get("taskId")) && StringUtils.isNotBlank(String.valueOf(params.get("taskId"))),"a.task_id",params.get("taskId"))) .and(params.get("regulatoryUnitId")!=null&&!"".equals(params.get("regulatoryUnitId")),t ->t.eq(Objects.nonNull(params.get("regulatoryUnitId")) && StringUtils.isNotBlank(String.valueOf(params.get("regulatoryUnitId"))),"a.regulatory_unit_id",params.get("regulatoryUnitId"))) .and(params.get("state")!=null&&!"".equals(params.get("state")),t ->t.eq(Objects.nonNull(params.get("state")) && StringUtils.isNotBlank(String.valueOf(params.get("state"))),"a.state",params.get("state"))) .and(params.get("operateUnitId")!=null&&!"".equals(params.get("operateUnitId")),t ->t.eq(Objects.nonNull(params.get("operateUnitId")) && StringUtils.isNotBlank(String.valueOf(params.get("operateUnitId"))),"a.operate_unit_id",params.get("operateUnitId"))) .and(params.get("signUnitId")!=null&&!"".equals(params.get("signUnitId")),t ->t.eq(Objects.nonNull(params.get("signUnitId")) && StringUtils.isNotBlank(String.valueOf(params.get("signUnitId"))),"a.sign_unit_id",params.get("signUnitId"))) .and(params.get("signPersonId")!=null&&!"".equals(params.get("signPersonId")),t ->t.eq(Objects.nonNull(params.get("signPersonId")) && StringUtils.isNotBlank(String.valueOf(params.get("signPersonId"))),"a.sign_person_id",params.get("signPersonId"))) .and(params.get("pileStart")!=null&&!"".equals(params.get("pileStart")),t ->t.gt(Objects.nonNull(params.get("pileStart")) && StringUtils.isNotBlank(String.valueOf(params.get("pileStart"))),"pile_start",params.get("pileStart")).or().gt("a.pile_end",params.get("pileStart"))) .and(params.get("pileEnd")!=null&&!"".equals(params.get("pileEnd")),t ->t. lt(Objects.nonNull(params.get("pileEnd")) && StringUtils.isNotBlank(String.valueOf(params.get("pileEnd"))),"pile_end",params.get("pileEnd")).or().lt("a.pile_start",params.get("pileEnd"))); IPage<Map> mapIPage = modelDefecRectificationNoticeMapper.queryPageMaps(page, query, params); return mapIPage; }catch (Exception e) { e.printStackTrace(); } return null; }

    让我们一行一行的来解释这个方法的代码。 IPage<Map> page = this.getPage(params, Map.class);首选是先规定一下这个需要返回的IPage的类型,其中IPage是一个已经被封装好了类,是用来前后端进行传值的时候的一个类型,

    @Deprecated default String[] descs() { return null; } @Deprecated default String[] ascs() { return null; } List<OrderItem> orders(); default Map<Object, Object> condition() { return null; } default boolean optimizeCountSql() { return true; } default boolean isSearchCount() { return true; } default long offset() { return this.getCurrent() > 0L ? (this.getCurrent() - 1L) * this.getSize() : 0L; } default long getPages() { if (this.getSize() == 0L) { return 0L; } else { long pages = this.getTotal() / this.getSize(); if (this.getTotal() % this.getSize() != 0L) { ++pages; } return pages; } } default IPage<T> setPages(long pages) { return this; } List<T> getRecords(); IPage<T> setRecords(List<T> var1); long getTotal(); IPage<T> setTotal(long var1); long getSize(); IPage<T> setSize(long var1); long getCurrent(); IPage<T> setCurrent(long var1); default <R> IPage<R> convert(Function<? super T, ? extends R> mapper) { List<R> collect = (List)this.getRecords().stream().map(mapper).collect(Collectors.toList()); return this.setRecords(collect); }

    他的源码看着多其实就一点,就是将我们常用的一些类封装进去,一些我们常用的集合类封装进去,在我们传到前段多种的数据的时候可以只是通过传递一个IPage对象就可以完成了。

    QueryWrapper<ModelDefecRectificationNoticeEntity> query = new QueryWrapper();在这里我们new了一个QueryWrapper方便后面实现查询功能。query .and(params.get("taskId")!=null&&!"".equals(params.get("taskId")),t ->t.eq(Objects.nonNull(params.get("taskId")) && StringUtils.isNotBlank(String.valueOf(params.get("taskId"))),"a.task_id",params.get("taskId")))首先使用and来连接,跟where条件中的and一样的,首先判断and的条件是否是必要的存在的,如果是map中的指定的key是存在且不为空才会在查询的时候实现制定的where操作。然后就是t ->t.eq使用箭头函数判定规则是是否相等不是其他判定方法。Objects.nonNull(params.get("taskId")) && StringUtils.isNotBlank(String.valueOf(params.get("taskId")))其实我在写的时候感觉这一句没有作用,但是在执行的时候出现了where条件后面的值为空的情况,然后就添加这一句进行反复判断map中指定的key值是否是存在的且不为空。"a.task_id",params.get("taskId")这一句是真正的比较,在这里可以实现的多表查询,在where条件中因为有多张表,同一个属性名可能在多张表里面,于是我们可以使用在where中写的表的别名,直接去引用就可以了,我觉得这也是他比一般的mybatis的要好用的地方,当然他的生成代码也很好用,后面我会介绍的。.and(params.get("pileStart")!=null&&!"".equals(params.get("pileStart")),t ->t.gt(Objects.nonNull(params.get("pileStart")) && StringUtils.isNotBlank(String.valueOf(params.get("pileStart"))),"pile_start",params.get("pileStart")).or().gt("a.pile_end",params.get("pileStart")))这个就是需要实现的功能就是比较桩号,如果起点小于搜索出来的值得起点桩号和终点桩号只要有一个小才会进行条件查询,所以这里进行一个大于或者小于的判断,还有一个或者情况使用了or。IPage<Map> mapIPage = modelDefecRectificationNoticeMapper.queryPageMaps(page, query, params);这就是我们实现查询的方法,给你们看一下mapper中方法头 旁边那个黑色的鸟就是我的插件实现了一个可以直接从mapper进入xml之中的功能,其中就有在传到后台时候wrapper自己封的分页, 然后我们如何实现分页查询呢? 我们来看源码 IPage<Map> page = this.getPage(params, Map.class); 在这里里面点开getPage方法 protected <T> IPage<T> getPage(Map<String, Object> params, Class<T> resultType) { return this.getPage(params, "", false, resultType); }

    然后继续点击getPage方法

    protected <T> IPage<T> getPage(Map<String, Object> params, String defaultOrderField, boolean isAsc, Class<T> resultType) { long curPage = 1L; long limit = 10L; if (params.get("page") != null) { curPage = Long.parseLong(String.valueOf(params.get("page"))); } if (params.get("limit") != null) { limit = Long.parseLong(String.valueOf(params.get("limit"))); } Page<T> page = new Page(curPage, limit); if (StringUtils.isNotBlank(defaultOrderField)) { try { String orderFieldName = com.baomidou.mybatisplus.core.toolkit.StringUtils.underlineToCamel(defaultOrderField); if (resultType.getField(orderFieldName) != null) { OrderItem orderItem = new OrderItem(); orderItem.setAsc(isAsc); orderItem.setColumn(defaultOrderField); page.addOrder(new OrderItem[]{orderItem}); } } catch (NoSuchFieldException var12) { ; } } return page; }

    就可以看到其实他的两个参数分别是page,limit这两个参数就是操控分页的参数,于是我们只需要在前端传到后台page和limit两个参数就可以了 然后就是权限为了实现权限的功能

    权限设定

    @CustomizeDataFilter(deptId = "sign_unit_id")

    通过这个注解来完成的,一般会放在这里一个部门号之类的,同一级别只能看这个字段是自己的部门id的,当然上级也是可以看的到下级部门的。

    Processed: 0.009, SQL: 9