diff --git a/mybatis-plus-join-test/pom.xml b/mybatis-plus-join-test/pom.xml
index 23fbc55..0ef80a5 100644
--- a/mybatis-plus-join-test/pom.xml
+++ b/mybatis-plus-join-test/pom.xml
@@ -45,11 +45,11 @@
2.5.4
- 1.8
- 1.8
+ 17
+ 17
true
- 1.8
- 1.8
+ 17
+ 17
github
UTF-8
diff --git a/mybatis-plus-join-test/test-join/pom.xml b/mybatis-plus-join-test/test-join/pom.xml
index 7b36b83..734f985 100644
--- a/mybatis-plus-join-test/test-join/pom.xml
+++ b/mybatis-plus-join-test/test-join/pom.xml
@@ -12,8 +12,8 @@
test-join
- 8
- 8
+ 17
+ 17
UTF-8
diff --git a/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/config/MybatisPlusConfig.java b/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/config/MybatisPlusConfig.java
index aea2d51..69fc9fc 100644
--- a/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/config/MybatisPlusConfig.java
+++ b/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/config/MybatisPlusConfig.java
@@ -1,11 +1,23 @@
package com.github.yulichang.test.join.config;
import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import com.github.yulichang.test.join.util.ThreadLocalUtils;
+import org.apache.ibatis.builder.SqlSourceBuilder;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
+import java.sql.SQLException;
+import java.util.Objects;
+
/**
* mybatis-plus配置
*/
@@ -16,11 +28,49 @@ public class MybatisPlusConfig {
* 分页插件
*/
@Bean
- public MybatisPlusInterceptor paginationInterceptor() {
+ public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
PaginationInnerInterceptor page = new PaginationInnerInterceptor(DbType.H2);
page.setOptimizeJoin(false);
interceptor.addInnerInterceptor(page);
+ interceptor.addInnerInterceptor(new SqlInterceptor());
return interceptor;
}
+
+ /**
+ * 校验sql
+ */
+ public static class SqlInterceptor implements InnerInterceptor {
+
+ @Override
+ public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
+ String sql = boundSql.getSql();
+ String s = ThreadLocalUtils.get();
+ if (StringUtils.isNotBlank(s) && !Objects.equals(formatSql(sql), formatSql(s))) {
+ System.err.println("执行sql: " + SqlSourceBuilder.removeExtraWhitespaces(sql));
+ System.err.println("预期sql: " + SqlSourceBuilder.removeExtraWhitespaces(s));
+ throw new RuntimeException("sql error");
+ }
+ InnerInterceptor.super.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);
+ }
+
+ private String formatSql(String sql) {
+ if (StringUtils.isBlank(sql)) {
+ return sql;
+ }
+ sql = sql.replaceAll("\n", "");
+ sql = sql.replaceAll("\r", "");
+ sql = sql.replaceAll("\t", "");
+ sql = sql.replaceAll("\s", "");
+ return dg(sql);
+ }
+
+ private String dg(String str) {
+ if (str.contains(" ")) {
+ str = str.replaceAll(" ", "");
+ return dg(str);
+ }
+ return str;
+ }
+ }
}
diff --git a/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/entity/UserDto.java b/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/entity/UserDto.java
index 7304b63..8ded6fc 100644
--- a/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/entity/UserDto.java
+++ b/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/entity/UserDto.java
@@ -14,6 +14,9 @@ public class UserDto {
private Integer userId;
+ @TableField(exist = false)
+ private String userName;
+
private Integer createBy;
@TableField(exist = false)
diff --git a/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/util/ThreadLocalUtils.java b/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/util/ThreadLocalUtils.java
new file mode 100644
index 0000000..d9c1144
--- /dev/null
+++ b/mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/util/ThreadLocalUtils.java
@@ -0,0 +1,22 @@
+package com.github.yulichang.test.join.util;
+
+public class ThreadLocalUtils {
+
+ private final static ThreadLocal userThreadLocal = new ThreadLocal<>();
+
+ /**
+ * 设置数据到当前线程
+ */
+ public static void set(String sql) {
+ userThreadLocal.set(sql);
+ }
+
+ /**
+ * 获取线程中的数据
+ */
+ public static String get() {
+ String s = userThreadLocal.get();
+ set(null);
+ return s;
+ }
+}
diff --git a/mybatis-plus-join-test/test-join/src/main/resources/db/data.sql b/mybatis-plus-join-test/test-join/src/main/resources/db/data.sql
index a8f43cd..165e33c 100644
--- a/mybatis-plus-join-test/test-join/src/main/resources/db/data.sql
+++ b/mybatis-plus-join-test/test-join/src/main/resources/db/data.sql
@@ -79,3 +79,13 @@ INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (20,20, 100
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (21,21, 10021, '10000000021', '朝阳21', false);
INSERT INTO address (id, user_id, area_id, tel, address, del) VALUES (22,22, 10022, '10000000022', '朝阳22', false);
+DELETE FROM user_dto;
+INSERT INTO user_dto (id, user_id, create_by, update_by, del) VALUES
+(1,1, 2, 3, false),
+(2,1, 2, 3, false),
+(3,1, 2, 3, false),
+(4,1, 2, 3, false),
+(5,1, 2, 3, false),
+(6,1, 2, 3, false),
+(7,1, 2, 3, false),
+(8,1, 2, 3, false);
\ No newline at end of file
diff --git a/mybatis-plus-join-test/test-join/src/main/resources/db/schema.sql b/mybatis-plus-join-test/test-join/src/main/resources/db/schema.sql
index 5578bdd..e5f2bf4 100644
--- a/mybatis-plus-join-test/test-join/src/main/resources/db/schema.sql
+++ b/mybatis-plus-join-test/test-join/src/main/resources/db/schema.sql
@@ -54,6 +54,5 @@ create table user_dto
user_id int not null,
create_by int not null,
update_by int not null,
- version int not null,
del bit null
);
diff --git a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/LambdaWrapperTest.java b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/LambdaWrapperTest.java
index 1ab52d2..c0b0bb7 100644
--- a/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/LambdaWrapperTest.java
+++ b/mybatis-plus-join-test/test-join/src/test/java/com/github/yulichang/test/join/LambdaWrapperTest.java
@@ -2,6 +2,7 @@ package com.github.yulichang.test.join;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.test.join.dto.AddressDTO;
import com.github.yulichang.test.join.dto.UserDTO;
@@ -11,6 +12,7 @@ import com.github.yulichang.test.join.entity.UserDO;
import com.github.yulichang.test.join.entity.UserDto;
import com.github.yulichang.test.join.mapper.UserDTOMapper;
import com.github.yulichang.test.join.mapper.UserMapper;
+import com.github.yulichang.test.join.util.ThreadLocalUtils;
import com.github.yulichang.toolkit.MPJWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import org.junit.jupiter.api.Test;
@@ -40,12 +42,22 @@ class LambdaWrapperTest {
@Test
void testJoin() {
+ ThreadLocalUtils.set("""
+ SELECT t.id,t.pid,t.`name`,t.`json`,t.sex,t.head_img,t.create_time,t.address_id,t.address_id2,t.del,t.create_by,t.update_by,
+ t1.id AS joina_id,t1.user_id,t1.area_id,t1.tel,t1.address,t1.del AS joina_del,t2.id AS joinb_id,t2.province,t2.city,t2.area,t2.postcode,t2.del AS joinb_del
+ FROM `user` t LEFT JOIN address t1 ON (t1.user_id = t.id)
+ LEFT JOIN area t2 ON (t2.id = t1.area_id)
+ WHERE t.del=false AND t1.del=false AND t2.del=false AND (t.id <= ?)
+ ORDER BY t.id DESC
+ """);
+
MPJLambdaWrapper wrapper = new MPJLambdaWrapper()
.selectAll(UserDO.class)
.selectCollection(AddressDO.class, UserDTO::getAddressList, addr -> addr
.association(AreaDO.class, AddressDTO::getArea))
.leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
.leftJoin(AreaDO.class, AreaDO::getId, AddressDO::getAreaId)
+ .le(UserDO::getId, 10000)
.orderByDesc(UserDO::getId);
List list = userMapper.selectJoinList(UserDTO.class, wrapper);
@@ -56,6 +68,16 @@ class LambdaWrapperTest {
@Test
void testJoin1() {
+ ThreadLocalUtils.set("""
+ SELECT t.id,t.pid,t.`name`,t.`json`,t.sex,t.head_img,t.create_time,t.address_id,t.address_id2,t.del,t.create_by,t.update_by,
+ t1.id AS joina_id,t1.user_id,t1.area_id,t1.tel,t1.address,t1.del AS joina_del,
+ t2.id AS joinb_id,t2.province,t2.city,t2.area,t2.postcode,t2.del AS joinb_del
+ FROM `user` t
+ LEFT JOIN address t1 ON (t1.user_id = t.id)
+ LEFT JOIN area t2 ON (t2.id = t1.area_id)
+ WHERE t.del=false AND t1.del=false AND t2.del=false
+ ORDER BY t.id DESC
+ """);
MPJLambdaWrapper wrapper = new MPJLambdaWrapper()
.selectAll(UserDO.class)
.selectCollection(AddressDO.class, UserDTO::getAddressList, addr -> addr
@@ -74,6 +96,15 @@ class LambdaWrapperTest {
*/
@Test
void testWrapper() {
+ ThreadLocalUtils.set("""
+ SELECT t.id
+ FROM `user` t
+ LEFT JOIN address t1 ON (t1.user_id = t.id)
+ LEFT JOIN area t2 ON (t2.id = t1.area_id)
+ WHERE t.del = false
+ AND t1.del = false
+ AND t2.del = false
+ """);
//基本数据类型 和 String
MPJLambdaWrapper wrapper = new MPJLambdaWrapper()
.select(UserDO::getId)
@@ -84,6 +115,16 @@ class LambdaWrapperTest {
assert list.get(0) != null;
System.out.println(list);
+
+ ThreadLocalUtils.set("""
+ SELECT t.create_time
+ FROM `user` t
+ LEFT JOIN address t1 ON (t1.user_id = t.id)
+ LEFT JOIN area t2 ON (t2.id = t1.area_id)
+ WHERE t.del = false
+ AND t1.del = false
+ AND t2.del = false
+ """);
//java.sql包下的类
MPJLambdaWrapper wrapper1 = new MPJLambdaWrapper()
.select(UserDO::getCreateTime)
@@ -99,38 +140,97 @@ class LambdaWrapperTest {
@Test
@SuppressWarnings("unchecked")
void testMSCache() {
-// PageHelper.startPage(1, 10);
+ ThreadLocalUtils.set("""
+ SELECT t.id,
+ t.pid,
+ t.`name`,
+ t.`json`,
+ t.sex,
+ t.head_img,
+ t.create_time,
+ t.address_id,
+ t.address_id2,
+ t.del,
+ t.create_by,
+ t.update_by
+ FROM `user` t
+ WHERE t.id = ?
+ AND t.del = false
+ AND (t.id <= ?)
+ ORDER BY t.id ASC, t.name ASC
+ """);
MPJLambdaWrapper wrapper = new MPJLambdaWrapper()
.selectAll(UserDO.class)
.setEntity(new UserDO() {{
setId(1);
}})
-// .eq(UserDO::getId,1)
+ .le(UserDO::getId, 100)
.orderByAsc(UserDO::getId, UserDO::getName);
- System.out.println(wrapper.getSqlSegment());
- System.out.println(wrapper.nonEmptyOfNormal());
- System.out.println(wrapper.isEmptyOfNormal());
- System.out.println("-----------------");
- System.out.println(wrapper.nonEmptyOfWhere());
- System.out.println(wrapper.isEmptyOfWhere());
-
List list = userMapper.selectList(wrapper);
-// list.forEach(System.out::println);
+ list.forEach(System.out::println);
}
@Test
- void testMSCachee() {
+ void testTableAliasR() {
+ ThreadLocalUtils.set("""
+ SELECT tt.id,
+ tt.user_id,
+ tt.create_by,
+ tt.update_by,
+ ua.`name` AS userName,
+ ub.`name` AS createName,
+ uc.`name` AS updateName
+ FROM user_dto tt
+ LEFT JOIN `user` ua ON (ua.id = tt.user_id)
+ LEFT JOIN `user` ub ON (ub.id = tt.create_by)
+ LEFT JOIN `user` uc ON (uc.id = tt.update_by)
+ WHERE ua.del = false
+ AND ub.del = false
+ AND uc.del = false
+ AND (ua.id <= ? AND ub.id >= ?)
+ """);
MPJLambdaWrapper wrapper = new MPJLambdaWrapper("tt")
.selectAll(UserDto.class)
.leftJoin(UserDO.class, "ua", UserDO::getId, UserDto::getUserId, ext -> ext
- .select(UserDO::getId))
+ .selectAs(UserDO::getName, UserDto::getUserName)
+ .le(UserDO::getId, 100))
.leftJoin(UserDO.class, "ub", UserDO::getId, UserDto::getCreateBy, ext -> ext
- .select(UserDO::getImg))
- .leftJoin(UserDO.class, "uc", UserDO::getId, UserDto::getUpdateBy);
- userDTOMapper.selectJoinList(UserDto.class, wrapper);
- System.out.println(1);
+ .selectAs(UserDO::getName, UserDto::getCreateName)
+ .ge(UserDO::getId, 0))
+ .leftJoin(UserDO.class, "uc", UserDO::getId, UserDto::getUpdateBy, ext -> ext
+ .selectAs(UserDO::getName, UserDto::getUpdateName));
+ List userDtos = userDTOMapper.selectJoinList(UserDto.class, wrapper);
+ assert StringUtils.isNotBlank(userDtos.get(0).getUserName());
+ assert StringUtils.isNotBlank(userDtos.get(0).getCreateName());
+ assert StringUtils.isNotBlank(userDtos.get(0).getUpdateName());
+
+ ThreadLocalUtils.set("""
+ SELECT tt.id,
+ tt.pid,
+ tt.`name`,
+ tt.`json`,
+ tt.sex,
+ tt.head_img,
+ tt.create_time,
+ tt.address_id,
+ tt.address_id2,
+ tt.del,
+ tt.create_by,
+ tt.update_by,
+ ua.id,
+ ub.head_img
+ FROM `user` tt
+ LEFT JOIN `user` ua ON (ua.id = tt.pid)
+ LEFT JOIN `user` ub ON (ub.id = tt.create_by)
+ LEFT JOIN `user` uc ON (uc.id = tt.update_by)
+ WHERE tt.del = false
+ AND ua.del = false
+ AND ub.del = false
+ AND uc.del = false
+ AND (ua.head_img = tt.name AND tt.id = ua.id)
+ """);
MPJLambdaWrapper w = new MPJLambdaWrapper("tt")
.selectAll(UserDO.class)
.leftJoin(UserDO.class, "ua", UserDO::getId, UserDO::getPid, ext -> ext
@@ -149,17 +249,66 @@ class LambdaWrapperTest {
*/
@Test
void testInner() {
+ ThreadLocalUtils.set("""
+ SELECT t.id,
+ t.pid,
+ t.`name`,
+ t.`json`,
+ t.sex,
+ t.head_img,
+ t.create_time,
+ t.address_id,
+ t.address_id2,
+ t.del,
+ t.create_by,
+ t.update_by,
+ t1.id AS joina_id,
+ t1.pid AS joina_pid,
+ t1.`name` AS joina_name,
+ t1.`json` AS joina_json,
+ t1.sex AS joina_sex,
+ t1.head_img AS joina_head_img,
+ t1.create_time AS joina_create_time,
+ t1.address_id AS joina_address_id,
+ t1.address_id2 AS joina_address_id2,
+ t1.del AS joina_del,
+ t1.create_by AS joina_create_by,
+ t1.update_by AS joina_update_by
+ FROM `user` t
+ LEFT JOIN `user` t1 ON (t1.pid = t.id)
+ WHERE t.del = false
+ AND (t.id > ?)
+ """);
//自连接
MPJLambdaWrapper wrapper = new MPJLambdaWrapper()
.disableSubLogicDel()//关闭副表逻辑删除
-// .disableLogicDel()//关闭主表逻辑删除
.selectAll(UserDO.class)
.selectCollection(UserDO.class, UserDO::getChildren)
- .leftJoin(UserDO.class, UserDO::getPid, UserDO::getId);
+ .leftJoin(UserDO.class, UserDO::getPid, UserDO::getId)
+ .gt(UserDO::getId, 0);
List list = userMapper.selectJoinList(UserDO.class, wrapper);
-// assert list.size() == 2 && list.get(0).getChildren().size() == 9;
System.out.println(list);
+ ThreadLocalUtils.set("""
+ SELECT t.id,
+ t.pid,
+ t.`name`,
+ t.`json`,
+ t.sex,
+ t.head_img,
+ t.create_time,
+ t.address_id,
+ t.address_id2,
+ t.del,
+ t.create_by,
+ t.update_by,
+ t1.`name` AS createName,
+ t2.`name` AS updateName
+ FROM `user` t
+ LEFT JOIN `user` t1 ON (t1.id = t.create_by)
+ LEFT JOIN `user` t2 ON (t2.id = t.update_by)
+ WHERE (t2.id = t.update_by AND t.id = t1.id)
+ """);
//关联一张表多次
MPJLambdaWrapper w = new MPJLambdaWrapper()
.disableLogicDel()
@@ -176,6 +325,51 @@ class LambdaWrapperTest {
List dos = userMapper.selectJoinList(UserDO.class, w);
assert dos.get(0).getCreateName() != null && dos.get(0).getUpdateName() != null;
+
+ ThreadLocalUtils.set("""
+ SELECT t.id,
+ t.pid,
+ t.`name`,
+ t.`json`,
+ t.sex,
+ t.head_img,
+ t.create_time,
+ t.address_id,
+ t.address_id2,
+ t.del,
+ t.create_by,
+ t.update_by,
+ t1.`name` AS alias,
+ t1.id AS joina_id,
+ t1.pid AS joina_pid,
+ t1.`name` AS joina_name,
+ t1.`json` AS joina_json,
+ t1.sex AS joina_sex,
+ t1.head_img AS joina_head_img,
+ t1.create_time AS joina_create_time,
+ t1.address_id AS joina_address_id,
+ t1.address_id2 AS joina_address_id2,
+ t1.del AS joina_del,
+ t1.create_by AS joina_create_by,
+ t1.update_by AS joina_update_by,
+ t2.id AS joinb_id,
+ t2.pid AS joinb_pid,
+ t2.`name` AS joinb_name,
+ t2.`json` AS joinb_json,
+ t2.sex AS joinb_sex,
+ t2.head_img AS joinb_head_img,
+ t2.create_time AS joinb_create_time,
+ t2.address_id AS joinb_address_id,
+ t2.address_id2 AS joinb_address_id2,
+ t2.del AS joinb_del,
+ t2.create_by AS joinb_create_by,
+ t2.update_by AS joinb_update_by
+ FROM `user` t
+ LEFT JOIN `user` t1 ON (t1.pid = t.id)
+ LEFT JOIN `user` t2 ON (t2.pid = t1.id)
+ WHERE t.del = false
+ AND (t1.id <= ? AND t.id <= ?)
+ """);
MPJLambdaWrapper wrapper1 = new MPJLambdaWrapper()
.disableSubLogicDel()
.selectAll(UserDO.class)
@@ -187,9 +381,6 @@ class LambdaWrapperTest {
.le(UserDO::getId, 5))
.le(UserDO::getId, 4);
List list1 = userMapper.selectJoinList(UserDO.class, wrapper1);
- System.out.println(wrapper1.getSqlSegment());
- System.out.println(wrapper1.getSqlSelect());
- assert "(t1.id <= #{ew.paramNameValuePairs.MPGENVAL1} AND t.id <= #{ew.paramNameValuePairs.MPGENVAL2})".equals(wrapper1.getSqlSegment());
System.out.println(list1);
}
@@ -244,6 +435,30 @@ class LambdaWrapperTest {
@Test
void testTableAlias() {
+ ThreadLocalUtils.set("""
+ SELECT t.id,
+ t.pid,
+ t.`name`,
+ t.`json`,
+ t.sex,
+ t.head_img,
+ t.create_time,
+ t.address_id,
+ t.address_id2,
+ t.del,
+ t.create_by,
+ t.update_by,
+ aa.id,
+ aa.user_id,
+ aa.area_id,
+ aa.tel,
+ aa.address,
+ aa.del
+ FROM `user` t
+ LEFT JOIN address aa ON (aa.user_id = t.id)
+ WHERE t.del = false
+ AND aa.del = false
+ """);
MPJLambdaWrapper wrapper = new MPJLambdaWrapper()
// .disableLogicDel()//关闭主表逻辑删除
.selectAll(UserDO.class)
@@ -266,6 +481,8 @@ class LambdaWrapperTest {
.leftJoin(AddressDO.class, AddressDO::getId, UserDO::getAddressId2);
List list = userMapper.selectJoinList(UserDO.class, wrapper);
+ assert list.get(0).getAddressList().get(0).getAddress()!= null;
+ assert list.get(0).getAddressList2().get(0).getAddress()!= null;
System.out.println(list);
}
@@ -293,6 +510,27 @@ class LambdaWrapperTest {
*/
@Test
void test3() {
+ ThreadLocalUtils.set("""
+ SELECT t.id,
+ t.pid,
+ t.`name`,
+ t.`json`,
+ t.sex,
+ t.head_img,
+ t.create_time,
+ t.address_id,
+ t.address_id2,
+ t.del,
+ t.create_by,
+ t.update_by,
+ t1.address
+ FROM `user` t
+ LEFT JOIN address t1 ON (t.id = t1.user_id AND t.id = t1.user_id)
+ WHERE t.del = false
+ AND t1.del = false
+ AND (t.id = ? AND (t.head_img = ? OR t1.user_id = ?) AND t.id = ?)
+ LIMIT ?
+ """);
IPage page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class,
MPJWrappers.lambdaJoin()
.selectAll(UserDO.class)