From 83585c075f9b34a3fcb9ea23de1df1015f3c5833 Mon Sep 17 00:00:00 2001 From: yulichang <570810310@qq.com> Date: Tue, 10 Jan 2023 15:27:14 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=20test?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mybatis-plus-join-test/pom.xml | 8 +- mybatis-plus-join-test/test-join/pom.xml | 4 +- .../test/join/config/MybatisPlusConfig.java | 52 +++- .../yulichang/test/join/entity/UserDto.java | 3 + .../test/join/util/ThreadLocalUtils.java | 22 ++ .../test-join/src/main/resources/db/data.sql | 10 + .../src/main/resources/db/schema.sql | 1 - .../test/join/LambdaWrapperTest.java | 282 ++++++++++++++++-- 8 files changed, 352 insertions(+), 30 deletions(-) create mode 100644 mybatis-plus-join-test/test-join/src/main/java/com/github/yulichang/test/join/util/ThreadLocalUtils.java 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)