通常,我们使用Mybatis实现join表关联的时候,一般都是通过在xml或注解里写自定义sql实现。

本文通过Mybatis Generator的插件功能新增一个JoinPlugin插件,只要在配置文件里加上该插件就可以使用。无其他第三方依赖。如下图:

该插件符合mbg plugin即插即用的特点,不影响生成的实体类,只对生成的Example文件做少量变动(新增一个内部类)。

首选我们看一下使用效果,如果符合你的要求,请关注支持。

/**
* 简单join查询示例
* select t0.user_id as t0_user_id,t0.user_name as t0_user_name,t0.login_account as t0_login_account,t0.login_password as t0_login_password,
* t0.user_sex as t0_user_sex,t0.user_email as t0_user_email,t0.user_mobile as t0_user_mobile,t0.user_avatar as t0_user_avatar,
* t0.user_company as t0_user_company,t0.user_dept as t0_user_dept,t0.is_del as t0_is_del,t0.is_admin as t0_is_admin,
* t0.system_type as t0_system_type,t0.last_login_time as t0_last_login_time,t0.create_time as t0_create_time,t0.create_user as t0_create_user,
* t0.update_time as t0_update_time,t0.update_user as t0_update_user,
* t2.role_id as t2_role_id,t2.role_name as t2_role_name
* 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 t2.role_id = t1.role_id
* where ( ( t0.user_id is not null and ( t0.create_time is not null or t0.create_user is not null ) ) ) and ( t1.user_id <>999999 and t1.role_id >=1 )
* order by t2.role_id desc,t0.create_time
* limit 10,100
*/
public void joinTable() {
AuthUserExample authUserExample=new AuthUserExample();
AuthUserExample.Criteria criteria=authUserExample.createCriteria();
//where条件
criteria.andUserIdIsNotNull();
criteria.createOrCriteria().andCreateTimeIsNotNull().andCreateUserIsNotNull(); //关联user_role
AuthUserRoleExample urExample=new AuthUserRoleExample();
//where中user_role表的条件
urExample.createCriteria().andUserIdNotEqualTo(999999).andRoleIdGreaterThanOrEqualTo(1);
criteria.createJoinCriteria()
.innerJoinTable(urExample)
//使用User表的user_id关联user_role表的user_id
.on(a->a.getUserId(), a->a.equalTo(b->b.tableInfo.getUserId())); //关联role
AuthRoleExample roleExample=new AuthRoleExample();
criteria.createJoinCriteria()
.leftJoinTable(roleExample)
//使用role表的role_id关联user_role表的role_id
.on(a->a.tableInfo.getRoleId(), a->a.equalTo(b->b.tableInfo.getRoleId()), urExample)
//先按照role表的role_id降序
.orderByDesc(a->a.tableInfo.getRoleId())
//再按照user表的create_time升序
.orderByFirstTable(a->a.getCreateTime())
//跳过前10条
.skip(10)
//取100条记录
.take(100)
//只查询role表的role_id和role_name两个字段
.select(a->new String[] {a.tableInfo.getRoleId(),a.tableInfo.getRoleName()}); //执行查询
List<Tuple> userList=userDao.selectJoinByExample(authUserExample);
int totalItemCount=(int) userDao.countJoinByExample(authUserExample);
System.out.println(userList.size()+",total:"+totalItemCount);
for(Tuple tuple:userList) {
AuthUser authUser=tuple.getObject(AuthUser.class);
AuthUserRole authUserRole=tuple.getObject(AuthUserRole.class);
AuthRole authRole=tuple.getObject(AuthRole.class);
totalItemCount++;
}
}

控制台打印内容如下:

2020-04-23 23:09:16.326  INFO 10308 --- [nio-9000-exec-4] p.r.m.i.SqlStatementInterceptor          : ===>sql:select t0.user_id as t0_user_id,t0.user_name as t0_user_name,t0.login_account as t0_login_account,t0.login_password as t0_login_password,t0.user_sex as t0_user_sex,t0.user_email as t0_user_email,t0.user_mobile as t0_user_mobile,t0.user_avatar as t0_user_avatar,t0.user_company as t0_user_company,t0.user_dept as t0_user_dept,t0.is_del as t0_is_del,t0.is_admin as t0_is_admin,t0.system_type as t0_system_type,t0.last_login_time as t0_last_login_time,t0.create_time as t0_create_time,t0.create_user as t0_create_user,t0.update_time as t0_update_time,t0.update_user as t0_update_user,t0.`type` as t0_type,t0.title as t0_title,t0.bz as t0_bz,t2.role_id as t2_role_id,t2.role_name as t2_role_name
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 t2.role_id = t1.role_id
where ( ( t0.user_id is not null and ( t0.create_time is not null or t0.create_user is not null ) ) ) and ( t1.user_id <>999999 and t1.role_id >=1 )
order by t2.role_id desc,t0.create_time
limit 10,100
2020-04-23 23:09:16.329 DEBUG 10308 --- [nio-9000-exec-4] c.r.m.d.A.selectJoinByExample : ==> Preparing: select t0.user_id as t0_user_id,t0.user_name as t0_user_name,t0.login_account as t0_login_account,t0.login_password as t0_login_password,t0.user_sex as t0_user_sex,t0.user_email as t0_user_email,t0.user_mobile as t0_user_mobile,t0.user_avatar as t0_user_avatar,t0.user_company as t0_user_company,t0.user_dept as t0_user_dept,t0.is_del as t0_is_del,t0.is_admin as t0_is_admin,t0.system_type as t0_system_type,t0.last_login_time as t0_last_login_time,t0.create_time as t0_create_time,t0.create_user as t0_create_user,t0.update_time as t0_update_time,t0.update_user as t0_update_user,t0.`type` as t0_type,t0.title as t0_title,t0.bz as t0_bz,t2.role_id as t2_role_id,t2.role_name as t2_role_name 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 t2.role_id = t1.role_id WHERE ( ( t0.user_id is not null and ( t0.create_time is not null or t0.create_user is not null ) ) ) and ( t1.user_id <>? and t1.role_id >=? ) order by t2.role_id desc,t0.create_time limit 10,100
2020-04-23 23:09:16.330 DEBUG 10308 --- [nio-9000-exec-4] c.r.m.d.A.selectJoinByExample : ==> Parameters: 999999(Integer), 1(Integer)
2020-04-23 23:09:16.361 DEBUG 10308 --- [nio-9000-exec-4] c.r.m.d.A.selectJoinByExample : <== Total: 100
2020-04-23 23:09:16.367 INFO 10308 --- [nio-9000-exec-4] p.r.m.i.SqlStatementInterceptor : c.r.m.d.AuthUserMapper.selectJoinByExample:41ms
2020-04-23 23:09:16.371 INFO 10308 --- [nio-9000-exec-4] p.r.m.i.SqlStatementInterceptor : ===>sql:select count(*)
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 t2.role_id = t1.role_id
where ( ( t0.user_id is not null and ( t0.create_time is not null or t0.create_user is not null ) ) ) and ( t1.user_id <>999999 and t1.role_id >=1 )
2020-04-23 23:09:16.375 DEBUG 10308 --- [nio-9000-exec-4] c.r.m.d.A.countJoinByExample : ==> Preparing: select count(*) 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 t2.role_id = t1.role_id WHERE ( ( t0.user_id is not null and ( t0.create_time is not null or t0.create_user is not null ) ) ) and ( t1.user_id <>? and t1.role_id >=? )
2020-04-23 23:09:16.376 DEBUG 10308 --- [nio-9000-exec-4] c.r.m.d.A.countJoinByExample : ==> Parameters: 999999(Integer), 1(Integer)
2020-04-23 23:09:16.385 DEBUG 10308 --- [nio-9000-exec-4] c.r.m.d.A.countJoinByExample : <== Total: 1
2020-04-23 23:09:16.385 INFO 10308 --- [nio-9000-exec-4] p.r.m.i.SqlStatementInterceptor : c.r.m.d.AuthUserMapper.countJoinByExample:14ms
100,total:5190

通过上面简单例子我们可以看到,生成的sql是完全符合预期的,并且不需要我们额外的手写sql了。

该插件特点:

1.可关联多表,on多个字段关联,on多种条件查询,例如:left join t_role as t1 on t0.role_id=t1.role_id and t0.sys_type=t1.role_type and t1.is_del=0 and t1.role_type='T'

2.可自定义表别名

3.sql中的所有表都可自定义要查询的字段,表字段多时,指定字段查询明显提高效率

4.分页、多表排序支持,函数式编程写法

5.支持in,exists等子查询

6.mybatis原生特性,无其他依赖

该插件原理:

由于mbg每个表都生成一个xml,在xml里自动组装生成的sql,并返回map对象。通过mybatis的拦截器拦截返回结果,将map转换成不同表的实体对象然后组装返回到一个类Tuple中。

本插件初衷:为了简化开发人员的数据库sql繁琐查询工作及改善mybatis写join关联时只能自定义的状况。开发过程中当表结构改变时,所有手写自定义的sql里的字段都要改一遍。

另外,mbg1.4.0的dynamic-sql不怎么好用,这么久了更新这样一个新版本很失望。

Mybatis Generator通用Join的实现的更多相关文章

  1. springboot中通用mapper结合mybatis generator的使用

    通用mapper就是指的是  tk.mybatis  包下的.这个是通用mapper就是说自动生成的dao层需要继承这个框架提供的mapper类.而我们之前用的org.mybatis这个最开始是普通的 ...

  2. Mybatis通用Join的实现(最终版)

    你是否还在为mybatis的多表关联查询而写xml烦恼,是否还在为动态组装查询条件烦恼,是否还在为此没有合适的解决方案烦恼? mybatis-extension插件,解决开发过程中需要多表关联时需手写 ...

  3. MyBatis Generator 自动生成的POJO对象的使用(一)

    MyBatis Generator 会自动生成以下几种类型的对象(除非你使用MyBatis3DynamicSql 的运行环境): Java Model Objects(总是生成) SQL Map Fi ...

  4. mybatis Generator生成代码及使用方式

    本文原创,转载请注明:http://www.cnblogs.com/fengzheng/p/5889312.html 为什么要有mybatis mybatis 是一个 Java 的 ORM 框架,OR ...

  5. MyBatis Generator 详解

    MyBatis Generator中文文档 MyBatis Generator中文文档地址:http://mbg.cndocs.tk/ 该中文文档由于尽可能和原文内容一致,所以有些地方如果不熟悉,看中 ...

  6. MyBatis Generator 详解 【转来纯为备忘】

    版权声明:版权归博主所有,转载请带上本文链接!联系方式:abel533@gmail.com   目录(?)[+] MyBatis Generator中文文档 运行MyBatis Generator X ...

  7. mybatis Generator配置文件详解

    这里按照配置的顺序对配置逐个讲解,更细的内容可以配合中文文档参照. 1. 配置文件头 <?xml version="1.0" encoding="UTF-8&quo ...

  8. Mybatis Generator(定制化)代码生成器

    1.使用Mapper专用的MyBatis Generator插件 通用Mapper在1.0.0版本的时候增加了MyBatis Generator(以下简称MBG)插件,使用该插件可以很方便的生成实体类 ...

  9. mybatis.generator.configurationFile

    mybatis.generator.configurationFile 有一个更好的配置方法,可以不用在generateConfig.xml里面写死驱动的地址:如果你的mybatis连接也是在pom. ...

随机推荐

  1. 吴恩达最新TensorFlow专项课程开放注册,你离TF Boy只差这一步

    不需要 ML/DL 基础,不需要深奥数学背景,初学者和软件开发者也能快速掌握 TensorFlow.掌握人工智能应用的开发秘诀. 以前,吴恩达的机器学习课程和深度学习课程会介绍很多概念与知识,虽然也会 ...

  2. Activiti7流程定义

    一.什么是流程定义 流程定义是线下bpmn2.0标椎去描述业务流程,通常使用activiti-explorer(web控制台)或 activiti-eclipse-designer 插件对业务流程进行 ...

  3. AC自动机(初步学习)

    一开始讲AC自动机就是在字典树上做一个KMP,吓得我感觉好难,不过了解了以后,感觉也就是有点难度,不吓人. 它只是在字典树上用了KMP的思想 典型问题:给n个模式串和一个文本串,问有多少个模式串在文本 ...

  4. python之常用模块ymal

    在学习python如何操作yml文件之前,我们先科普一下yml的格式 yaml是专门写配置文件的语言,非常简洁和强大,比json更加方便 YAML 语言(发音 /ˈjæməl/ )的设计目标,就是方便 ...

  5. Python python 五种数据类型--字符串

    # python 字符串的初始化 var1 = 'hello,world' # python 字符串为不可变类型 var2= var1* 2 print(var1) #hello,world prin ...

  6. iOS 图片加载和处理

    一.图片显示 图片的显示分为三步:加载.解码.渲染.解码和渲染是由 UIKit 进行,通常我们操作的只有加载. 以 UIImageView 为例.当其显示在屏幕上时,需要 UIImage 作为数据源. ...

  7. [WPF]是时候将WPF控件库从.Net Framework升级到.NET Core 3.1

    1. 升级到Core的好处 去年中我曾考虑将我的控件库项目Kino.Toolkit.Wpf升级到.NET Core,不过很快放弃了,因为当时.NET Core是预览版,编译WPF还需要使用最新的Vis ...

  8. CodeForces - 817B(分类讨论 + 排列组合)

    题目链接 思路如下 这一题是:最菜的队伍只有三个人组成,我们只需对排序后的数组的 前三个元素进行分类讨论即可: a[3] != a[2] && a[3] != ar[1] a[3] = ...

  9. C/C++知识总结 四 循环与分支语句

    C/C++循环与分支语句 循环与分支语句的意义 关系运算符.逻辑运算符 for循环和嵌套for循环(基于范围for循环) while循环与do while循环 分支if语句.if else语句.if ...

  10. Java 程序该怎么优化?(技巧篇)

    搬砖者:为什么程序总是那么慢?它现在到底在干什么?时间都花到哪里去了? 面试官:简单谈谈 Java 程序性能优化? 1. 字符串处理优化,乃优化之源. 研发过程中,String 的 API 用的应该是 ...