diff --git a/README.md b/README.md index 9b79f73..dd259b3 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ 1. 将代码down到本地,使用maven install -2. 在自己的项目中替换mybatisplus依赖(框架依赖mybatisplus<3.4.2>) +2. 在自己的项目中添加依赖 ```xml @@ -26,12 +26,9 @@ ### 方法二 -1. 将mybatisplus目录复制到你的工程中 +1. 将mybatisplus目录复制到你的工程中的springboot扫描路径下 -2. 如果mybatisplus目录不在springboot扫描路径下, - 将MybatisPlusConfiguration移动到springboot扫描路径下或添加springboot扫描路径 - -3. 添加cglib依赖 +2. 添加cglib依赖 ```xml @@ -47,9 +44,152 @@ * service继承MyBaseService (可选) * serviceImpl继承MyBaseServiceImpl (可选) -### MyLambdaQueryWrapper用法 +## MyQueryWrapper用法 -#### select(UserEntity::getId) 查询指定的字段,支持可变参数 +简单的3表查询 +```java +class test { + @Resource + private UserMapper userMapper; + + void testJoin() { + List list = userMapper.selectJoinList(UserDTO.class, + new MyLambdaQuery() + .selectAll(UserDO.class) + .select("addr.tel", "addr.address") + .select("a.province") + .leftJoin("user_address addr on t.id = addr.user_id") + .rightJoin("area a on addr.area_id = a.id") + .eq(true, UserDO::getId, 1) + .stringQuery() + .like(true, "addr.tel", "1") + .le(true, "a.province", "1")); + } +} +``` + +对应sql + +```sql +SELECT + t.id, + t.name, + t.sex, + t.head_img, + addr.tel, + addr.address, + a.province +FROM +user t +LEFT JOIN user_address addr on t.id = addr.user_id +RIGHT JOIN area a on addr.area_id = a.id +WHERE ( + t.id = ? + AND addr.tel LIKE ? + AND a.province <= ?) +``` + +说明: +* UserDTO.class 查询结果类(resultType) +* selectAll(UserDO.class) 查询主表全部字段(主表实体类) +* select() mp的select策略是覆盖,这里的策略是追加,可以一直select +主表字段可以用lambda,会自动添加表别名,主表别名默认是 t ,非主表字段必须带别名查询 +* leftJoin() rightJoin() innerJoin() 传sql片段 格式 (表 + 别名 + 关联条件) +* stringQuery() lambda查询转string查询 +* lambda() string查询转lambda查询 +* sql组装由mp完成,正常使用没有sql注入风险 + +分页查询 + +```java +class test { + @Resource + private UserMapper userMapper; + + void testJoin() { + IPage page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, + new MyLambdaQuery() + .selectAll(UserDO.class) + .select("addr.tel", "addr.address") + .select("a.province") + .leftJoin("user_address addr on t.id = addr.user_id") + .rightJoin("area a on addr.area_id = a.id")); + } +} +``` + +对应sql + +```sql +SELECT + t.id, + t.name, + t.sex, + t.head_img, + addr.tel, + addr.address, + a.province +FROM +user t +LEFT JOIN user_address addr on t.id = addr.user_id +RIGHT JOIN area a on addr.area_id = a.id +LIMIT ?,? +``` + +还可以怎么操作,但不建议 + +```java +class test { + @Resource + private UserMapper userMapper; + + void testJoin() { + List list = userMapper.selectJoinList(UserDTO.class, + new MyLambdaQuery() + .selectAll(UserDO.class) + .select("addr.tel", "addr.address") + //行列转换 + .select("CASE t.sex WHEN '男' THEN '1' ELSE '0' END AS sex") + //求和函数 + .select("sum(a.province) as province") + //自定义数据集 + .leftJoin("(select * from user_address) addr on t.id = addr.user_id") + .rightJoin("area a on addr.area_id = a.id") + .eq(true, UserDO::getId, 1) + .stringQuery() + .like(true, "addr.tel", "1") + .le(true, "a.province", "1") + .orderByDesc("addr.id")); + } +} +``` + +对应sql + +```sql +SELECT + t.id, + t.name, + t.sex, + t.head_img, + addr.tel, + addr.address, + CASE t.sex WHEN '男' THEN '1' ELSE '0' END AS sex, + sum(a.province) as province +FROM +user t +LEFT JOIN (select * from user_address) addr on t.id = addr.user_id +RIGHT JOIN area a on addr.area_id = a.id +WHERE ( + t.id = ? + AND addr.tel LIKE ? + AND a.province <= ?) +ORDER BY addr.id DESC +``` + +# MyLambdaQueryWrapper用法 + +### MyLambdaQueryWrapper更符合面向对象(OOP),没有难以理解的常量(魔术值),全部基于lambda,但好像不那么好理解 简单的3表查询 @@ -101,8 +241,6 @@ class test { } ``` -#### selectAll() 查询UserEntity全部字段 - 查询user全部字段和user_address表中的address,tel ```java @@ -111,11 +249,10 @@ class test { private UserMapper userMapper; void testJoin() { - List list = userMapper.selectJoinList(new MyLambdaQueryWrapper() + List list = userMapper.selectJoinList(UserDTO.class, new MyLambdaQueryWrapper() .selectAll(UserEntity.class) .leftJoin(UserEntity::getId, UserAddressEntity::getUserId, - right -> right.select(UserAddressEntity::getAddress, UserAddressEntity::getTel)) - , UserDTO.class); + right -> right.select(UserAddressEntity::getAddress, UserAddressEntity::getTel))); } } ``` @@ -133,8 +270,6 @@ FROM user t0 LEFT JOIN user_address t1 ON t0.id = t1.user_id ``` -#### as(UserEntity::getHeadImg,UserDTO::getUserHeadImg) - 查询字段别名 head_img as userHeadImg ```java @@ -143,11 +278,10 @@ class test { private UserMapper userMapper; void testJoin() { - List list = userMapper.selectJoinList(new MyLambdaQueryWrapper() + List list = userMapper.selectJoinList(UserDTO.class, new MyLambdaQueryWrapper() .as(UserEntity::getHeadImg, UserDTO::getUserHeadImg) .leftJoin(UserEntity::getId, UserAddressEntity::getUserId, - right -> right.select(UserAddressEntity::getAddress, UserAddressEntity::getTel)) - , UserDTO.class); + right -> right.select(UserAddressEntity::getAddress, UserAddressEntity::getTel))); } } ``` @@ -168,7 +302,7 @@ FROM user t0 user left join user_address on user.id = User_address.user_id 第三个参数是右表wrapper对象,可以继续使用,以上方法. -#### 条件查询eq() +连表条件查询 ```java class test { @@ -176,14 +310,13 @@ class test { private UserMapper userMapper; void testJoin() { - List list = userMapper.selectJoinList(new MyLambdaQueryWrapper() + List list = userMapper.selectJoinList(UserDTO.class, new MyLambdaQueryWrapper() .selectAll(UserEntity.class) .leftJoin(UserEntity::getId, UserAddressEntity::getUserId, right -> right.select(UserAddressEntity::getAddress, UserAddressEntity::getTel)) .eq(true, UserEntity::getId, 1) .like(UserAddressEntity::getTel, "1") - .eq(UserEntity::getId, UserAddressEntity::getUserId) - , UserDTO.class); + .eq(UserEntity::getId, UserAddressEntity::getUserId)); } } ``` @@ -205,5 +338,3 @@ WHERE ( AND t0.id = t1.user_id) ``` -#### [参考测试类](https://gitee.com/best_handsome/mybatis-plus-join/blob/master/src/test/java/com/example/mp/MpJoinTest.java) - diff --git a/src/main/java/com/github/mybatisplus/base/MyBaseMapper.java b/src/main/java/com/github/mybatisplus/base/MyBaseMapper.java index ff38045..7253159 100644 --- a/src/main/java/com/github/mybatisplus/base/MyBaseMapper.java +++ b/src/main/java/com/github/mybatisplus/base/MyBaseMapper.java @@ -20,9 +20,9 @@ public interface MyBaseMapper extends BaseMapper { * 连表查询返回一条记录 * * @param queryWrapper joinWrapper - * @param clazz 返回对象class + * @param clazz resultType */ - DTO selectJoinOne(@Param(Constants.WRAPPER) Wrapper queryWrapper, @Param(Constant.CLAZZ) Class clazz); + DTO selectJoinOne(@Param(Constant.CLAZZ) Class clazz, @Param(Constants.WRAPPER) Wrapper queryWrapper); /** * 连表查询返回Map @@ -35,9 +35,9 @@ public interface MyBaseMapper extends BaseMapper { * 连表查询返回记录集合 * * @param queryWrapper joinWrapper - * @param clazz 返回对象class + * @param clazz resultType */ - List selectJoinList(@Param(Constants.WRAPPER) Wrapper queryWrapper,@Param(Constant.CLAZZ) Class clazz); + List selectJoinList(@Param(Constant.CLAZZ) Class clazz, @Param(Constants.WRAPPER) Wrapper queryWrapper); /** * 连表查询返回Map集合 @@ -50,9 +50,12 @@ public interface MyBaseMapper extends BaseMapper { * 连表查询返回记录集合并分页 * * @param queryWrapper joinWrapper + * @param clazz resultType * @param 分页返回对象 */ - > IPage selectJoinPage(P page, @Param(Constants.WRAPPER) Wrapper queryWrapper, @Param(Constant.CLAZZ) Class clazz); + > IPage selectJoinPage(P page, + @Param(Constant.CLAZZ) Class clazz, + @Param(Constants.WRAPPER) Wrapper queryWrapper); /** * 连表查询返回Map集合并分页 diff --git a/src/main/java/com/github/mybatisplus/base/MyBaseService.java b/src/main/java/com/github/mybatisplus/base/MyBaseService.java index d2e6227..01bc94e 100644 --- a/src/main/java/com/github/mybatisplus/base/MyBaseService.java +++ b/src/main/java/com/github/mybatisplus/base/MyBaseService.java @@ -17,39 +17,39 @@ public interface MyBaseService extends IService { /** * ignore */ - default DTO selectJoinOne(MyWrapperFunc wrapperFunc, Class clazz) { - return selectJoinOne(wrapperFunc.apply(new MyLambdaQueryWrapper<>()), clazz); + default DTO selectJoinOne(Class clazz, MyWrapperFunc wrapperFunc) { + return selectJoinOne(clazz, wrapperFunc.apply(new MyLambdaQueryWrapper<>())); } /** * 连接查询返回一条记录 */ - DTO selectJoinOne(MyLambdaQueryWrapper wrapper, Class clazz); + DTO selectJoinOne(Class clazz, MyLambdaQueryWrapper wrapper); /** * ignore */ - default List selectJoinList(MyWrapperFunc wrapperFunc, Class clazz) { - return selectJoinList(wrapperFunc.apply(new MyLambdaQueryWrapper<>()), clazz); + default List selectJoinList(Class clazz, MyWrapperFunc wrapperFunc) { + return selectJoinList(clazz, wrapperFunc.apply(new MyLambdaQueryWrapper<>())); } /** * 连接查询返回集合 */ - List selectJoinList(MyLambdaQueryWrapper wrapper, Class clazz); + List selectJoinList(Class clazz, MyLambdaQueryWrapper wrapper); /** * ignore */ - default > IPage selectJoinListPage(P page, MyWrapperFunc wrapperFunc, Class clazz) { - return selectJoinListPage(page, wrapperFunc.apply(new MyLambdaQueryWrapper<>()), clazz); + default > IPage selectJoinListPage(P page, Class clazz, MyWrapperFunc wrapperFunc) { + return selectJoinListPage(page, clazz, wrapperFunc.apply(new MyLambdaQueryWrapper<>())); } /** * 连接查询返回集合并分页 */ - > IPage selectJoinListPage(P page, MyLambdaQueryWrapper wrapper, Class clazz); + > IPage selectJoinListPage(P page, Class clazz, MyLambdaQueryWrapper wrapper); /** diff --git a/src/main/java/com/github/mybatisplus/base/MyBaseServiceImpl.java b/src/main/java/com/github/mybatisplus/base/MyBaseServiceImpl.java index 1a67dd1..433d5c6 100644 --- a/src/main/java/com/github/mybatisplus/base/MyBaseServiceImpl.java +++ b/src/main/java/com/github/mybatisplus/base/MyBaseServiceImpl.java @@ -15,19 +15,19 @@ public class MyBaseServiceImpl, T> extends ServiceImpl @Override - public DTO selectJoinOne(MyLambdaQueryWrapper wrapper, Class clazz) { - return baseMapper.selectJoinOne(wrapper, clazz); + public DTO selectJoinOne(Class clazz, MyLambdaQueryWrapper wrapper) { + return baseMapper.selectJoinOne(clazz, wrapper); } @Override - public List selectJoinList(MyLambdaQueryWrapper wrapper, Class clazz) { - return baseMapper.selectJoinList(wrapper, clazz); + public List selectJoinList(Class clazz, MyLambdaQueryWrapper wrapper) { + return baseMapper.selectJoinList(clazz, wrapper); } @Override - public > IPage selectJoinListPage(P page, MyLambdaQueryWrapper wrapper, Class clazz) { - return baseMapper.selectJoinPage(page, wrapper, clazz); + public > IPage selectJoinListPage(P page, Class clazz, MyLambdaQueryWrapper wrapper) { + return baseMapper.selectJoinPage(page, clazz, wrapper); } @Override diff --git a/src/main/java/com/github/mybatisplus/interceptor/MyResultInterceptor.java b/src/main/java/com/github/mybatisplus/interceptor/MyResultInterceptor.java index c016482..7b12356 100644 --- a/src/main/java/com/github/mybatisplus/interceptor/MyResultInterceptor.java +++ b/src/main/java/com/github/mybatisplus/interceptor/MyResultInterceptor.java @@ -21,7 +21,6 @@ import java.util.Objects; * @author yulichang */ @Intercepts({@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})}) -//@Intercepts({@Signature(type = ResultSetHandler.class, method = "handleCursorResultSets", args = {Statement.class})}) public class MyResultInterceptor implements Interceptor { @@ -78,7 +77,7 @@ public class MyResultInterceptor implements Interceptor { return (Class) args.get("clazz"); } } catch (Exception e) { - e.printStackTrace(); + return null; } } } diff --git a/src/main/java/com/github/mybatisplus/method/MyAbstractMethod.java b/src/main/java/com/github/mybatisplus/method/MyAbstractMethod.java index 16caaaa..28d6b62 100644 --- a/src/main/java/com/github/mybatisplus/method/MyAbstractMethod.java +++ b/src/main/java/com/github/mybatisplus/method/MyAbstractMethod.java @@ -5,7 +5,6 @@ import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils; import com.github.mybatisplus.toolkit.Constant; -import com.github.mybatisplus.wrapper.MyLambdaQueryWrapper; import java.util.ArrayList; import java.util.List; @@ -24,7 +23,7 @@ public abstract class MyAbstractMethod extends AbstractMethod { String[] columns = selectColumns.split(StringPool.COMMA); List selectColumnList = new ArrayList<>(); for (String c : columns) { - selectColumnList.add(Constant.TABLE_ALIAS + MyLambdaQueryWrapper.TABLE_ALIAS_INDEX + StringPool.DOT + c); + selectColumnList.add(Constant.TABLE_ALIAS + StringPool.DOT + c); } selectColumns = String.join(StringPool.COMMA, selectColumnList); } diff --git a/src/main/java/com/github/mybatisplus/method/SelectJoinList.java b/src/main/java/com/github/mybatisplus/method/SelectJoinList.java index 7a4f4ce..6470e4f 100644 --- a/src/main/java/com/github/mybatisplus/method/SelectJoinList.java +++ b/src/main/java/com/github/mybatisplus/method/SelectJoinList.java @@ -2,7 +2,6 @@ package com.github.mybatisplus.method; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.github.mybatisplus.toolkit.Constant; -import com.github.mybatisplus.wrapper.MyLambdaQueryWrapper; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; @@ -17,7 +16,7 @@ public class SelectJoinList extends MyAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_LIST; String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), Constant.TABLE_ALIAS + MyLambdaQueryWrapper.TABLE_ALIAS_INDEX, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), Constant.TABLE_ALIAS, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/mybatisplus/method/SelectJoinMap.java b/src/main/java/com/github/mybatisplus/method/SelectJoinMap.java index f100bab..91c8f7b 100644 --- a/src/main/java/com/github/mybatisplus/method/SelectJoinMap.java +++ b/src/main/java/com/github/mybatisplus/method/SelectJoinMap.java @@ -2,7 +2,6 @@ package com.github.mybatisplus.method; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.github.mybatisplus.toolkit.Constant; -import com.github.mybatisplus.wrapper.MyLambdaQueryWrapper; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; @@ -17,7 +16,7 @@ public class SelectJoinMap extends MyAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAP; String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), Constant.TABLE_ALIAS + MyLambdaQueryWrapper.TABLE_ALIAS_INDEX, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), Constant.TABLE_ALIAS, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/mybatisplus/method/SelectJoinMaps.java b/src/main/java/com/github/mybatisplus/method/SelectJoinMaps.java index 5d9a96f..6b93310 100644 --- a/src/main/java/com/github/mybatisplus/method/SelectJoinMaps.java +++ b/src/main/java/com/github/mybatisplus/method/SelectJoinMaps.java @@ -2,7 +2,6 @@ package com.github.mybatisplus.method; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.github.mybatisplus.toolkit.Constant; -import com.github.mybatisplus.wrapper.MyLambdaQueryWrapper; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; @@ -17,7 +16,7 @@ public class SelectJoinMaps extends MyAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAPS; String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), Constant.TABLE_ALIAS + MyLambdaQueryWrapper.TABLE_ALIAS_INDEX, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), Constant.TABLE_ALIAS, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/mybatisplus/method/SelectJoinMapsPage.java b/src/main/java/com/github/mybatisplus/method/SelectJoinMapsPage.java index 17a63de..afbb6c0 100644 --- a/src/main/java/com/github/mybatisplus/method/SelectJoinMapsPage.java +++ b/src/main/java/com/github/mybatisplus/method/SelectJoinMapsPage.java @@ -2,7 +2,6 @@ package com.github.mybatisplus.method; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.github.mybatisplus.toolkit.Constant; -import com.github.mybatisplus.wrapper.MyLambdaQueryWrapper; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; @@ -17,7 +16,7 @@ public class SelectJoinMapsPage extends MyAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_MAPS_PAGE; String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), Constant.TABLE_ALIAS + MyLambdaQueryWrapper.TABLE_ALIAS_INDEX, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), Constant.TABLE_ALIAS, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/mybatisplus/method/SelectJoinOne.java b/src/main/java/com/github/mybatisplus/method/SelectJoinOne.java index fb68a97..aa61eed 100644 --- a/src/main/java/com/github/mybatisplus/method/SelectJoinOne.java +++ b/src/main/java/com/github/mybatisplus/method/SelectJoinOne.java @@ -2,7 +2,6 @@ package com.github.mybatisplus.method; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.github.mybatisplus.toolkit.Constant; -import com.github.mybatisplus.wrapper.MyLambdaQueryWrapper; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; @@ -17,7 +16,7 @@ public class SelectJoinOne extends MyAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_ONE; String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), Constant.TABLE_ALIAS + MyLambdaQueryWrapper.TABLE_ALIAS_INDEX, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), Constant.TABLE_ALIAS, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/mybatisplus/method/SelectJoinPage.java b/src/main/java/com/github/mybatisplus/method/SelectJoinPage.java index 8819dab..3cbd4bf 100644 --- a/src/main/java/com/github/mybatisplus/method/SelectJoinPage.java +++ b/src/main/java/com/github/mybatisplus/method/SelectJoinPage.java @@ -2,7 +2,6 @@ package com.github.mybatisplus.method; import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.github.mybatisplus.toolkit.Constant; -import com.github.mybatisplus.wrapper.MyLambdaQueryWrapper; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; @@ -17,7 +16,7 @@ public class SelectJoinPage extends MyAbstractMethod { public MappedStatement injectMappedStatement(Class mapperClass, Class modelClass, TableInfo tableInfo) { SqlMethod sqlMethod = SqlMethod.SELECT_JOIN_PAGE; String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(tableInfo, true), - tableInfo.getTableName(), Constant.TABLE_ALIAS + MyLambdaQueryWrapper.TABLE_ALIAS_INDEX, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); + tableInfo.getTableName(), Constant.TABLE_ALIAS, sqlWhereEntityWrapper(true, tableInfo), sqlComment()); SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass); return this.addSelectMappedStatementForOther(mapperClass, sqlMethod.getMethod(), sqlSource, Map.class); } diff --git a/src/main/java/com/github/mybatisplus/query/MyAbstractLambda.java b/src/main/java/com/github/mybatisplus/query/MyAbstractLambda.java new file mode 100644 index 0000000..debe0b2 --- /dev/null +++ b/src/main/java/com/github/mybatisplus/query/MyAbstractLambda.java @@ -0,0 +1,85 @@ +package com.github.mybatisplus.query; + +import com.baomidou.mybatisplus.core.toolkit.Assert; +import com.baomidou.mybatisplus.core.toolkit.LambdaUtils; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.core.toolkit.support.ColumnCache; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; +import com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda; +import com.github.mybatisplus.toolkit.Constant; +import org.apache.ibatis.reflection.property.PropertyNamer; + +import java.util.Arrays; +import java.util.Map; + +import static java.util.stream.Collectors.joining; + +/** + * copy {@link com.baomidou.mybatisplus.core.conditions.AbstractLambdaWrapper} + */ +@SuppressWarnings("serial") +public abstract class MyAbstractLambda> + extends MyAbstractWrapper, Children> { + + private Map columnMap = null; + private boolean initColumnMap = false; + + @SuppressWarnings("unchecked") + @Override + protected String columnsToString(SFunction... columns) { + return columnsToString(true, columns); + } + + @SuppressWarnings("unchecked") + protected String columnsToString(boolean onlyColumn, SFunction... columns) { + return Arrays.stream(columns).map(i -> Constant.TABLE_ALIAS + StringPool.DOT + columnToString(i, onlyColumn)).collect(joining(StringPool.COMMA)); + } + + @Override + protected String columnToString(SFunction column) { + return columnToString(column, true); + } + + protected String columnToString(SFunction column, boolean onlyColumn) { + return Constant.TABLE_ALIAS + StringPool.DOT + getColumn(LambdaUtils.resolve(column), onlyColumn); + } + + /** + * 获取 SerializedLambda 对应的列信息,从 lambda 表达式中推测实体类 + *

+ * 如果获取不到列信息,那么本次条件组装将会失败 + * + * @param lambda lambda 表达式 + * @param onlyColumn 如果是,结果: "name", 如果否: "name" as "name" + * @return 列 + * @throws com.baomidou.mybatisplus.core.exceptions.MybatisPlusException 获取不到列信息时抛出异常 + * @see SerializedLambda#getImplClass() + * @see SerializedLambda#getImplMethodName() + */ + private String getColumn(SerializedLambda lambda, boolean onlyColumn) { + Class aClass = lambda.getInstantiatedType(); + tryInitCache(aClass); + String fieldName = PropertyNamer.methodToProperty(lambda.getImplMethodName()); + ColumnCache columnCache = getColumnCache(fieldName, aClass); + return onlyColumn ? columnCache.getColumn() : columnCache.getColumnSelect(); + } + + private void tryInitCache(Class lambdaClass) { + if (!initColumnMap) { + final Class entityClass = getEntityClass(); + if (entityClass != null) { + lambdaClass = entityClass; + } + columnMap = LambdaUtils.getColumnMap(lambdaClass); + initColumnMap = true; + } + Assert.notNull(columnMap, "can not find lambda cache for this entity [%s]", lambdaClass.getName()); + } + + private ColumnCache getColumnCache(String fieldName, Class lambdaClass) { + ColumnCache columnCache = columnMap.get(LambdaUtils.formatKey(fieldName)); + Assert.notNull(columnCache, "can not find lambda cache for this property [%s] of entity [%s]", + fieldName, lambdaClass.getName()); + return columnCache; + } +} diff --git a/src/main/java/com/github/mybatisplus/query/MyAbstractWrapper.java b/src/main/java/com/github/mybatisplus/query/MyAbstractWrapper.java new file mode 100644 index 0000000..a035425 --- /dev/null +++ b/src/main/java/com/github/mybatisplus/query/MyAbstractWrapper.java @@ -0,0 +1,543 @@ +package com.github.mybatisplus.query; + +import com.baomidou.mybatisplus.core.conditions.ISqlSegment; +import com.baomidou.mybatisplus.core.conditions.SharedString; +import com.baomidou.mybatisplus.core.conditions.Wrapper; +import com.baomidou.mybatisplus.core.conditions.interfaces.Compare; +import com.baomidou.mybatisplus.core.conditions.interfaces.Func; +import com.baomidou.mybatisplus.core.conditions.interfaces.Join; +import com.baomidou.mybatisplus.core.conditions.interfaces.Nested; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; +import com.baomidou.mybatisplus.core.enums.SqlKeyword; +import com.baomidou.mybatisplus.core.enums.SqlLike; +import com.baomidou.mybatisplus.core.toolkit.*; +import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils; +import com.baomidou.mybatisplus.core.toolkit.sql.StringEscape; +import com.github.mybatisplus.query.interfaces.MyJoin; +import com.github.mybatisplus.toolkit.Constant; + +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.BiPredicate; +import java.util.function.Consumer; + +import static com.baomidou.mybatisplus.core.enums.SqlKeyword.*; +import static com.baomidou.mybatisplus.core.enums.WrapperKeyword.APPLY; +import static java.util.stream.Collectors.joining; + +/** + * copy {@link com.baomidou.mybatisplus.core.conditions.AbstractWrapper} + */ +@SuppressWarnings({"serial", "unchecked"}) +public abstract class MyAbstractWrapper> extends Wrapper + implements Compare, Nested, Join, Func, MyJoin { + + /** + * 占位符 + */ + protected final Children typedThis = (Children) this; + /** + * 必要度量 + */ + protected AtomicInteger paramNameSeq; + protected Map paramNameValuePairs; + protected SharedString lastSql; + /** + * SQL注释 + */ + protected SharedString sqlComment; + /** + * SQL起始语句 + */ + protected SharedString sqlFirst; + + /** + * 连表字段 + */ + protected SharedString from = SharedString.emptyString(); + /** + * ß + * 数据库表映射实体类 + */ + private T entity; + protected MergeSegments expression; + /** + * 实体类型(主要用于确定泛型以及取TableInfo缓存) + */ + private Class entityClass; + + @Override + public T getEntity() { + return entity; + } + + public Children setEntity(T entity) { + this.entity = entity; + return typedThis; + } + + public Class getEntityClass() { + if (entityClass == null && entity != null) { + entityClass = (Class) entity.getClass(); + } + return entityClass; + } + + public Children setEntityClass(Class entityClass) { + if (entityClass != null) { + this.entityClass = entityClass; + } + return typedThis; + } + + @Override + public Children leftJoin(boolean condition, String joinSql) { + if (condition) { + from.setStringValue(from.getStringValue() + Constant.LEFT_JOIN + joinSql); + } + return typedThis; + } + + @Override + public Children rightJoin(boolean condition, String joinSql) { + if (condition) { + from.setStringValue(from.getStringValue() + Constant.RIGHT_JOIN + joinSql); + } + return typedThis; + } + + + @Override + public Children innerJoin(boolean condition, String joinSql) { + if (condition) { + from.setStringValue(from.getStringValue() + Constant.INNER_JOIN + joinSql); + } + return typedThis; + } + + @Override + public Children allEq(boolean condition, Map params, boolean null2IsNull) { + if (condition && CollectionUtils.isNotEmpty(params)) { + params.forEach((k, v) -> { + if (StringUtils.checkValNotNull(v)) { + eq(k, v); + } else { + if (null2IsNull) { + isNull(k); + } + } + }); + } + return typedThis; + } + + @Override + public Children allEq(boolean condition, BiPredicate filter, Map params, boolean null2IsNull) { + if (condition && CollectionUtils.isNotEmpty(params)) { + params.forEach((k, v) -> { + if (filter.test(k, v)) { + if (StringUtils.checkValNotNull(v)) { + eq(k, v); + } else { + if (null2IsNull) { + isNull(k); + } + } + } + }); + } + return typedThis; + } + + @Override + public Children eq(boolean condition, R column, Object val) { + return addCondition(condition, column, EQ, val); + } + + @Override + public Children ne(boolean condition, R column, Object val) { + return addCondition(condition, column, NE, val); + } + + @Override + public Children gt(boolean condition, R column, Object val) { + return addCondition(condition, column, GT, val); + } + + @Override + public Children ge(boolean condition, R column, Object val) { + return addCondition(condition, column, GE, val); + } + + @Override + public Children lt(boolean condition, R column, Object val) { + return addCondition(condition, column, LT, val); + } + + @Override + public Children le(boolean condition, R column, Object val) { + return addCondition(condition, column, LE, val); + } + + @Override + public Children like(boolean condition, R column, Object val) { + return likeValue(condition, LIKE, column, val, SqlLike.DEFAULT); + } + + @Override + public Children notLike(boolean condition, R column, Object val) { + return likeValue(condition, NOT_LIKE, column, val, SqlLike.DEFAULT); + } + + @Override + public Children likeLeft(boolean condition, R column, Object val) { + return likeValue(condition, LIKE, column, val, SqlLike.LEFT); + } + + @Override + public Children likeRight(boolean condition, R column, Object val) { + return likeValue(condition, LIKE, column, val, SqlLike.RIGHT); + } + + @Override + public Children between(boolean condition, R column, Object val1, Object val2) { + return doIt(condition, () -> columnToString(column), BETWEEN, () -> formatSql("{0}", val1), AND, + () -> formatSql("{0}", val2)); + } + + @Override + public Children notBetween(boolean condition, R column, Object val1, Object val2) { + return doIt(condition, () -> columnToString(column), NOT_BETWEEN, () -> formatSql("{0}", val1), AND, + () -> formatSql("{0}", val2)); + } + + @Override + public Children and(boolean condition, Consumer consumer) { + return and(condition).addNestedCondition(condition, consumer); + } + + @Override + public Children or(boolean condition, Consumer consumer) { + return or(condition).addNestedCondition(condition, consumer); + } + + @Override + public Children nested(boolean condition, Consumer consumer) { + return addNestedCondition(condition, consumer); + } + + @Override + public Children not(boolean condition, Consumer consumer) { + return not(condition).addNestedCondition(condition, consumer); + } + + @Override + public Children or(boolean condition) { + return doIt(condition, OR); + } + + @Override + public Children apply(boolean condition, String applySql, Object... value) { + return doIt(condition, APPLY, () -> formatSql(applySql, value)); + } + + @Override + public Children last(boolean condition, String lastSql) { + if (condition) { + this.lastSql.setStringValue(StringPool.SPACE + lastSql); + } + return typedThis; + } + + @Override + public Children comment(boolean condition, String comment) { + if (condition) { + this.sqlComment.setStringValue(comment); + } + return typedThis; + } + + @Override + public Children first(boolean condition, String firstSql) { + if (condition) { + this.sqlFirst.setStringValue(firstSql); + } + return typedThis; + } + + @Override + public Children exists(boolean condition, String existsSql) { + return doIt(condition, EXISTS, () -> String.format("(%s)", existsSql)); + } + + @Override + public Children notExists(boolean condition, String existsSql) { + return not(condition).exists(condition, existsSql); + } + + @Override + public Children isNull(boolean condition, R column) { + return doIt(condition, () -> columnToString(column), IS_NULL); + } + + @Override + public Children isNotNull(boolean condition, R column) { + return doIt(condition, () -> columnToString(column), IS_NOT_NULL); + } + + @Override + public Children in(boolean condition, R column, Collection coll) { + return doIt(condition, () -> columnToString(column), IN, inExpression(coll)); + } + + @Override + public Children notIn(boolean condition, R column, Collection coll) { + return doIt(condition, () -> columnToString(column), NOT_IN, inExpression(coll)); + } + + @Override + public Children inSql(boolean condition, R column, String inValue) { + return doIt(condition, () -> columnToString(column), IN, () -> String.format("(%s)", inValue)); + } + + @Override + public Children notInSql(boolean condition, R column, String inValue) { + return doIt(condition, () -> columnToString(column), NOT_IN, () -> String.format("(%s)", inValue)); + } + + @Override + public Children groupBy(boolean condition, R... columns) { + if (ArrayUtils.isEmpty(columns)) { + return typedThis; + } + return doIt(condition, GROUP_BY, + () -> columns.length == 1 ? columnToString(columns[0]) : columnsToString(columns)); + } + + @Override + public Children orderBy(boolean condition, boolean isAsc, R... columns) { + if (ArrayUtils.isEmpty(columns)) { + return typedThis; + } + SqlKeyword mode = isAsc ? ASC : DESC; + for (R column : columns) { + doIt(condition, ORDER_BY, () -> columnToString(column), mode); + } + return typedThis; + } + + @Override + public Children having(boolean condition, String sqlHaving, Object... params) { + return doIt(condition, HAVING, () -> formatSqlIfNeed(condition, sqlHaving, params)); + } + + @Override + public Children func(boolean condition, Consumer consumer) { + if (condition) { + consumer.accept(typedThis); + } + return typedThis; + } + + /** + * 内部自用 + *

NOT 关键词

+ */ + protected Children not(boolean condition) { + return doIt(condition, NOT); + } + + /** + * 内部自用 + *

拼接 AND

+ */ + protected Children and(boolean condition) { + return doIt(condition, AND); + } + + /** + * 内部自用 + *

拼接 LIKE 以及 值

+ */ + protected Children likeValue(boolean condition, SqlKeyword keyword, R column, Object val, SqlLike sqlLike) { + return doIt(condition, () -> columnToString(column), keyword, () -> formatSql("{0}", SqlUtils.concatLike(val, sqlLike))); + } + + /** + * 普通查询条件 + * + * @param condition 是否执行 + * @param column 属性 + * @param sqlKeyword SQL 关键词 + * @param val 条件值 + */ + protected Children addCondition(boolean condition, R column, SqlKeyword sqlKeyword, Object val) { + return doIt(condition, () -> columnToString(column), sqlKeyword, () -> formatSql("{0}", val)); + } + + /** + * 多重嵌套查询条件 + * + * @param condition 查询条件值 + */ + protected Children addNestedCondition(boolean condition, Consumer consumer) { + if (condition) { + final Children instance = instance(); + consumer.accept(instance); + return doIt(true, APPLY, instance); + } + return typedThis; + } + + /** + * 子类返回一个自己的新对象 + */ + protected abstract Children instance(); + + /** + * 格式化SQL + * + * @param sqlStr SQL语句部分 + * @param params 参数集 + * @return sql + */ + protected final String formatSql(String sqlStr, Object... params) { + return formatSqlIfNeed(true, sqlStr, params); + } + + /** + *

+ * 根据需要格式化SQL
+ *
+ * Format SQL for methods: EntityQ.where/and/or...("name={0}", value); + * ALL the {i} will be replaced with #{MPGENVALi}
+ *
+ * ew.where("sample_name={0}", "haha").and("sample_age >{0} + * and sample_age<{1}", 18, 30) TO + * sample_name=#{MPGENVAL1} and sample_age>#{MPGENVAL2} and + * sample_age<#{MPGENVAL3}
+ *

+ * + * @param need 是否需要格式化 + * @param sqlStr SQL语句部分 + * @param params 参数集 + * @return sql + */ + protected final String formatSqlIfNeed(boolean need, String sqlStr, Object... params) { + if (!need || StringUtils.isBlank(sqlStr)) { + return null; + } + if (ArrayUtils.isNotEmpty(params)) { + for (int i = 0; i < params.length; ++i) { + String genParamName = Constants.WRAPPER_PARAM + paramNameSeq.incrementAndGet(); + sqlStr = sqlStr.replace(String.format("{%s}", i), + String.format(Constants.WRAPPER_PARAM_FORMAT, Constants.WRAPPER, genParamName)); + paramNameValuePairs.put(genParamName, params[i]); + } + } + return sqlStr; + } + + /** + * 获取in表达式 包含括号 + * + * @param value 集合 + */ + private ISqlSegment inExpression(Collection value) { + return () -> value.stream().map(i -> formatSql("{0}", i)) + .collect(joining(StringPool.COMMA, StringPool.LEFT_BRACKET, StringPool.RIGHT_BRACKET)); + } + + /** + * 必要的初始化 + */ + protected void initNeed() { + paramNameSeq = new AtomicInteger(0); + paramNameValuePairs = new HashMap<>(16); + expression = new MergeSegments(); + lastSql = SharedString.emptyString(); + sqlComment = SharedString.emptyString(); + sqlFirst = SharedString.emptyString(); + } + + @Override + public void clear() { + entity = null; + paramNameSeq.set(0); + paramNameValuePairs.clear(); + expression.clear(); + lastSql.toEmpty(); + sqlComment.toEmpty(); + sqlFirst.toEmpty(); + } + + /** + * 对sql片段进行组装 + * + * @param condition 是否执行 + * @param sqlSegments sql片段数组 + * @return children + */ + protected Children doIt(boolean condition, ISqlSegment... sqlSegments) { + if (condition) { + expression.add(sqlSegments); + } + return typedThis; + } + + @Override + public String getSqlSegment() { + return expression.getSqlSegment() + lastSql.getStringValue(); + } + + @Override + public String getSqlComment() { + if (StringUtils.isNotBlank(sqlComment.getStringValue())) { + return "/*" + StringEscape.escapeRawString(sqlComment.getStringValue()) + "*/"; + } + return null; + } + + @Override + public String getSqlFirst() { + if (StringUtils.isNotBlank(sqlFirst.getStringValue())) { + return StringEscape.escapeRawString(sqlFirst.getStringValue()); + } + return null; + } + + @Override + public MergeSegments getExpression() { + return expression; + } + + public Map getParamNameValuePairs() { + return paramNameValuePairs; + } + + /** + * 获取 columnName + */ + protected String columnToString(R column) { + return (String) column; + } + + /** + * 多字段转换为逗号 "," 分割字符串 + * + * @param columns 多字段 + */ + protected String columnsToString(R... columns) { + return Arrays.stream(columns).map(this::columnToString).collect(joining(StringPool.COMMA)); + } + + @Override + @SuppressWarnings("all") + public Children clone() { + return SerializationUtils.clone(typedThis); + } +} diff --git a/src/main/java/com/github/mybatisplus/query/MyLambdaQuery.java b/src/main/java/com/github/mybatisplus/query/MyLambdaQuery.java new file mode 100644 index 0000000..5efb207 --- /dev/null +++ b/src/main/java/com/github/mybatisplus/query/MyLambdaQuery.java @@ -0,0 +1,188 @@ +package com.github.mybatisplus.query; + +import com.baomidou.mybatisplus.core.conditions.SharedString; +import com.baomidou.mybatisplus.core.conditions.query.Query; +import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; +import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; +import com.baomidou.mybatisplus.core.toolkit.Assert; +import com.baomidou.mybatisplus.core.toolkit.StringPool; +import com.baomidou.mybatisplus.core.toolkit.StringUtils; +import com.baomidou.mybatisplus.core.toolkit.support.SFunction; +import com.github.mybatisplus.toolkit.Constant; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +/** + * copy {@link com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper} + *

+ * sqlSelect 由覆盖改为追加 + */ +@SuppressWarnings("serial") +public class MyLambdaQuery extends MyAbstractLambda> + implements Query, T, SFunction> { + + /** + * 查询字段 + */ + private SharedString sqlSelect = new SharedString(); + + + /** + * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity) + */ + public MyLambdaQuery() { + this((T) null); + } + + /** + * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity) + */ + public MyLambdaQuery(T entity) { + super.setEntity(entity); + super.initNeed(); + } + + /** + * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(entity) + */ + public MyLambdaQuery(Class entityClass) { + super.setEntityClass(entityClass); + super.initNeed(); + } + + /** + * 不建议直接 new 该实例,使用 Wrappers.lambdaQuery(...) + */ + MyLambdaQuery(T entity, Class entityClass, SharedString from, SharedString sqlSelect, AtomicInteger paramNameSeq, + Map paramNameValuePairs, MergeSegments mergeSegments, + SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) { + super.setEntity(entity); + super.setEntityClass(entityClass); + this.paramNameSeq = paramNameSeq; + this.paramNameValuePairs = paramNameValuePairs; + this.expression = mergeSegments; + this.sqlSelect = sqlSelect; + this.from = from; + this.lastSql = lastSql; + this.sqlComment = sqlComment; + this.sqlFirst = sqlFirst; + } + + /** + * SELECT 部分 SQL 设置 + * + * @param columns 查询字段 + */ + @SafeVarargs + @Override + public final MyLambdaQuery select(SFunction... columns) { + if (ArrayUtils.isNotEmpty(columns)) { + String s = columnsToString(false, columns); + if (StringUtils.isBlank(sqlSelect.getStringValue())) { + this.sqlSelect.setStringValue(s); + } else { + this.sqlSelect.setStringValue(this.getSqlSelect() + StringPool.COMMA + s); + } + } + return typedThis; + } + + @SafeVarargs + public final MyLambdaQuery select(String... columns) { + if (ArrayUtils.isNotEmpty(columns)) { + String s = String.join(StringPool.COMMA, columns); + if (StringUtils.isBlank(sqlSelect.getStringValue())) { + this.sqlSelect.setStringValue(s); + } else { + this.sqlSelect.setStringValue(this.getSqlSelect() + StringPool.COMMA + s); + } + } + return typedThis; + } + + /** + * 过滤查询的字段信息(主键除外!) + *

例1: 只要 java 字段名以 "test" 开头的 -> select(i -> i.getProperty().startsWith("test"))

+ *

例2: 只要 java 字段属性是 CharSequence 类型的 -> select(TableFieldInfo::isCharSequence)

+ *

例3: 只要 java 字段没有填充策略的 -> select(i -> i.getFieldFill() == FieldFill.DEFAULT)

+ *

例4: 要全部字段 -> select(i -> true)

+ *

例5: 只要主键字段 -> select(i -> false)

+ * + * @param predicate 过滤方式 + * @return this + */ + @Override + public MyLambdaQuery select(Class entityClass, Predicate predicate) { + if (entityClass == null) { + entityClass = getEntityClass(); + } else { + setEntityClass(entityClass); + } + Assert.notNull(entityClass, "entityClass can not be null"); + String s = TableInfoHelper.getTableInfo(entityClass).chooseSelect(predicate); + List list = Arrays.stream(s.split(StringPool.COMMA)).map(i -> Constant.TABLE_ALIAS + StringPool.DOT + i).collect(Collectors.toList()); + String join = String.join(StringPool.COMMA, list); + if (StringUtils.isBlank(sqlSelect.getStringValue())) { + this.sqlSelect.setStringValue(join); + } else { + this.sqlSelect.setStringValue(this.getSqlSelect() + StringPool.COMMA + join); + } + return typedThis; + } + + public final MyLambdaQuery selectAll(Class clazz) { + TableInfo info = TableInfoHelper.getTableInfo(clazz); + List list = new ArrayList<>(); + list.add(Constant.TABLE_ALIAS + StringPool.DOT + info.getKeyColumn()); + list.addAll(info.getFieldList().stream().map(i -> Constant.TABLE_ALIAS + StringPool.DOT + i.getColumn()).collect(Collectors.toList())); + String join = String.join(StringPool.COMMA, list); + if (StringUtils.isBlank(sqlSelect.getStringValue())) { + this.sqlSelect.setStringValue(join); + } else { + this.sqlSelect.setStringValue(this.getSqlSelect() + StringPool.COMMA + join); + } + return typedThis; + } + + /** + * 返回一个支持 lambda 函数写法的 wrapper + */ + public MyQueryWrapper stringQuery() { + return new MyQueryWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs, + expression, sqlSelect, from, lastSql, sqlComment, sqlFirst); + } + + @Override + public String getSqlSelect() { + return sqlSelect.getStringValue(); + } + + public String getFrom() { + return from.getStringValue(); + } + + /** + * 用于生成嵌套 sql + *

故 sqlSelect from不向下传递

+ */ + @Override + protected MyLambdaQuery instance() { + return new MyLambdaQuery<>(getEntity(), getEntityClass(), null, null, paramNameSeq, paramNameValuePairs, + new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString()); + } + + @Override + public void clear() { + super.clear(); + sqlSelect.toNull(); + } +} diff --git a/src/main/java/com/github/mybatisplus/query/MyQueryWrapper.java b/src/main/java/com/github/mybatisplus/query/MyQueryWrapper.java new file mode 100644 index 0000000..17147e6 --- /dev/null +++ b/src/main/java/com/github/mybatisplus/query/MyQueryWrapper.java @@ -0,0 +1,112 @@ +package com.github.mybatisplus.query; + +import com.baomidou.mybatisplus.core.conditions.SharedString; +import com.baomidou.mybatisplus.core.conditions.query.Query; +import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; +import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; +import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; +import com.baomidou.mybatisplus.core.toolkit.ArrayUtils; +import com.baomidou.mybatisplus.core.toolkit.StringPool; + +import java.util.Map; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.function.Predicate; + +/** + * copy {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper} + */ +@SuppressWarnings("serial") +public class MyQueryWrapper extends MyAbstractWrapper> + implements Query, T, String> { + + /** + * 查询字段 + */ + private SharedString sqlSelect = new SharedString(); + + public MyQueryWrapper() { + this(null); + } + + public MyQueryWrapper(T entity) { + super.setEntity(entity); + super.initNeed(); + } + + public MyQueryWrapper(T entity, String... columns) { + super.setEntity(entity); + super.initNeed(); + this.select(columns); + } + + /** + * 非对外公开的构造方法,只用于生产嵌套 sql + * + * @param entityClass 本不应该需要的 + */ + public MyQueryWrapper(T entity, Class entityClass, AtomicInteger paramNameSeq, + Map paramNameValuePairs, MergeSegments mergeSegments, + SharedString sqlSelect, SharedString from, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst) { + super.setEntity(entity); + super.setEntityClass(entityClass); + this.paramNameSeq = paramNameSeq; + this.paramNameValuePairs = paramNameValuePairs; + this.expression = mergeSegments; + this.sqlSelect = sqlSelect; + this.lastSql = lastSql; + this.from = from; + this.sqlComment = sqlComment; + this.sqlFirst = sqlFirst; + } + + @Override + public MyQueryWrapper select(String... columns) { + if (ArrayUtils.isNotEmpty(columns)) { + this.sqlSelect.setStringValue(String.join(StringPool.COMMA, columns)); + } + return typedThis; + } + + @Override + public MyQueryWrapper select(Class entityClass, Predicate predicate) { + super.setEntityClass(entityClass); + this.sqlSelect.setStringValue(TableInfoHelper.getTableInfo(getEntityClass()).chooseSelect(predicate)); + return typedThis; + } + + @Override + public String getSqlSelect() { + return sqlSelect.getStringValue(); + } + + + public String getFrom() { + return from.getStringValue(); + } + + /** + * 返回一个支持 lambda 函数写法的 wrapper + */ + public MyLambdaQuery lambda() { + return new MyLambdaQuery<>(getEntity(), getEntityClass(), null, null, paramNameSeq, paramNameValuePairs, + expression, lastSql, sqlComment, sqlFirst); + } + + /** + * 用于生成嵌套 sql + *

+ * 故 sqlSelect from 不向下传递 + *

+ */ + @Override + protected MyQueryWrapper instance() { + return new MyQueryWrapper<>(getEntity(), getEntityClass(), paramNameSeq, paramNameValuePairs, new MergeSegments(), + null, null, SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString()); + } + + @Override + public void clear() { + super.clear(); + sqlSelect.toNull(); + } +} diff --git a/src/main/java/com/github/mybatisplus/query/interfaces/MyJoin.java b/src/main/java/com/github/mybatisplus/query/interfaces/MyJoin.java new file mode 100644 index 0000000..9877e52 --- /dev/null +++ b/src/main/java/com/github/mybatisplus/query/interfaces/MyJoin.java @@ -0,0 +1,22 @@ +package com.github.mybatisplus.query.interfaces; + +public interface MyJoin { + + default Children leftJoin(String joinSql) { + return leftJoin(true, joinSql); + } + + Children leftJoin(boolean condition, String joinSql); + + default Children rightJoin(String joinSql) { + return rightJoin(true, joinSql); + } + + Children rightJoin(boolean condition, String joinSql); + + default Children innerJoin(String joinSql) { + return innerJoin(true, joinSql); + } + + Children innerJoin(boolean condition, String joinSql); +} diff --git a/src/main/java/com/github/mybatisplus/wrapper/MyAbstractLambdaWrapper.java b/src/main/java/com/github/mybatisplus/wrapper/MyAbstractLambdaWrapper.java index f60ad70..144a115 100644 --- a/src/main/java/com/github/mybatisplus/wrapper/MyAbstractLambdaWrapper.java +++ b/src/main/java/com/github/mybatisplus/wrapper/MyAbstractLambdaWrapper.java @@ -22,16 +22,6 @@ public abstract class MyAbstractLambdaWrapper columnMap = null; - @SuppressWarnings("unchecked") - @Override - protected String columnsToString(SFunction... columns) { - return columnsToString(true, columns); - } - - @SuppressWarnings("unchecked") - protected String columnsToString(boolean onlyColumn, SFunction... columns) { - return Arrays.stream(columns).map(i -> columnToString(i, onlyColumn)).collect(joining(StringPool.COMMA)); - } @Override protected String columnToString(SFunction column) { diff --git a/src/main/java/com/github/mybatisplus/wrapper/MyAbstractWrapper.java b/src/main/java/com/github/mybatisplus/wrapper/MyAbstractWrapper.java index dc99039..3cddbaa 100644 --- a/src/main/java/com/github/mybatisplus/wrapper/MyAbstractWrapper.java +++ b/src/main/java/com/github/mybatisplus/wrapper/MyAbstractWrapper.java @@ -171,9 +171,6 @@ public abstract class MyAbstractWrapper getParamNameValuePairs() { - return paramNameValuePairs; - } /** * 获取 columnName @@ -182,15 +179,6 @@ public abstract class MyAbstractWrapper extends MyAbstractLambdaWrapper> implements Query, T, SFunction>, MyJoin, T> { @@ -52,22 +52,23 @@ public class MyJoinLambdaQueryWrapper extends MyAbstractLambdaWrapper entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, SharedString lastSql, SharedString sqlComment) { - super.setEntity(entity); - this.setEntityClass(entityClass); + setEntity(entity); + setEntityClass(entityClass); this.paramNameSeq = paramNameSeq; this.paramNameValuePairs = paramNameValuePairs; this.expression = mergeSegments; @@ -92,8 +93,9 @@ public class MyJoinLambdaQueryWrapper extends MyAbstractLambdaWrapper select(SFunction... columns) { + public final MyJoinLambdaQueryWrapper select(SFunction... columns) { if (ArrayUtils.isNotEmpty(columns)) { for (SFunction str : columns) { selectColumnList.add(new SelectColumn(rUid, columnToString(str), null, null)); @@ -157,7 +159,7 @@ public class MyJoinLambdaQueryWrapper extends MyAbstractLambdaWrapper select(Class entityClass, Predicate predicate) { - this.setEntityClass(entityClass); + setEntityClass(entityClass); TableInfo info = TableInfoHelper.getTableInfo(getEntityClass()); Assert.notNull(info, "can not find table to entity %s", entityClass); info.getFieldList().stream().filter(predicate).forEach(s -> @@ -165,71 +167,13 @@ public class MyJoinLambdaQueryWrapper extends MyAbstractLambdaWrapper MyJoinLambdaQueryWrapper as(SFunction entityColumn, SFunction DTOColumn) { - selectColumnList.add(new SelectColumn(rUid, columnToString(entityColumn), MyLambdaUtils.getName(DTOColumn), null)); - return this; - } - - public MyJoinLambdaQueryWrapper asCount(MySFunction entityColumn, SFunction DTOColumn) { - selectColumnList.add(new SelectColumn(rUid, columnToString(entityColumn), MyLambdaUtils.getName(DTOColumn), SelectFunc.COUNT)); - return this; - } - - public MyJoinLambdaQueryWrapper asSum(MySFunction entityColumn, SFunction DTOColumn) { - selectColumnList.add(new SelectColumn(rUid, columnToString(entityColumn), MyLambdaUtils.getName(DTOColumn), SelectFunc.SUM)); - return this; - } - - public MyJoinLambdaQueryWrapper asAvg(MySFunction entityColumn, SFunction DTOColumn) { - selectColumnList.add(new SelectColumn(rUid, columnToString(entityColumn), MyLambdaUtils.getName(DTOColumn), SelectFunc.AVG)); - return this; - } - - public MyJoinLambdaQueryWrapper asMax(MySFunction entityColumn, SFunction DTOColumn) { - selectColumnList.add(new SelectColumn(rUid, columnToString(entityColumn), MyLambdaUtils.getName(DTOColumn), SelectFunc.MAX)); - return this; - } - - public MyJoinLambdaQueryWrapper asMin(MySFunction entityColumn, SFunction DTOColumn) { - selectColumnList.add(new SelectColumn(rUid, columnToString(entityColumn), MyLambdaUtils.getName(DTOColumn), SelectFunc.MIN)); - return this; - } - - public MyJoinLambdaQueryWrapper asDateFormat(MySFunction entityColumn, SFunction DTOColumn) { - selectColumnList.add(new SelectColumn(rUid, columnToString(entityColumn), MyLambdaUtils.getName(DTOColumn), SelectFunc.DATE_FORMAT)); - return this; - } - - /** - * 左连接查询 - * - * @param leftCondition 主表参与比较的字段 (on) - * @param rightCondition 子表参与比较的字段 (on) - * @param rightWrapper 子表的wrapper - */ @Override - public MyJoinLambdaQueryWrapper leftJoin(boolean condition, String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return join(condition, alias, Constant.LEFT_JOIN, leftCondition, rightCondition, rightWrapper); - } - - /** - * 右连接查询(参考左连接) - */ - @Override - public MyJoinLambdaQueryWrapper rightJoin(boolean condition, String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return join(condition, alias, Constant.RIGHT_JOIN, leftCondition, rightCondition, rightWrapper); - } - - /** - * 内连接查询(参考左连接) - */ - @Override - public MyJoinLambdaQueryWrapper innerJoin(boolean condition, String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return join(condition, alias, Constant.INNER_JOIN, leftCondition, rightCondition, rightWrapper); - } - - private MyJoinLambdaQueryWrapper join(boolean condition, String alias, String keyWord, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { + public MyJoinLambdaQueryWrapper join(boolean condition, + String alias, + String keyWord, + MySFunction leftCondition, + MySFunction rightCondition, + Function, MyJoinLambdaQueryWrapper> rightWrapper) { if (condition) { setEntityClass(MyLambdaUtils.getEntityClass(leftCondition)); int childrenId = rUid + 1; @@ -237,7 +181,7 @@ public class MyJoinLambdaQueryWrapper extends MyAbstractLambdaWrapper apply = rightWrapper.apply(new MyJoinLambdaQueryWrapper<>(childrenId)); + MyJoinLambdaQueryWrapper apply = (MyJoinLambdaQueryWrapper) rightWrapper.apply(new MyJoinLambdaQueryWrapper<>(childrenId)); classList.addAll(apply.classList); this.selectColumnList.addAll(apply.selectColumnList); } diff --git a/src/main/java/com/github/mybatisplus/wrapper/MyLambdaQueryWrapper.java b/src/main/java/com/github/mybatisplus/wrapper/MyLambdaQueryWrapper.java index 87dbb97..cb7574c 100644 --- a/src/main/java/com/github/mybatisplus/wrapper/MyLambdaQueryWrapper.java +++ b/src/main/java/com/github/mybatisplus/wrapper/MyLambdaQueryWrapper.java @@ -2,6 +2,7 @@ package com.github.mybatisplus.wrapper; import com.baomidou.mybatisplus.core.conditions.ISqlSegment; import com.baomidou.mybatisplus.core.conditions.SharedString; +import com.baomidou.mybatisplus.core.conditions.query.Query; import com.baomidou.mybatisplus.core.conditions.segments.MergeSegments; import com.baomidou.mybatisplus.core.enums.SqlKeyword; import com.baomidou.mybatisplus.core.enums.SqlLike; @@ -12,12 +13,10 @@ import com.baomidou.mybatisplus.core.metadata.TableInfoHelper; import com.baomidou.mybatisplus.core.toolkit.*; import com.baomidou.mybatisplus.core.toolkit.sql.SqlUtils; import com.baomidou.mybatisplus.core.toolkit.support.SFunction; -import com.github.mybatisplus.wrapper.interfaces.MyCompare; -import com.github.mybatisplus.wrapper.interfaces.MyFunc; -import com.github.mybatisplus.wrapper.interfaces.MyNested; import com.github.mybatisplus.func.MySFunction; import com.github.mybatisplus.toolkit.Constant; import com.github.mybatisplus.toolkit.MyLambdaUtils; +import com.github.mybatisplus.wrapper.interfaces.*; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @@ -31,6 +30,8 @@ import static java.util.stream.Collectors.joining; /** * 连接查询Query + * 只允许主表有条件查询,内部的表只允许select和继续连表的功能, + * 所以将条件查询接口在此实现 结构臃肿,有待进一步优化 * * @author yulichang * @see com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper @@ -40,125 +41,85 @@ import static java.util.stream.Collectors.joining; * @see com.baomidou.mybatisplus.core.conditions.interfaces.Func * @since 2021/01/19 */ -public class MyLambdaQueryWrapper extends MyJoinLambdaQueryWrapper - implements MyCompare>, MyNested, MyLambdaQueryWrapper>, - MyFunc> { +@SuppressWarnings("all") +public class MyLambdaQueryWrapper extends MyAbstractLambdaWrapper> + implements + Query, T, SFunction>, + MyJoin, T>, + MyCompare>, + MyNested, MyLambdaQueryWrapper>, + MyFunc>, + MyMPJoin> { + + + private MyJoinLambdaQueryWrapper wrapper = new MyJoinLambdaQueryWrapper<>(); + /** * 表别名初始序号 */ public static final int TABLE_ALIAS_INDEX = 0; - /** - * 主表默认别名 - */ - public static final String DEFAULT_ALIAS = "t"; public MyLambdaQueryWrapper() { this(null); } public MyLambdaQueryWrapper(T entity) { - super.rUid = TABLE_ALIAS_INDEX; - super.setEntity(entity); + wrapper.rUid = TABLE_ALIAS_INDEX; + wrapper.setEntity(entity); super.initNeed(); } MyLambdaQueryWrapper(T entity, Class entityClass, SharedString sqlSelect, AtomicInteger paramNameSeq, Map paramNameValuePairs, MergeSegments mergeSegments, SharedString lastSql, SharedString sqlComment, SharedString sqlFirst, - int rUid, List selectColumns, List classList) { + int rUid, List selectColumns, List classList) { super.setEntity(entity); super.setEntityClass(entityClass); this.paramNameSeq = paramNameSeq; this.paramNameValuePairs = paramNameValuePairs; this.expression = mergeSegments; - this.sqlSelect = sqlSelect; + this.wrapper.sqlSelect = sqlSelect; this.lastSql = lastSql; this.sqlComment = sqlComment; this.sqlFirst = sqlFirst; - this.rUid = rUid; - this.selectColumnList = selectColumns; - this.classList = classList; + + wrapper.rUid = rUid; + wrapper.selectColumnList = selectColumns; + wrapper.classList = classList; } @Override protected MyLambdaQueryWrapper instance() { return new MyLambdaQueryWrapper<>(getEntity(), getEntityClass(), null, paramNameSeq, paramNameValuePairs, new MergeSegments(), SharedString.emptyString(), SharedString.emptyString(), SharedString.emptyString(), - rUid, selectColumnList, classList); + wrapper.rUid, wrapper.selectColumnList, wrapper.classList); } @Override - public MyLambdaQueryWrapper leftJoin(boolean condition, String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return join(condition, alias, Constant.LEFT_JOIN, leftCondition, rightCondition, rightWrapper); - } - - @Override - public MyLambdaQueryWrapper leftJoin(MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return this.leftJoin(true, null, leftCondition, rightCondition, rightWrapper); - } - - @Override - public MyLambdaQueryWrapper leftJoin(String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return this.leftJoin(true, alias, leftCondition, rightCondition, rightWrapper); - } - - @Override - public MyLambdaQueryWrapper leftJoin(boolean condition, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return this.leftJoin(condition, null, leftCondition, rightCondition, rightWrapper); - } - - public MyLambdaQueryWrapper rightJoin(boolean condition, String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return join(condition, alias, Constant.RIGHT_JOIN, leftCondition, rightCondition, rightWrapper); - } - - @Override - public MyLambdaQueryWrapper rightJoin(MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return this.rightJoin(true, null, leftCondition, rightCondition, rightWrapper); - } - - @Override - public MyLambdaQueryWrapper rightJoin(String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return this.rightJoin(true, alias, leftCondition, rightCondition, rightWrapper); - } - - @Override - public MyLambdaQueryWrapper rightJoin(boolean condition, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return this.rightJoin(condition, null, leftCondition, rightCondition, rightWrapper); - } - - - public MyLambdaQueryWrapper innerJoin(boolean condition, String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return join(condition, alias, Constant.INNER_JOIN, leftCondition, rightCondition, rightWrapper); - } - - @Override - public MyLambdaQueryWrapper innerJoin(MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return this.innerJoin(true, null, leftCondition, rightCondition, rightWrapper); - } - - @Override - public MyLambdaQueryWrapper innerJoin(String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return this.innerJoin(true, alias, leftCondition, rightCondition, rightWrapper); - } - - @Override - public MyLambdaQueryWrapper innerJoin(boolean condition, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { - return this.innerJoin(condition, null, leftCondition, rightCondition, rightWrapper); - } - - private MyLambdaQueryWrapper join(boolean condition, String alias, String keyWord, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { + public MyLambdaQueryWrapper join(boolean condition, + String alias, + String keyWord, + MySFunction leftCondition, + MySFunction rightCondition, + Function, MyJoinLambdaQueryWrapper> rightWrapper) { if (condition) { setEntityClass(MyLambdaUtils.getEntityClass(leftCondition)); Class clazz = MyLambdaUtils.getEntityClass(rightCondition); TableInfo info = TableInfoHelper.getTableInfo(clazz); Assert.notNull(info, "can not find table to entity %s", clazz); - classList.add(new SubTable(alias, keyWord, rUid, MyLambdaUtils.getColumn(leftCondition), classList.size() + 1, MyLambdaUtils.getColumn(rightCondition), info.getTableName())); - MyJoinLambdaQueryWrapper apply = rightWrapper.apply(new MyJoinLambdaQueryWrapper<>(classList.size())); - classList.addAll(apply.classList); - this.selectColumnList.addAll(apply.selectColumnList); + wrapper.classList.add(new MyJoinLambdaQueryWrapper.SubTable(alias, + keyWord, + wrapper.rUid, + MyLambdaUtils.getColumn(leftCondition), + wrapper.classList.size() + 1, + MyLambdaUtils.getColumn(rightCondition), + info.getTableName())); + MyJoinLambdaQueryWrapper apply = rightWrapper.apply(new MyJoinLambdaQueryWrapper<>(wrapper.classList.size())); + wrapper.classList.addAll(apply.classList); + wrapper.selectColumnList.addAll(apply.selectColumnList); } return this; } @@ -166,77 +127,39 @@ public class MyLambdaQueryWrapper extends MyJoinLambdaQueryWrapper @SafeVarargs @Override public final MyLambdaQueryWrapper select(SFunction... columns) { - super.select(columns); - return this; - } - - @Override - public MyLambdaQueryWrapper selectAll(Class clazz) { - super.selectAll(clazz); - return this; - } - - @Override - public MyLambdaQueryWrapper selectDistinct() { - super.selectDistinct(); + wrapper.select(columns); return this; } @Override public MyLambdaQueryWrapper select(Predicate predicate) { - super.select(predicate); + wrapper.select(predicate); return this; } @Override public MyLambdaQueryWrapper select(Class entityClass, Predicate predicate) { - super.select(entityClass, predicate); + wrapper.select(entityClass, predicate); return this; } - @Override - public MyLambdaQueryWrapper as(SFunction entityColumn, SFunction DTOColumn) { - super.as(entityColumn, DTOColumn); + + public MyLambdaQueryWrapper selectAll(Class clazz) { + wrapper.selectAll(clazz); return this; } - public MyLambdaQueryWrapper asCount(MySFunction entityColumn, SFunction DTOColumn) { - super.asCount(entityColumn, DTOColumn); + public MyLambdaQueryWrapper selectDistinct() { + wrapper.selectDistinct(); return this; } - public MyLambdaQueryWrapper asSum(MySFunction entityColumn, SFunction DTOColumn) { - super.asSum(entityColumn, DTOColumn); - return this; - } - - public MyLambdaQueryWrapper asAvg(MySFunction entityColumn, SFunction DTOColumn) { - super.asAvg(entityColumn, DTOColumn); - return this; - } - - public MyLambdaQueryWrapper asMax(MySFunction entityColumn, SFunction DTOColumn) { - super.asMax(entityColumn, DTOColumn); - return this; - } - - public MyLambdaQueryWrapper asMin(MySFunction entityColumn, SFunction DTOColumn) { - super.asMin(entityColumn, DTOColumn); - return this; - } - - public MyLambdaQueryWrapper asDateFormat(MySFunction entityColumn, SFunction DTOColumn) { - super.asDateFormat(entityColumn, DTOColumn); - return this; - } - - @Override public String getSqlSelect() { - if (StringUtils.isBlank(sqlSelect.getStringValue()) && CollectionUtils.isNotEmpty(selectColumnList)) { + if (StringUtils.isBlank(wrapper.sqlSelect.getStringValue()) && CollectionUtils.isNotEmpty(wrapper.selectColumnList)) { List collect = new ArrayList<>(); - selectColumnList.forEach(c -> { - String s = Constant.TABLE_ALIAS + c.getUid() + StringPool.DOT + c.getColumn(); + wrapper.selectColumnList.forEach(c -> { + String s = Constant.TABLE_ALIAS + (c.getUid() == TABLE_ALIAS_INDEX ? "" : c.getUid()) + StringPool.DOT + c.getColumn(); if (c.getFunction() != null) { s = String.format(c.getFunction().getSql(), s); } @@ -246,9 +169,9 @@ public class MyLambdaQueryWrapper extends MyJoinLambdaQueryWrapper collect.add(s + Constant.AS + c.getAs()); } }); - this.sqlSelect.setStringValue(String.join(StringPool.COMMA, collect)); + wrapper.sqlSelect.setStringValue(String.join(StringPool.COMMA, collect)); } - return sqlSelect.getStringValue(); + return wrapper.sqlSelect.getStringValue(); } @Override @@ -257,29 +180,29 @@ public class MyLambdaQueryWrapper extends MyJoinLambdaQueryWrapper } public String getFrom() { - if (StringUtils.isNotBlank(from.getStringValue())) { - return from.getStringValue(); + if (StringUtils.isNotBlank(wrapper.from.getStringValue())) { + return wrapper.from.getStringValue(); } StringBuilder sb = new StringBuilder(); - this.classList.forEach(right -> + wrapper.classList.forEach(right -> sb.append(right.getKeyWord()).append(right.getRightTableName()) .append(StringPool.SPACE) .append(Constant.TABLE_ALIAS) - .append(right.getRightUid()) + .append(right.getRightUid() == TABLE_ALIAS_INDEX ? StringPool.EMPTY : right.getRightUid()) .append(Constant.ON) .append(Constant.TABLE_ALIAS) - .append(right.getLeftUid()) + .append(right.getLeftUid() == TABLE_ALIAS_INDEX ? StringPool.EMPTY : right.getLeftUid()) .append(StringPool.DOT) .append(right.getLeftColumn()) .append(Constant.EQUALS) .append(Constant.TABLE_ALIAS) - .append(right.getRightUid()) + .append(right.getRightUid() == TABLE_ALIAS_INDEX ? StringPool.EMPTY : right.getRightUid()) .append(StringPool.DOT) .append(right.getRightColumn()) .append(StringPool.SPACE) ); - this.from.setStringValue(sb.toString()); - return this.from.getStringValue(); + wrapper.from.setStringValue(sb.toString()); + return wrapper.from.getStringValue(); } /** @@ -287,12 +210,12 @@ public class MyLambdaQueryWrapper extends MyJoinLambdaQueryWrapper */ private String getClassTablePrefix(Class clazz) { if (getEntityClass() == clazz) { - return Constant.TABLE_ALIAS + rUid; + return Constant.TABLE_ALIAS; } else { TableInfo info = TableInfoHelper.getTableInfo(clazz); Assert.notNull(info, "can not find table to entity %s", clazz); String tableName = info.getTableName(); - for (SubTable sub : classList) { + for (MyJoinLambdaQueryWrapper.SubTable sub : wrapper.classList) { if (sub.getRightTableName().equals(tableName)) { return Constant.TABLE_ALIAS + sub.getRightUid(); } @@ -306,10 +229,10 @@ public class MyLambdaQueryWrapper extends MyJoinLambdaQueryWrapper */ private String getColumn(MySFunction column, String alias) { if (alias != null) { - if (alias.equals(DEFAULT_ALIAS)) { - return Constant.TABLE_ALIAS + rUid + StringPool.DOT + column2String(column, true); + if (alias.equals(Constant.TABLE_ALIAS)) { + return Constant.TABLE_ALIAS + StringPool.DOT + column2String(column, true); } - for (SubTable sub : classList) { + for (MyJoinLambdaQueryWrapper.SubTable sub : wrapper.classList) { if (alias.equals(sub.getAlias())) { return Constant.TABLE_ALIAS + sub.getRightUid() + StringPool.DOT + column2String(column, true); } @@ -440,10 +363,50 @@ public class MyLambdaQueryWrapper extends MyJoinLambdaQueryWrapper return doIt(condition, AND); } - private MyLambdaQueryWrapper or(boolean condition) { + @Override + public MyLambdaQueryWrapper or(boolean condition) { return doIt(condition, OR); } + @Override + public MyLambdaQueryWrapper apply(boolean condition, String applySql, Object... value) { + return doIt(condition, APPLY, () -> formatSql(applySql, value)); + } + + @Override + public MyLambdaQueryWrapper last(boolean condition, String lastSql) { + if (condition) { + this.lastSql.setStringValue(StringPool.SPACE + lastSql); + } + return typedThis; + } + + @Override + public MyLambdaQueryWrapper comment(boolean condition, String comment) { + if (condition) { + this.sqlComment.setStringValue(comment); + } + return typedThis; + } + + @Override + public MyLambdaQueryWrapper first(boolean condition, String firstSql) { + if (condition) { + this.sqlFirst.setStringValue(firstSql); + } + return typedThis; + } + + @Override + public MyLambdaQueryWrapper exists(boolean condition, String existsSql) { + return doIt(condition, EXISTS, () -> String.format("(%s)", existsSql)); + } + + @Override + public MyLambdaQueryWrapper notExists(boolean condition, String existsSql) { + return not(condition).exists(condition, existsSql); + } + private MyLambdaQueryWrapper not(boolean condition) { return doIt(condition, NOT); } @@ -455,11 +418,11 @@ public class MyLambdaQueryWrapper extends MyJoinLambdaQueryWrapper return this; } - private MyLambdaQueryWrapper likeValue(boolean condition, SqlKeyword keyword, String column, Object val, SqlLike sqlLike) { + private MyLambdaQueryWrapper likeValue(boolean condition, SqlKeyword keyword, String column, Object val, SqlLike sqlLike) { return doIt(condition, () -> column, keyword, () -> formatSql("{0}", SqlUtils.concatLike(val, sqlLike))); } - protected MyLambdaQueryWrapper addCondition(boolean condition, String column, SqlKeyword sqlKeyword, Object val) { + protected MyLambdaQueryWrapper addCondition(boolean condition, String column, SqlKeyword sqlKeyword, Object val) { return doIt(condition, () -> column, sqlKeyword, () -> formatSql("{0}", val)); } @@ -529,12 +492,12 @@ public class MyLambdaQueryWrapper extends MyJoinLambdaQueryWrapper } @Override - public MyLambdaQueryWrapper having(boolean condition, String alias, String sqlHaving, Object... params) { + public MyLambdaQueryWrapper having(boolean condition, String alias, String sqlHaving, Object... params) { return doIt(condition, HAVING, () -> formatSqlIfNeed(condition, sqlHaving, params)); } @Override - public MyLambdaQueryWrapper func(boolean condition, String alias, Consumer> consumer) { + public MyLambdaQueryWrapper func(boolean condition, String alias, Consumer> consumer) { if (condition) { consumer.accept(this); } diff --git a/src/main/java/com/github/mybatisplus/wrapper/interfaces/MyFunc.java b/src/main/java/com/github/mybatisplus/wrapper/interfaces/MyFunc.java index b87526b..eed187c 100644 --- a/src/main/java/com/github/mybatisplus/wrapper/interfaces/MyFunc.java +++ b/src/main/java/com/github/mybatisplus/wrapper/interfaces/MyFunc.java @@ -183,31 +183,31 @@ public interface MyFunc extends Serializable { Children orderBy(boolean condition, String alias, boolean isAsc, MySFunction... columns); - default Children having(String sqlHaving, Object... params) { + default Children having(String sqlHaving, Object... params) { return having(true, null, sqlHaving, params); } - default Children having(boolean condition, String sqlHaving, Object... params) { + default Children having(boolean condition, String sqlHaving, Object... params) { return having(condition, null, sqlHaving, params); } - default Children having(String alias, String sqlHaving, Object... params) { + default Children having(String alias, String sqlHaving, Object... params) { return having(true, alias, sqlHaving, params); } - Children having(boolean condition, String alias, String sqlHaving, Object... params); + Children having(boolean condition, String alias, String sqlHaving, Object... params); - default Children func(Consumer consumer) { + default Children func(Consumer consumer) { return func(true, null, consumer); } - default Children func(boolean condition, Consumer consumer) { + default Children func(boolean condition, Consumer consumer) { return func(condition, null, consumer); } - default Children func(String alias, Consumer consumer) { + default Children func(String alias, Consumer consumer) { return func(true, alias, consumer); } - Children func(boolean condition, String alias, Consumer consumer); + Children func(boolean condition, String alias, Consumer consumer); } diff --git a/src/main/java/com/github/mybatisplus/wrapper/interfaces/MyJoin.java b/src/main/java/com/github/mybatisplus/wrapper/interfaces/MyJoin.java index be9b730..1e94fb3 100644 --- a/src/main/java/com/github/mybatisplus/wrapper/interfaces/MyJoin.java +++ b/src/main/java/com/github/mybatisplus/wrapper/interfaces/MyJoin.java @@ -1,6 +1,7 @@ package com.github.mybatisplus.wrapper.interfaces; import com.github.mybatisplus.func.MySFunction; +import com.github.mybatisplus.toolkit.Constant; import com.github.mybatisplus.wrapper.MyJoinLambdaQueryWrapper; import java.util.function.Function; @@ -11,11 +12,13 @@ import java.util.function.Function; public interface MyJoin { - Children leftJoin(boolean condition, - String alias, - MySFunction leftCondition, - MySFunction rightCondition, - Function, MyJoinLambdaQueryWrapper> rightWrapper); + default Children leftJoin(boolean condition, + String alias, + MySFunction leftCondition, + MySFunction rightCondition, + Function, MyJoinLambdaQueryWrapper> rightWrapper) { + return join(condition, alias, Constant.LEFT_JOIN, leftCondition, rightCondition, rightWrapper); + } default Children leftJoin(MySFunction leftCondition, @@ -24,7 +27,10 @@ public interface MyJoin { return leftJoin(true, null, leftCondition, rightCondition, rightWrapper); } - default Children leftJoin(String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { + default Children leftJoin(String alias, + MySFunction leftCondition, + MySFunction rightCondition, + Function, MyJoinLambdaQueryWrapper> rightWrapper) { return leftJoin(true, alias, leftCondition, rightCondition, rightWrapper); } @@ -36,11 +42,13 @@ public interface MyJoin { } - Children rightJoin(boolean condition, - String alias, - MySFunction leftCondition, - MySFunction rightCondition, - Function, MyJoinLambdaQueryWrapper> rightWrapper); + default Children rightJoin(boolean condition, + String alias, + MySFunction leftCondition, + MySFunction rightCondition, + Function, MyJoinLambdaQueryWrapper> rightWrapper) { + return join(condition, alias, Constant.RIGHT_JOIN, leftCondition, rightCondition, rightWrapper); + } default Children rightJoin(MySFunction leftCondition, @@ -49,7 +57,10 @@ public interface MyJoin { return rightJoin(true, null, leftCondition, rightCondition, rightWrapper); } - default Children rightJoin(String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { + default Children rightJoin(String alias, + MySFunction leftCondition, + MySFunction rightCondition, + Function, MyJoinLambdaQueryWrapper> rightWrapper) { return rightJoin(true, alias, leftCondition, rightCondition, rightWrapper); } @@ -61,11 +72,13 @@ public interface MyJoin { } - Children innerJoin(boolean condition, - String alias, - MySFunction leftCondition, - MySFunction rightCondition, - Function, MyJoinLambdaQueryWrapper> rightWrapper); + default Children innerJoin(boolean condition, + String alias, + MySFunction leftCondition, + MySFunction rightCondition, + Function, MyJoinLambdaQueryWrapper> rightWrapper) { + return join(condition, alias, Constant.INNER_JOIN, leftCondition, rightCondition, rightWrapper); + } default Children innerJoin(MySFunction leftCondition, @@ -74,7 +87,10 @@ public interface MyJoin { return innerJoin(true, null, leftCondition, rightCondition, rightWrapper); } - default Children innerJoin(String alias, MySFunction leftCondition, MySFunction rightCondition, Function, MyJoinLambdaQueryWrapper> rightWrapper) { + default Children innerJoin(String alias, + MySFunction leftCondition, + MySFunction rightCondition, + Function, MyJoinLambdaQueryWrapper> rightWrapper) { return innerJoin(true, alias, leftCondition, rightCondition, rightWrapper); } @@ -86,4 +102,10 @@ public interface MyJoin { } + Children join(boolean condition, + String alias, + String keyWord, + MySFunction leftCondition, + MySFunction rightCondition, + Function, MyJoinLambdaQueryWrapper> rightWrapper); }