# mybatis-plus-join **Repository Path**: rszhang/mybatis-plus-join ## Basic Information - **Project Name**: mybatis-plus-join - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 7 - **Created**: 2021-09-23 - **Last Updated**: 2022-02-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 在看了大多数的别人开源的联表查询项目后,感觉到不是很满意,想要的子查询没有,想要的函数也没有,更别说函数嵌套函数和函数嵌套子查询了. 所以决定自己来实现这些功能 项目基于mybatis-plus **支持关联查询,支持mysql中的各种函数** 如json_object(),sum(),max(),case when,ifnull,if(),month(),year()...... 不完整,但是可以后续慢慢补充 使用说明: 替换BaseMapper为`com.mybatis.plus.mapper.ParentMapper` 替换IService为`com.mybatis.plus.service.IBaseService` 替换ServiceImpl为`com.mybatis.plus.service.impl.BaseService` 将`com.mybatis.plus.config.DynamicResultMapInterceptor`注入spring容器 将`com.mybatis.plus.join.JoinSqlInjector`注入spring容器,并且不能注入其他的ISqlInjector #### **使用介绍**: 举例:有用户表和成绩表 User | id | name | | ----- | ---- | | 10001 | 老李 | | 10002 | 老王 | Score | id | userId | score | examId(考试id) | | ---- | ------ | ----- | -------------- | | 1 | 10001 | 100 | 1 | | 2 | 10002 | 50 | 1 | | 3 | 10001 | 100 | 2 | | 4 | 10002 | 60 | 2 | | 5 | 10001 | 100 | 3 | | 6 | 10002 | 70 | 3 | ###### 1.基本方法:one(),first(),list(),page() 使用非常简单,和mybatis-plus类似,只需要调用 Service 的 `query(Class cl)` 方法即可。 ```java // 这样就直接查询所有的用户 List users = userService.query(User.class).list(); // 这样就直接查询第一个名字叫张三 User firstUser = userService.query(User.class).eq(User::getName,"张三").first(); // 这样就直接查询叫张三的人,如果返回多个会报异常 User user = userService.query(User.class).eq(User::getName,"张三").one(); // 这样就直接查询第1页的10个用户 IPage userPage = userService.query(User.class).page(new Page(1,10)); ``` ###### 2.实体转 `DTO` , `VO` 的方法:one(Class cl),first(Class cl),list(Class cl),page(Class cl) ``` // 这样就直接查询所有的用户 List users = userService.query(User.class).list(UserDTO.class); // 这样就直接查询第一个名字叫张三 UserDTO firstUser = userService.query(User.class).eq(User::getName,"张三").first(UserDTO.class); // 这样就直接查询叫张三的人,如果返回多个会报异常 UserDTO user = userService.query(User.class).eq(User::getName,"张三").one(UserDTO.class); // 这样就直接查询第1页的10个用户 IPage userPage = userService.query(User.class).page(new Page(1,10),UserDTO.class); ``` ###### 3.`where`条件判断 ```java List users = userService.query(User.class) .eq(User::getName,"张三") // 和mybatis-plus保持一致(mybatis-plus的所有方法都被保留了下来) //.ge(User::getCreateTime,"2020-01-01") @@@@@1 .where(User::getCreateTime,ConditionEnum.GE,"2020-01-01") // 看起来和`@@@@@1`一样,实际上是为了下面的函数操作 .list(UserDTO.class); ``` ###### 4.各种`MYSQL`内置的函数 函数可以在`BaseService`里的静态方法里看到,所有的函数都在里面,有些可能实现的不是很合理。 ```java // YEAR()函数:查询2020年的用户 List users = userService.query(User.class) .where(YEAR(User::getCreateTime),ConditionEnum.EQ,2020) .list(UserDTO.class); // MONTH()函数:查询2020年1月份的用户 users = userService.query(User.class) .where(YEAR(User::getCreateTime),ConditionEnum.EQ,2020) .where(MONTH(User::getCreateTime),ConditionEnum.EQ,1) .list(UserDTO.class); // CASE WHEN流程控制 users = userService.query(User.class) .select(CASE(YEAR(User::getCreateTime)) .when(2020, "去年") .when(2021, "今年") .el("其他"), UserDTO::getYearName) // 放到UserDTO的yearName字段里 .list(UserDTO.class); // CASE WHEN流程控制另一种形式,更灵活,但是写起来更复杂 users = userService.query(User.class) .select(CASE() .when(YEAR(User::getCreateTime),ConditionEnum.EQ,2020, "去年") .when(YEAR(User::getCreateTime),ConditionEnum.EQ,2021, "今年") .el("其他"), UserDTO::getYearName) // 放到UserDTO的yearName字段里 .list(UserDTO.class); // JSON_OBJECT()函数 UserDTO user = userService.query(User.class) .eq(User::getId,"1") .select(JSON().KV("id",User::getId) .KV("createTime",User::getCreateTime) , UserDTO::getId) // 放到UserDTO的id字段里,这个时候id返回的应该是json字符串:"{'id':'1','createTime':'2020-01-01 00:00:01'}" .one(UserDTO.class); //......还有其他的一些函数,可以自行研究,自行实现 ``` ###### 5.`MYSQL`的加减乘除 ```java // PLUS(),SUB(),MUL(),DIV() // 获取用户创建了几年 List users = userService.query(User.class) .select(SUB( YEAR(NOW()) - YEAR(User::getCreateTime) ), UserDTO::getAge) .list(UserDTO.class); ``` ###### 6.`MYSQL`子查询 ```java // 查询年份不是2020年的用户,方式1 List users = userService.query(User.class) .notIn(User::getId, q -> q.query(User.class) .where(YEAR(User::getCreateTime),ConditionEnum.EQ,2020) .select(User::getId) ).list(UserDTO.class); // 查询年份不是2020年的用户,方式2 List users = userService.query(User.class) .notIn(User::getId, QUERY(q.query(User.class) .where(YEAR(User::getCreateTime),ConditionEnum.EQ,2020) .select(User::getId)) ).list(UserDTO.class); // 上面方式1和方式2的原理是一样的,方式1只是简化了一点点。 // exist函数 userService.query(User.class) .select(JSON().KV("是否参加了比赛2", EXISTS(q -> q.query(Score.class) .eq(Score::getExamId, "2") .where(Score::getUserId, ConditionEnum.EQ, User::getId)) ) .KV("是否参加了比赛3", EXISTS(q -> q.query(Score.class) .eq(Score::getExamId, "2") .where(Score::getUserId, ConditionEnum.EQ, User::getId) ) ), "id") .first(UserDTO.class); ``` ###### 7.关联查询 ```java // 查询在考试1中成绩最高的人名字,方式1 UserDTO user = userService.query(User.class) .select(User::getName) .select(MAX(Score::getScore), UserDTO::getScore) .innerJoin(Score.class) .on(User::getId, ConditionEnum.EQ, Score::getUserId) .on(Score::getExamId, ConditionEnum.EQ, "1") .one(UserDTO.class); // 查询在考试1中成绩最高的人名字,方式2 UserDTO user = userService.query(User.class) .select(User::getName) .select(MAX(Score::getScore), UserDTO::getScore) .innerJoin(Score.class, q->q.on(User::getId, ConditionEnum.EQ, Score::getUserId) .on(Score::getExamId, ConditionEnum.EQ, "1")) .one(UserDTO.class); ```