标签:rtt 关联查询 分页查询 返回 intercept des 自定义 inand table
你是否还在为mybatis的多表关联查询而写xml烦恼,是否还在为动态组装查询条件烦恼,是否还在为此没有合适的解决方案烦恼?
mybatis-extension插件,解决开发过程中需要多表关联时需手写xml的烦恼,同样支持通过传入sql返回结果集。
纯mybatis原生支持,轻量级无侵入,可用于辅助mybatis-plus、tk.mybatis或者mybatis-generator使用。
1.运行依赖:
* mybatis>=3.5.2
* jdk>=1.8
2.特性:
2.1. 支持多表自定义join关联查询
2.2. 支持自定义AND/OR混合条件,排序,分页等
2.3. 支持GROUPBY/HAVING聚合查询
2.4. 支持自定义sql查询
2.5. 所有的列名选择功能支持lambda写法和字符串输入两种方式
2.6. 自动判断表名、列名与实体类名、字段名对应,多表关联时自动给表名起别名
2.7. 内置多种mybatis generator常用插件,例如批量新增、分页等
3.性能:
比mybatis-generator性能提高约30%,甚至比navicat中直接执行查询还快,与其他插件的对比待测试。
4.不足:
不支持单表多次重复关联
不支持复杂的三层嵌套AND/OR
不支持多表UNION
5.最佳实践:
轻量级(jar包小于100KB)无其他依赖,可辅助其他mybatis插件使用,为解决JOIN关联为生,并持续提供各种特性
6.使用说明(springboot示例,代码在本文下方下载)
6.1pom.xml中引入mybatis-extension的依赖(目前未放到maven中央仓库,可参考下方本地引入或者放入离线仓库)
<dependency> <groupId>priv.rexsheng</groupId> <artifactId>mybatis-extension</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/resources/templates/mybatis-extension-1.0.0.jar</systemPath> </dependency>
6.2 在启动类或者配置类上加入扫描mapper包
@MapperScan(basePackages = {"priv.rexsheng.mybatis.mapper"})
6.3配置mybatis拦截器
import priv.rexsheng.mybatis.interceptor.ResultTypeInterceptor; @Configuration public class InterceptorConfig { @Bean public ResultTypeInterceptor resultTypeInterceptor() { return new ResultTypeInterceptor(); } }
6.4正常使用mapper接口查询即可
import priv.rexsheng.mybatis.extension.TableQueryBuilder; import priv.rexsheng.mybatis.mapper.DynamicMapper; import priv.rexsheng.mybatis.test.dto.UserRoleQueryDto; import priv.rexsheng.mybatis.test.entity.TUser; import priv.rexsheng.mybatis.test.entity.UserRole; @SpringBootTest public class MapperTest { @Autowired private DynamicMapper dao; /** * 单表简单查询 */ @Test public void simpleSelect() { //定义要查询的表的构建器 TableQueryBuilder<TUser> userQuery=TableQueryBuilder.from(TUser.class); //定义要查询的字段 userQuery.select(TUser::getUserId,TUser::getUserName).and().like(TUser::getUserName, "%王二小%"); //执行查询 List<TUser> userList=dao.selectByBuilder(userQuery.build()); log.info("用户列表:{}",userList); } }
7. 各种查询使用说明
7.1单表查询
@Test public void simpleUserList() { TableQueryBuilder<TUser> userQuery=TableQueryBuilder.from(TUser.class); //只查询user_id与user_name两个字段, userQuery.select(TUser::getUserId,TUser::getUserName) .where().gt(TUser::getUserId, 3) .or().isNotNull(TUser::getUpdateUser).isNotNull(TUser::getCreateTime); //按照创建时间倒序取前10条 userQuery.orderByDesc(TUser::getCreateTime).take(10); List<TUser> userList=dao.selectByBuilder(userQuery.build()); logger.info("用户列表:{}",userList); }
2020-09-03 06:45:32.272 DEBUG 18496 --- [ main] p.r.m.m.D.selectByBuilder_TUser : ==> Preparing: SELECT user_id AS userId, user_name AS userName FROM t_user WHERE (user_id > ?) AND (update_user IS NOT NULL OR create_time IS NOT NULL) ORDER BY create_time DESC LIMIT ? 2020-09-03 06:45:32.293 DEBUG 18496 --- [ main] p.r.m.m.D.selectByBuilder_TUser : ==> Parameters: 3(Integer), 10(Integer) 2020-09-03 06:45:32.315 DEBUG 18496 --- [ main] p.r.m.m.D.selectByBuilder_TUser : <== Total: 10
7.2 单表分组聚合查询
@Test public void simpleUserGroup() throws ParseException { SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); Date minDate=sdf.parse("2000-10-01"); TableQueryBuilder<TUser> userQuery=TableQueryBuilder.from(TUser.class); //select create_user,max(create_time) userQuery.select(TUser::getCreateUser).selectMax(TUser::getCreateTime, "createTime") .where().gt(TUser::getUserId, 3); //group by create_user having count(*)>1 and min(create_time)>=‘2020-10-01 00:00:00‘ userQuery.groupBy(TUser::getCreateUser).havingCount(a->a.gt("*", 1)).havingMin(a->a.gte(TUser::getCreateTime,minDate)); List<TUser> userList=dao.selectByBuilder(userQuery.build()); logger.info("用户列表:{}",userList); }
2020-09-03 06:20:27.178 DEBUG 1280 --- [ main] p.r.m.m.D.selectByBuilder_TUser : ==> Preparing: SELECT create_user AS createUser, MAX(create_time) AS createTime FROM t_user WHERE (user_id > ?) GROUP BY create_user HAVING (COUNT(*) > ? AND MIN(create_time) >= ?) 2020-09-03 06:20:27.204 DEBUG 1280 --- [ main] p.r.m.m.D.selectByBuilder_TUser : ==> Parameters: 3(Integer), 1(Integer), 2000-10-01 00:00:00.0(Timestamp) 2020-09-03 06:20:27.242 DEBUG 1280 --- [ main] p.r.m.m.D.selectByBuilder_TUser : <== Total: 10 2020-09-03 06:20:27.250 INFO 1280 --- [ main] priv.rexsheng.mybatis.test.JoinTest : 用户列表:[TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=5, updateTime=null, updateUser=null], TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=6, updateTime=null, updateUser=null], TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=7, updateTime=null, updateUser=null], TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=8, updateTime=null, updateUser=null], TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=9, updateTime=null, updateUser=null], TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=10, updateTime=null, updateUser=null], TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=1, updateTime=null, updateUser=null], TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=2, updateTime=null, updateUser=null], TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=3, updateTime=null, updateUser=null], TUser [userId=null, userName=null, createTime=Mon Aug 31 15:37:59 CST 2020, createUser=4, updateTime=null, updateUser=null]]
7.3单表分页查询并转换返回类型
@Test public void simpleUserPageWithConvert() throws ParseException { TableQueryBuilder<TUser> userQuery=TableQueryBuilder.from(TUser.class); //查询第4页数据,并将查询的结果转换为实体类UserInfoDto userQuery.select(TUser::getUserId,TUser::getCreateTime) .selectAs(TUser::getUserName, "trueName") .page(4, 10); List<UserInfoDto> userPagedList=dao.selectByBuilder(userQuery.build(UserInfoDto.class)); logger.info("用户列表:{}",userPagedList); }
2020-09-03 06:30:13.542 DEBUG 9944 --- [ main] p.r.m.m.D.selectByBuilder_UserInfoDto : ==> Preparing: SELECT user_id AS userId, create_time AS createTime, user_name AS trueName FROM t_user LIMIT ? OFFSET ? 2020-09-03 06:30:13.565 DEBUG 9944 --- [ main] p.r.m.m.D.selectByBuilder_UserInfoDto : ==> Parameters: 10(Integer), 30(Integer) 2020-09-03 06:30:13.587 DEBUG 9944 --- [ main] p.r.m.m.D.selectByBuilder_UserInfoDto : <== Total: 10 2020-09-03 06:30:13.596 INFO 9944 --- [ main] priv.rexsheng.mybatis.test.JoinTest : 用户列表:[UserInfoDto [userId=31, trueName=用户31, createTime=2020-08-31T15:35:47], UserInfoDto [userId=32, trueName=用户32, createTime=2020-08-31T15:35:47], UserInfoDto [userId=33, trueName=用户33, createTime=2020-08-31T15:35:47], UserInfoDto [userId=34, trueName=用户34, createTime=2020-08-31T15:35:47], UserInfoDto [userId=35, trueName=用户35, createTime=2020-08-31T15:35:47], UserInfoDto [userId=36, trueName=用户36, createTime=2020-08-31T15:35:47], UserInfoDto [userId=37, trueName=用户37, createTime=2020-08-31T15:35:47], UserInfoDto [userId=38, trueName=用户38, createTime=2020-08-31T15:35:47], UserInfoDto [userId=39, trueName=用户39, createTime=2020-08-31T15:35:47], UserInfoDto [userId=40, trueName=用户40, createTime=2020-08-31T15:35:47]]
public class UserInfoDto { private Integer userId; private String trueName; private LocalDateTime createTime; }
7.4多个表的关联查询
@Test public void joinAndGroup() { long startTime=System.currentTimeMillis(); TableQueryBuilder<TUser> userQuery=TableQueryBuilder.from(TUser.class); userQuery.selectAs(TUser::getCreateUser,"userId").selectCount("*","count") .groupBy(TUser::getCreateUser).havingCount(a->a.gt("*", 0)).havingMin(a->a.gte(TUser::getUserId, 1)); userQuery.where().gt(TUser::getUserId, 3).or().isNotNull(TUser::getCreateTime).isNotNull(TUser::getCreateUser); TableQueryBuilder<TRole> roleQuery=TableQueryBuilder.from(TRole.class); roleQuery.selectMax(TRole::getRoleId, "roleId") .where().isNull(TRole::getUpdateTime).and().isNotNull(TRole::getCreateUser); roleQuery.groupBy(TRole::getRoleId).havingMax(a->a.gt(TRole::getRoleId, -1)); TableQueryBuilder<UserRole> userRoleQuery=TableQueryBuilder.from(UserRole.class); userRoleQuery.and().isNotNull("user_id").isNotNull("role_id"); userRoleQuery.leftJoin(roleQuery).on(UserRole::getRoleId, TRole::getRoleId); userQuery.orderByCount("*").leftJoin(userRoleQuery).on(TUser::getUserId, UserRole::getUserId); List<UserCountDto> userList=dao.selectByBuilder(userQuery.build(UserCountDto.class)); long endTime=System.currentTimeMillis(); logger.info("复杂聚合:{}ms,data:{}",endTime-startTime,userList); TestCase.assertNotNull(userList); TestCase.assertTrue(userList.size()>0); TestCase.assertNotNull(userList.get(0)); }
2020-09-03 06:45:52.626 DEBUG 8928 --- [ main] p.r.m.m.D.selectByBuilder_UserCountDto : ==> Preparing: SELECT a.create_user AS userId, COUNT(*) AS count, MAX(c.role_id) AS roleId FROM t_user AS a LEFT OUTER JOIN t_user_role AS b on a.user_id=b.user_id LEFT OUTER JOIN t_role AS c on b.role_id=c.role_id WHERE (a.user_id > ?) AND (a.create_time IS NOT NULL OR a.create_user IS NOT NULL) AND (b.user_id IS NOT NULL AND b.role_id IS NOT NULL) AND (c.update_time IS NULL) AND (c.create_user IS NOT NULL) GROUP BY a.create_user, c.role_id HAVING (COUNT(*) > ? AND MIN(a.user_id) >= ?) AND (MAX(c.role_id) > ?) ORDER BY COUNT(*) 2020-09-03 06:45:52.627 DEBUG 8928 --- [ main] p.r.m.m.D.selectByBuilder_UserCountDto : ==> Parameters: 3(Integer), 0(Integer), 1(Integer), -1(Integer) 2020-09-03 06:45:52.630 DEBUG 8928 --- [ main] p.r.m.m.D.selectByBuilder_UserCountDto : <== Total: 39 2020-09-03 06:45:52.631 INFO 8928 --- [ main] priv.rexsheng.mybatis.test.JoinTest : 复杂聚合:6ms,data:[UserCountDto [userId=9, count=1, roleId=1], UserCountDto [userId=7, count=1, roleId=5], UserCountDto [userId=6, count=1, roleId=1], UserCountDto [userId=10, count=1, roleId=7], UserCountDto [userId=9, count=1, roleId=6], UserCountDto [userId=8, count=1, roleId=4], UserCountDto [userId=7, count=1, roleId=1], UserCountDto [userId=5, count=1, roleId=1], UserCountDto [userId=10, count=1, roleId=3], UserCountDto [userId=9, count=1, roleId=2], UserCountDto [userId=7, count=1, roleId=6], UserCountDto [userId=6, count=1, roleId=2], UserCountDto [userId=10, count=1, roleId=8], UserCountDto [userId=9, count=1, roleId=7], UserCountDto [userId=8, count=1, roleId=5], UserCountDto [userId=7, count=1, roleId=2], UserCountDto [userId=5, count=1, roleId=2], UserCountDto [userId=10, count=1, roleId=4], UserCountDto [userId=9, count=1, roleId=3], UserCountDto [userId=8, count=1, roleId=1], UserCountDto [userId=6, count=1, roleId=3], UserCountDto [userId=10, count=1, roleId=9], UserCountDto [userId=9, count=1, roleId=8], UserCountDto [userId=8, count=1, roleId=6], UserCountDto [userId=7, count=1, roleId=3], UserCountDto [userId=5, count=1, roleId=3], UserCountDto [userId=10, count=1, roleId=5], UserCountDto [userId=9, count=1, roleId=4], UserCountDto [userId=8, count=1, roleId=2], UserCountDto [userId=6, count=1, roleId=4], UserCountDto [userId=10, count=1, roleId=1], UserCountDto [userId=8, count=1, roleId=7], UserCountDto [userId=7, count=1, roleId=4], UserCountDto [userId=5, count=1, roleId=4], UserCountDto [userId=10, count=1, roleId=6], UserCountDto [userId=9, count=1, roleId=5], UserCountDto [userId=8, count=1, roleId=3], UserCountDto [userId=6, count=1, roleId=5], UserCountDto [userId=10, count=1, roleId=2]]
7.5 sql查询
@Test public void testCountSql() { List<Long> countList = dao.selectBySql("Select Count(*) from t_user", Long.class); logger.info("countList:{}", countList); TestCase.assertNotNull(countList); TestCase.assertTrue(countList.get(0)>0); logger.info("countList.0:{}", countList.get(0)); } @Test public void testSelectSql() { List<TUser> userList = dao.selectBySql("Select user_id as userId,user_name as userName,create_time as createTime from t_user where user_id>10 limit 3", TUser.class); logger.info("userList:{}", userList); TestCase.assertNotNull(userList); TestCase.assertNotNull(userList.get(0).getCreateTime()); logger.info("userList.0:{}", userList.get(0)); }
2020-09-03 06:52:33.860 DEBUG 20716 --- [ main] p.r.m.m.DynamicMapper.selectBySql_TUser : ==> Preparing: Select user_id as userId,user_name as userName,create_time as createTime from t_user where user_id>10 limit 3 2020-09-03 06:52:33.884 DEBUG 20716 --- [ main] p.r.m.m.DynamicMapper.selectBySql_TUser : ==> Parameters: 2020-09-03 06:52:33.912 DEBUG 20716 --- [ main] p.r.m.m.DynamicMapper.selectBySql_TUser : <== Total: 3 2020-09-03 06:52:33.921 INFO 20716 --- [ main] priv.rexsheng.mybatis.test.SqlTest : userList:[TUser [userId=11, userName=用户11, createTime=Mon Aug 31 15:35:47 CST 2020, createUser=null, updateTime=null, updateUser=null], TUser [userId=12, userName=用户12, createTime=Mon Aug 31 15:35:47 CST 2020, createUser=null, updateTime=null, updateUser=null], TUser [userId=13, userName=用户13, createTime=Mon Aug 31 15:35:47 CST 2020, createUser=null, updateTime=null, updateUser=null]] 2020-09-03 06:52:33.924 INFO 20716 --- [ main] priv.rexsheng.mybatis.test.SqlTest : userList.0:TUser [userId=11, userName=用户11, createTime=Mon Aug 31 15:35:47 CST 2020, createUser=null, updateTime=null, updateUser=null] 2020-09-03 06:52:33.930 DEBUG 20716 --- [ main] p.r.m.m.DynamicMapper.selectBySql_Long : ==> Preparing: Select Count(*) from t_user 2020-09-03 06:52:33.930 DEBUG 20716 --- [ main] p.r.m.m.DynamicMapper.selectBySql_Long : ==> Parameters: 2020-09-03 06:52:33.935 DEBUG 20716 --- [ main] p.r.m.m.DynamicMapper.selectBySql_Long : <== Total: 1 2020-09-03 06:52:33.936 INFO 20716 --- [ main] priv.rexsheng.mybatis.test.SqlTest : countList:[10000] 2020-09-03 06:52:33.936 INFO 20716 --- [ main] priv.rexsheng.mybatis.test.SqlTest : countList.0:10000
7.6 实体类结构
public class TUser { private Integer userId; private String userName; private Date createTime; private Integer createUser; private Date updateTime; @ColumnName("update_user") private Integer updateUser; } public class TRole { private Integer roleId; private String roleName; private String roleRemark; private LocalDateTime createTime; private Integer createUser; private Date updateTime; private Integer updateUser; } @TableName("t_user_role") public class UserRole { private Integer Id; private Integer userId; private Integer roleId; } public class UserInfoDto { private Integer userId; private String trueName; private LocalDateTime createTime; } public class UserCountDto { private Integer userId; private Long count; private Integer roleId; }
标签:rtt 关联查询 分页查询 返回 intercept des 自定义 inand table
原文地址:https://www.cnblogs.com/RexSheng/p/mybatis-extension.html