Mybatis Generator通用Join的实现(二)

借助Mybatis Generator我们可以实现通用的join关联和group聚合查询,通过在example类中加入一个内部类tableInfo存放数据表名和字段名称,避免了tk.mybatis或者mybatis-plus那种查询需要手写字段名称的弊端。

上一篇我们讲了通过自定义插件来实现mybatis的通用join查询,本文在此基础上进行了优化和精简,使该插件更符合开发人员的习惯。

下面将讲解该插件的使用。

举个常见的例子,用户表-用户角色表-角色表,这三个表都是通过主键id关键,表结构大致如下:

 1. 在generatorConfig.xml中加入我们的插件,并配置上这三个表

 然后执行mybatis generator,生成表实体和对应example文件

  然后我们就可以开始造了

 2.单表多字段查询

public void joinTableV2() {
        AuthUserExample userExp=new AuthUserExample();
        userExp.select(a->new String[] {a.tableInfo.getUserId(),a.tableInfo.getUserName()});
        userExp.createCriteria().andIsDelEqualTo(0);
        List<Tuple> userList=userDao.selectJoinByExample(userExp);
        for(Tuple tuple:userList) {
            AuthUser user=tuple.getObject(AuthUser.class);
            if(user!=null) {
                System.out.println(user.getUserId()+":"+user.getUserName());
            }
            else {
                System.out.println("null");
            }
        }
    }

控制台打印如下(返回结果只截图部分数据):

2020-05-15 23:47:01.659 DEBUG 9840 --- [nio-9000-exec-2] c.r.m.d.A.selectJoinByExample            : ==>  Preparing: select t0.user_id as t0_user_id,t0.user_name as t0_user_name from auth_user as t0 WHERE ( ( t0.is_del = ? ) ) 
2020-05-15 23:47:01.659 DEBUG 9840 --- [nio-9000-exec-2] c.r.m.d.A.selectJoinByExample            : ==> Parameters: 0(Integer)
2020-05-15 23:47:01.662 DEBUG 9840 --- [nio-9000-exec-2] c.r.m.d.A.selectJoinByExample            : <==      Total: 478
2020-05-15 23:47:01.665  INFO 9840 --- [nio-9000-exec-2] p.r.m.i.SqlStatementInterceptor          : c.r.m.d.AuthUserMapper.selectJoinByExample:6ms
805:赵彤我
806:于毅你
807:赵延死

 3.多表多字段查询,只查询用户表user_id和用户角色表的role_id两个字段

public void joinTableV2() {
        AuthUserExample userExp=new AuthUserExample();
        userExp.createCriteria().andIsDelEqualTo(0).andLoginAccountEqualTo("zjd");
        userExp.select(a->new String[] {a.tableInfo.getUserId()});
        
        AuthUserRoleExample userRoleExp=new AuthUserRoleExample();
        //关联
        userExp.innerJoin(userRoleExp)
        .on(a->a.tableInfo.getUserId(), a->a.equalTo(b->b.tableInfo.getUserId()))
        .select(ur->new String[] {ur.tableInfo.getRoleId()});
        
        List<Tuple> userList=userDao.selectJoinByExample(userExp);
        for(Tuple tuple:userList) {
            AuthUser user=tuple.getObject(AuthUser.class);
            AuthUserRole userRole=tuple.getObject(AuthUserRole.class);
            if(user!=null) {
                System.out.print(user.getUserId()+":");
            }
            else {
                System.out.print("null:");
            }
            System.out.println(userRole!=null?userRole.getRoleId():"null");
        }
    }
2020-05-15 23:56:40.852 DEBUG 9840 --- [nio-9000-exec-1] c.r.m.d.A.selectJoinByExample            : ==>  Preparing: select t0.user_id as t0_user_id,t1.role_id as t1_role_id from auth_user as t0 inner join auth_user_role as t1 on t0.user_id = t1.user_id WHERE ( ( t0.is_del = ? and t0.login_account = ? ) ) 
2020-05-15 23:56:40.852 DEBUG 9840 --- [nio-9000-exec-1] c.r.m.d.A.selectJoinByExample            : ==> Parameters: 0(Integer), zjd(String)
2020-05-15 23:56:40.856 DEBUG 9840 --- [nio-9000-exec-1] c.r.m.d.A.selectJoinByExample            : <==      Total: 11
2020-05-15 23:56:40.857  INFO 9840 --- [nio-9000-exec-1] p.r.m.i.SqlStatementInterceptor          : c.r.m.d.AuthUserMapper.selectJoinByExample:9ms
956:2
956:93
956:309
956:310
956:117
956:118
956:120
956:121
956:122
956:123
956:124

4.多表多字段复杂查询(查询用户id及关联的角色表数据)

public void joinTableV2() {
        AuthUserExample userExp=new AuthUserExample();
        userExp.createCriteria().andIsDelEqualTo(0).andLoginAccountEqualTo("zjd");
        userExp.select(a->new String[] {a.tableInfo.getUserId()});
        
        AuthRoleExample roleExp=new AuthRoleExample();
        roleExp.createCriteria().andIsDelEqualTo(0);
        
        //“用户角色表”关联“角色表”
        AuthUserRoleExample userRoleExp=new AuthUserRoleExample();
        userRoleExp.leftJoin(roleExp)
        .on(a->a.tableInfo.getRoleId(), a->a.equalTo(b->b.tableInfo.getRoleId()))
        //可在on关联中加入条件判断
        .and(a->a.tableInfo.getCreateTime(), a->a.isNotNull())
        //查询角色表所有字段
        .select(a->a.tableInfo.allColumns());
        
        //“用户表”关联“用户角色表”
        userExp.innerJoin(userRoleExp)
        .on(a->a.tableInfo.getUserId(), a->a.equalTo(b->b.tableInfo.getUserId()));
        
        List<Tuple> userList=userDao.selectJoinByExample(userExp);
        for(Tuple tuple:userList) {
            AuthUser user=tuple.getObject(AuthUser.class);
            AuthRole role=tuple.getObject(AuthRole.class);
            if(user!=null) {
                System.out.print(user.getUserId()+":");
            }
            else {
                System.out.print("null:");
            }
            System.out.println(role!=null?(role.getRoleId()+","+role.getRoleName()+","+role.getCreateTime()):"null");
        }
        
    }
2020-05-16 01:04:52.934 DEBUG 3360 --- [nio-9000-exec-2] c.r.m.d.A.selectJoinByExample            : ==>  Preparing: select t0.user_id as t0_user_id,t2.role_id as t2_role_id,t2.role_name as t2_role_name,t2.remark as t2_remark,t2.role_type as t2_role_type,t2.is_allow as t2_is_allow,t2.role_sort as t2_role_sort,t2.second_menu as t2_second_menu,t2.first_menu as t2_first_menu,t2.is_del as t2_is_del,t2.create_time as t2_create_time,t2.create_user as t2_create_user,t2.update_time as t2_update_time,t2.update_user as t2_update_user from auth_user as t0 inner join auth_user_role as t1 on t0.user_id = t1.user_id left join auth_role as t2 on t1.role_id = t2.role_id and t2.create_time is not null WHERE ( ( t0.is_del = ? and t0.login_account = ? ) ) and ( ( t2.is_del = ? ) ) 
2020-05-16 01:04:52.934 DEBUG 3360 --- [nio-9000-exec-2] c.r.m.d.A.selectJoinByExample            : ==> Parameters: 0(Integer), zjd(String), 0(Integer)
2020-05-16 01:04:52.945 DEBUG 3360 --- [nio-9000-exec-2] c.r.m.d.A.selectJoinByExample            : <==      Total: 10
2020-05-16 01:04:52.947  INFO 3360 --- [nio-9000-exec-2] p.r.m.i.SqlStatementInterceptor          : c.r.m.d.AuthUserMapper.selectJoinByExample:16ms
956:93,超级管理员,2020-01-06 23:37:01.0
956:309,反馈平台普通用户,2020-04-07 23:16:46.0
956:310,反馈平台开发用户,2020-04-07 23:18:50.0
956:117,采购员,2020-01-09 09:41:20.0
956:118,采购管理员,2020-01-09 15:33:46.0
956:120,采购领导,2020-01-09 20:58:57.0
956:121,总公司管理员,2020-01-09 21:00:59.0
956:122,总公司领导,2020-01-09 21:02:10.0
956:123,总公司归口部门领导,2020-01-09 21:03:16.0
956:124,总公司纪检监察领导,2020-01-09 21:03:53.0

5. 单表聚合查询(查询各系统的用户数量并且倒序显示用户数量大于10的)

public void joinTableV2() {
        AuthUserExample userExp=new AuthUserExample();
        userExp.createCriteria().andIsDelEqualTo(0).andSystemTypeIsNotNull();
        
        userExp.select(a->new String[]{a.tableInfo.getSystemType()})
        .selectAggregation(a->a.count(b->new String[] {b.tableInfo.getUserId()}))
        .groupBy(a->new String[] {a.tableInfo.getSystemType()})
        .having(a->a.count(b->new String[] {b.tableInfo.getUserId()}), a->a.greaterThan(10))
        .orderByAggregationDesc(a->a.count(b->new String[] {b.tableInfo.getUserId()}))
        ;
        
        List<Tuple> userList=userDao.selectJoinByExample(userExp);
        for(Tuple tuple:userList) {
            AuthUser user=tuple.getObject(AuthUser.class);
            AuthUser countUser=tuple.getCount(AuthUser.class);
            if(user!=null) {
                System.out.print(user.getSystemType()+":");
            }
            else {
                System.out.print("null:");
            }
            System.out.println(countUser!=null?countUser.getUserId():"null");
        }
        
    }
2020-05-16 00:30:10.174 DEBUG 3360 --- [nio-9000-exec-5] c.r.m.d.A.selectJoinByExample            : ==>  Preparing: select t0.system_type as t0_system_type,count(t0.user_id) as _count_t0_user_id from auth_user as t0 WHERE ( ( t0.is_del = ? and t0.system_type is not null ) ) group by t0.system_type having count( t0.user_id ) > ? order by count(t0.user_id) desc 
2020-05-16 00:30:10.175 DEBUG 3360 --- [nio-9000-exec-5] c.r.m.d.A.selectJoinByExample            : ==> Parameters: 0(Integer), 10(Integer)
2020-05-16 00:30:10.177 DEBUG 3360 --- [nio-9000-exec-5] c.r.m.d.A.selectJoinByExample            : <==      Total: 3
2020-05-16 00:30:10.177  INFO 3360 --- [nio-9000-exec-5] p.r.m.i.SqlStatementInterceptor          : c.r.m.d.AuthUserMapper.selectJoinByExample:5ms
0:251
3:176
1:51

 6.多表关联聚合查询(查询各角色拥有的用户数量)

public void joinTableV2() {
        AuthUserExample userExp=new AuthUserExample();
        userExp.createCriteria().andIsDelEqualTo(0).andSystemTypeIsNotNull();
        userExp.disableSelect().selectAggregation(a->a.count(b->new String[] {b.tableInfo.getUserId()}));
        
        AuthUserRoleExample urExp=new AuthUserRoleExample();
        userExp.innerJoin(urExp).on(a->a.tableInfo.getUserId(), a->a.equalTo(b->b.tableInfo.getUserId()))
        .groupBy(a->new String[] {a.tableInfo.getRoleId()})
        .select(a->new String[] {a.tableInfo.getRoleId()});
        
        List<Tuple> userList=userDao.selectJoinByExample(userExp);
        for(Tuple tuple:userList) {
            AuthUserRole userRole=tuple.getObject(AuthUserRole.class);
            AuthUser countUser=tuple.getCount(AuthUser.class);
            if(userRole!=null) {
                System.out.print(userRole.getRoleId()+":");
            }
            else {
                System.out.print("null:");
            }
            System.out.println(countUser!=null?countUser.getUserId():"null");
        }
        
    }
2020-05-16 00:41:56.389 DEBUG 3360 --- [nio-9000-exec-4] c.r.m.d.A.selectJoinByExample            : ==>  Preparing: select count(t0.user_id) as _count_t0_user_id,t1.role_id as t1_role_id from auth_user as t0 inner join auth_user_role as t1 on t0.user_id = t1.user_id WHERE ( ( t0.is_del = ? and t0.system_type is not null ) ) group by t1.role_id 
2020-05-16 00:41:56.389 DEBUG 3360 --- [nio-9000-exec-4] c.r.m.d.A.selectJoinByExample            : ==> Parameters: 0(Integer)2020-05-16 00:41:56.400 DEBUG 3360 --- [nio-9000-exec-4] c.r.m.d.A.selectJoinByExample            : <==      Total: 200
2020-05-16 00:41:56.403  INFO 3360 --- [nio-9000-exec-4] p.r.m.i.SqlStatementInterceptor          : c.r.m.d.AuthUserMapper.selectJoinByExample:17ms
93:10
132:1
240:26
219:33
220:17
223:136
135:143

想要验证一下数据正确性的话,可以到数据库里执行一下sql,发现结果是一样的

该插件帮助我们避免了在开发过程中手写多表查询sql的麻烦,但是该插件也不是万能的,其他更复杂的查询还是需要我们自己动手写的。

猜你喜欢

转载自www.cnblogs.com/RexSheng/p/12897926.html