mybatis-plus
mybatis-plus copied to clipboard
[功能改进]: 4.0 希望支持功能建议收集
单纯的收集建议,不一定采纳!!
- 支持物理删除
lambdaUpdate().eq(Test::getId, "1").remove().force(); - 支持忽略逻辑删除查询
lambdaQuery().eq(Test::getId, "1").list().ignoreLogicalDel(); - 支持忽略逻辑删除更新
lambdaUpdate().set(Test::getType, "2").eq(Test::getId, "1").update().ignoreLogicalDel(); - 增加
sum、count等简单的聚合函数 - IService 接口支持下查询结果转换功能。以下接口是举例,最终想法就是Entity查出10条,VO只需要5条,直接用Mapstruct映射下,调用
getById("id", EntityConvertMapper:toVO);即可。/** * 根据id查询 * * @param id 主键 * @param convert 转换 * @return {@link R } */ public <R> R getById(Serializable id, Function<T, R> convert); /** * 根据 Wrapper,查询一条记录 <br/> * <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p> * * @param queryWrapper 查询包装器 * @param convert 转换 * @return {@link R } */ public <R> R getOne(Wrapper<T> queryWrapper, Function<T, R> convert); /** * 列表 * * @param wrapper 包装器 * @param convert 转换 * @return {@link List }<{@link R }> */ public <R> List<R> list(Wrapper<T> wrapper, Function<T, R> convert); /** * 查询(根据ID 批量查询) * * @param idList 主键ID列表 * @param convert 转换 * @return {@link List }<{@link R }> */ public <R> List<R> listByIds(Collection<? extends Serializable> idList, Function<T, R> convert); /** * 分页查询(循环转) * * @param page 翻页对象 * @param queryWrapper 实体对象封装操作类 * @param convert 转换 * @return {@link IPage }<{@link R }> */ public <R> IPage<R> page(IPage<T> page, Wrapper<T> queryWrapper, Function<T, R> convert); /** * page查询结果转IPage<Map<String, Object>> * * @param page page对象 * @param convertFields 转换字段 * @return {@link IPage }<{@link Map }<{@link String }, {@link Object }>> */ public IPage<Map<String, Object>> pageResult2Map(IPage<?> page, String... convertFields); - Mapper.xml、@TableName、@TableField 支持下开发中能够热加载。(一改动,使用jrebel热部署都没用,xml至少还能用
JRebel mybatisPlus extension插件能热部署,实体类完全没用,求求你改改吧,加个字段还要重启项目很累啊!!!)/** * 实体类反射获取表信息【初始化】 */ public synchronized static TableInfo initTableInfo(MapperBuilderAssistant builderAssistant, Class<?> clazz) { TableInfo targetTableInfo = TABLE_INFO_CACHE.get(clazz); final Configuration configuration = builderAssistant.getConfiguration(); if (targetTableInfo != null) { Configuration oldConfiguration = targetTableInfo.getConfiguration(); if (!oldConfiguration.equals(configuration)) { // 不是同一个 Configuration,进行重新初始化 targetTableInfo = initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz); } return targetTableInfo; } return initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz); }
求求你sum之类的简单语法也加上吧
1.queryWrapperLambda和queryWrapper互转,或者queryWrapperLambda支持写sql 2.增加 sum 、count 等复杂的聚合函数
希望引入PageHelper 相似的分页处理方式,要分页的时候在查询之前定义分页条件,不需要分页的时候就不需要定义分页调整, 而不是需要将分页Page对象一层层传递下去Service,Mapper
PageHelper.startPage(query.getPage(), query.getPageSize());
//list 其实是可以共用的,前面定义了分页查询条件,返回的是分页结构的数据;没定义分页条件时,返回的是符合条件的集合
List<OlesDeviceDTO> list = xxxService.list(query);
updateById 这个函数在执行 sql 前检查是否除ID外所有字段都为 null,如果为 null 那么不执行 sql。
因为有时候一张表好几十个字段,如果在执行之前手动检查,代码会很丑陋。
希望增加“通用”的sql函数、聚合、转换 相关功能等
1.queryWrapperLambda和queryWrapper互转,或者queryWrapperLambda支持写sql 2.增加 sum 、count 等复杂的聚合函数
现在就可以用 new queryWrapper().select(" SUM(xxx) AS xxx").lambda().eq()
求求你sum之类的简单语法也加上吧
现在就可以用 new queryWrapper().select(" SUM(xxx) AS xxx").lambda().eq()
建议,能向下兼容3.X。
例如 TableName TableId以及 TableField 可以兼容java的persistence Api 的注解
希望增加日志打印SQL的功能,只打印SQL,而不打印返回的数据。 并且现在日志里的SQL,并不能直接运行,希望可以打印成可以执行的SQL
增加注解式定义查询字段(复合查询场景下,有大量重复代码用于判空、条件拼接) 现状: if(a != null) then wrapper.eq(xxx,a), if(b !=null) then wrapper.in(xxx, b), if( c != null) then wrapper.like(xxx,c)
期待: @QueryCondition(type=EQ, columnName = "xxx") private String a; @QueryCondition(type=IN, columnName = "xxx") private List<String> b; @QueryCondition(type=LIKE, columnName = "xxx") private String c;
增加注解式定义查询字段(复合查询场景下,有大量重复代码用于判空、条件拼接) 现状: if(a != null) then wrapper.eq(xxx,a), if(b !=null) then wrapper.in(xxx, b), if( c != null) then wrapper.like(xxx,c)
期待: @QueryCondition(type=EQ, columnName = "xxx") private String a; @QueryCondition(type=IN, columnName = "xxx") private List b; @QueryCondition(type=LIKE, columnName = "xxx") private String c;
上古就支持条件判断了,你还用 if ?
希望增加日志打印SQL的功能,只打印SQL,而不打印返回的数据。 并且现在日志里的SQL,并不能直接运行,希望可以打印成可以执行的SQL
一看就是没好好看文档的。
ps6y解决方案:https://baomidou.com/guides/p6spy/ druid连接池解决方案:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_LogFilter
希望引入PageHelper 相似的分页处理方式,要分页的时候在查询之前定义分页条件,不需要分页的时候就不需要定义分页调整, 而不是需要将分页Page对象一层层传递下去Service,Mapper
PageHelper.startPage(query.getPage(), query.getPageSize()); //list 其实是可以共用的,前面定义了分页查询条件,返回的是分页结构的数据;没定义分页条件时,返回的是符合条件的集合 List<OlesDeviceDTO> list = xxxService.list(query);
这种做法早期支持过,存在安全隐患移除了,当使 startPage 和 List 中间调用了其它 list 会导致本应该分页的语句变成全表扫描,这种做法是极为不安全的,因此不会支持该能力。
感谢,文档上只有ps6y ,还需要改配置,实在麻烦,Mybatisflex那个原生的就很不错。 druid的方案倒是可以
---- 回复的原邮件 ---- | 发件人 | @.> | | 日期 | 2024年08月17日 14:55 | | 收件人 | @.> | | 抄送至 | @.>@.> | | 主题 | Re: [baomidou/mybatis-plus] [功能改进]: 4.0 希望支持功能建议收集 (Issue #6374) |
希望增加日志打印SQL的功能,只打印SQL,而不打印返回的数据。 并且现在日志里的SQL,并不能直接运行,希望可以打印成可以执行的SQL
一看就是没好好看文档的。
ps6y解决方案:https://baomidou.com/guides/p6spy/ druid连接池解决方案:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_LogFilter
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
增加注解式定义查询字段(复合查询场景下,有大量重复代码用于判空、条件拼接) 现状: if(a != null) then wrapper.eq(xxx,a), if(b !=null) then wrapper.in(xxx, b), if( c != null) then wrapper.like(xxx,c) 期待: @QueryCondition(type=EQ, columnName = "xxx") private String a; @QueryCondition(type=IN, columnName = "xxx") private List b; @QueryCondition(type=LIKE, columnName = "xxx") private String c;
上古就支持条件判断了,你还用 if ?
您好!您的给的这个不就是个等值条件的method吗?我的意思是:复合条件查询下(QueryDTO查询参数非常多),不用每次都自己去判空,然后手动的写一大堆wrapper.eq, wrapper.in等等,而是通过注解查询字段的方式来解决这个问题
增加注解式定义查询字段(复合查询场景下,有大量重复代码用于判空、条件拼接) 现状: if(a != null) then wrapper.eq(xxx,a), if(b !=null) then wrapper.in(xxx, b), if( c != null) then wrapper.like(xxx,c) 期待: @QueryCondition(type=EQ, columnName = "xxx") private String a; @QueryCondition(type=IN, columnName = "xxx") private List b; @QueryCondition(type=LIKE, columnName = "xxx") private String c;
上古就支持条件判断了,你还用 if ?
您好!您的给的这个不就是个等值条件的method吗?我的意思是:复合条件查询下(QueryDTO查询参数非常多),不用每次都自己去判空,然后手动的写一大堆wrapper.eq, wrapper.in等等,而是通过注解查询字段的方式来解决这个问题
你没考虑过多个业务都要用的场景吗?按你这样说,A业务要这个查询条件,B业务不要,这还只是2个业务的场景,我10个业务用到这个实体类,你还要用注解还要加一堆分组去判断?
你没考虑过多个业务都要用的场景吗?按你这样说,A业务要这个查询条件,B业务不要,这还只是2个业务的场景,我10个业务用到这个实体类,你还要用注解还要加一堆分组去判断?
你这么说就真的没理解我说的话,B业务不要,他不传这个参数不就行了 ?注解式默认过滤为空的条件。或者你说没做业务隔离控制,那写个策略枚举类,路由下不同业务下的不同查询权限就解决了?
希望增加日志打印SQL的功能,只打印SQL,而不打印返回的数据。 并且现在日志里的SQL,并不能直接运行,希望可以打印成可以执行的SQL
一看就是没好好看文档的。
ps6y解决方案:https://baomidou.com/guides/p6spy/ druid连接池解决方案:https://github.com/alibaba/druid/wiki/%E9%85%8D%E7%BD%AE_LogFilter
如果把mapper层的日志调成debug 不就输出sql了么
你没考虑过多个业务都要用的场景吗?按你这样说,A业务要这个查询条件,B业务不要,这还只是2个业务的场景,我10个业务用到这个实体类,你还要用注解还要加一堆分组去判断?
你这么说就真的没理解我说的话,B业务不要,他不传这个参数不就行了 ?注解式默认过滤为空的条件。或者你说没做业务隔离控制,那写个策略枚举类,路由下不同业务下的不同查询权限就解决了?
这个东西太重了 类上加查询条件注解的话 不太适用于所有场景吧 也违背了ibatis的半自动框架的初衷吧 这样搞直接用jpa了
你没考虑过多个业务都要用的场景吗?按你这样说,A业务要这个查询条件,B业务不要,这还只是2个业务的场景,我10个业务用到这个实体类,你还要用注解还要加一堆分组去判断?
你这么说就真的没理解我说的话,B业务不要,他不传这个参数不就行了 ?注解式默认过滤为空的条件。或者你说没做业务隔离控制,那写个策略枚举类,路由下不同业务下的不同查询权限就解决了?
这个东西太重了 类上加查询条件注解的话 不太适用于所有场景吧 也违背了ibatis的半自动框架的初衷吧 这样搞直接用jpa了
不太认同,个人认为框架不应该被定义。如果强行给ibatis定义为半自动化框架,而放弃一些可以简化业务逻辑的API,这不是有背于框架本身的意思吗(框架就是简化开发)。你想想mybatis-plus的意义是啥,不就是为了简化mybatis繁琐的CURD吗?而且个人认为给字段增加注解,不会是一个重操作,范围简化了代码量,service层可以更加专注于业务代码的编写。
你没考虑过多个业务都要用的场景吗?按你这样说,A业务要这个查询条件,B业务不要,这还只是2个业务的场景,我10个业务用到这个实体类,你还要用注解还要加一堆分组去判断?
你这么说就真的没理解我说的话,B业务不要,他不传这个参数不就行了 ?注解式默认过滤为空的条件。或者你说没做业务隔离控制,那写个策略枚举类,路由下不同业务下的不同查询权限就解决了?
这个东西太重了 类上加查询条件注解的话 不太适用于所有场景吧 也违背了ibatis的半自动框架的初衷吧 这样搞直接用jpa了
不太认同,个人认为框架不应该被定义。如果强行给ibatis定义为半自动化框架,而放弃一些可以简化业务逻辑的API,这不是有背于框架本身的意思吗(框架就是简化开发)。你想想mybatis-plus的意义是啥,不就是为了简化mybatis繁琐的CURD吗?而且个人认为给字段增加注解,不会是一个重操作,范围简化了代码量,service层可以更加专注于业务代码的编写。
不明白在类上加条件注解的场景究竟有多少?一个po实例对应数据库的一条记录,如何被过滤筛选根据不同的业务场景,不同的接口方法调用,不同的传参都有不同的过滤逻辑加入进来,除了 等于 不等于 还有 is null is not null 或者 exist not exist having等各种各样的函数表达方式, 框架会变得特别笨重。
你没考虑过多个业务都要用的场景吗?按你这样说,A业务要这个查询条件,B业务不要,这还只是2个业务的场景,我10个业务用到这个实体类,你还要用注解还要加一堆分组去判断?
你这么说就真的没理解我说的话,B业务不要,他不传这个参数不就行了 ?注解式默认过滤为空的条件。或者你说没做业务隔离控制,那写个策略枚举类,路由下不同业务下的不同查询权限就解决了?
这个东西太重了 类上加查询条件注解的话 不太适用于所有场景吧 也违背了ibatis的半自动框架的初衷吧 这样搞直接用jpa了
不太认同,个人认为框架不应该被定义。如果强行给ibatis定义为半自动化框架,而放弃一些可以简化业务逻辑的API,这不是有背于框架本身的意思吗(框架就是简化开发)。你想想mybatis-plus的意义是啥,不就是为了简化mybatis繁琐的CURD吗?而且个人认为给字段增加注解,不会是一个重操作,范围简化了代码量,service层可以更加专注于业务代码的编写。
不明白在类上加条件注解的场景究竟有多少?一个po实例对应数据库的一条记录,如何被过滤筛选根据不同的业务场景,不同的接口方法调用,不同的传参都有不同的过滤逻辑加入进来,除了 等于 不等于 还有 is null is not null 或者 exist not exist having等各种各样的函数表达方式, 框架会变得特别笨重。
不太好说明白,还是得给你把代码给写出来。等我有时间吧,talk is cheap, show you code!
- 支持物理删除
lambdaUpdate().eq(Test::getId, "1").remove().force();- 支持忽略逻辑删除查询
lambdaQuery().eq(Test::getId, "1").list().ignoreLogicalDel();- 支持忽略逻辑删除更新
lambdaUpdate().set(Test::getType, "2").eq(Test::getId, "1").update().ignoreLogicalDel();- 增加
sum、count等简单的聚合函数- IService 接口支持下查询结果转换功能。以下接口是举例,最终想法就是Entity查出10条,VO只需要5条,直接用Mapstruct映射下,调用
getById("id", EntityConvertMapper:toVO);即可。/** * 根据id查询 * * @param id 主键 * @param convert 转换 * @return {@link R } */ public <R> R getById(Serializable id, Function<T, R> convert); /** * 根据 Wrapper,查询一条记录 <br/> * <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p> * * @param queryWrapper 查询包装器 * @param convert 转换 * @return {@link R } */ public <R> R getOne(Wrapper<T> queryWrapper, Function<T, R> convert); /** * 列表 * * @param wrapper 包装器 * @param convert 转换 * @return {@link List }<{@link R }> */ public <R> List<R> list(Wrapper<T> wrapper, Function<T, R> convert); /** * 查询(根据ID 批量查询) * * @param idList 主键ID列表 * @param convert 转换 * @return {@link List }<{@link R }> */ public <R> List<R> listByIds(Collection<? extends Serializable> idList, Function<T, R> convert); /** * 分页查询(循环转) * * @param page 翻页对象 * @param queryWrapper 实体对象封装操作类 * @param convert 转换 * @return {@link IPage }<{@link R }> */ public <R> IPage<R> page(IPage<T> page, Wrapper<T> queryWrapper, Function<T, R> convert); /** * page查询结果转IPage<Map<String, Object>> * * @param page page对象 * @param convertFields 转换字段 * @return {@link IPage }<{@link Map }<{@link String }, {@link Object }>> */ public IPage<Map<String, Object>> pageResult2Map(IPage<?> page, String... convertFields);- Mapper.xml、@TableName、@TableField 支持下开发中能够热加载。(一改动,使用jrebel热部署都没用,xml至少还能用
JRebel mybatisPlus extension插件能热部署,实体类完全没用,求求你改改吧,加个字段还要重启项目很累啊!!!)/** * 实体类反射获取表信息【初始化】 */ public synchronized static TableInfo initTableInfo(MapperBuilderAssistant builderAssistant, Class<?> clazz) { TableInfo targetTableInfo = TABLE_INFO_CACHE.get(clazz); final Configuration configuration = builderAssistant.getConfiguration(); if (targetTableInfo != null) { Configuration oldConfiguration = targetTableInfo.getConfiguration(); if (!oldConfiguration.equals(configuration)) { // 不是同一个 Configuration,进行重新初始化 targetTableInfo = initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz); } return targetTableInfo; } return initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz); }
@nn200433 我搞了个idea插件,可以热加载实体类,目前日常使用没问题,你可以试试,装上后jrebel方式启动项目就行了
- 支持物理删除
lambdaUpdate().eq(Test::getId, "1").remove().force();- 支持忽略逻辑删除查询
lambdaQuery().eq(Test::getId, "1").list().ignoreLogicalDel();- 支持忽略逻辑删除更新
lambdaUpdate().set(Test::getType, "2").eq(Test::getId, "1").update().ignoreLogicalDel();- 增加
sum、count等简单的聚合函数- IService 接口支持下查询结果转换功能。以下接口是举例,最终想法就是Entity查出10条,VO只需要5条,直接用Mapstruct映射下,调用
getById("id", EntityConvertMapper:toVO);即可。/** * 根据id查询 * * @param id 主键 * @param convert 转换 * @return {@link R } */ public <R> R getById(Serializable id, Function<T, R> convert); /** * 根据 Wrapper,查询一条记录 <br/> * <p>结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")</p> * * @param queryWrapper 查询包装器 * @param convert 转换 * @return {@link R } */ public <R> R getOne(Wrapper<T> queryWrapper, Function<T, R> convert); /** * 列表 * * @param wrapper 包装器 * @param convert 转换 * @return {@link List }<{@link R }> */ public <R> List<R> list(Wrapper<T> wrapper, Function<T, R> convert); /** * 查询(根据ID 批量查询) * * @param idList 主键ID列表 * @param convert 转换 * @return {@link List }<{@link R }> */ public <R> List<R> listByIds(Collection<? extends Serializable> idList, Function<T, R> convert); /** * 分页查询(循环转) * * @param page 翻页对象 * @param queryWrapper 实体对象封装操作类 * @param convert 转换 * @return {@link IPage }<{@link R }> */ public <R> IPage<R> page(IPage<T> page, Wrapper<T> queryWrapper, Function<T, R> convert); /** * page查询结果转IPage<Map<String, Object>> * * @param page page对象 * @param convertFields 转换字段 * @return {@link IPage }<{@link Map }<{@link String }, {@link Object }>> */ public IPage<Map<String, Object>> pageResult2Map(IPage<?> page, String... convertFields);- Mapper.xml、@TableName、@TableField 支持下开发中能够热加载。(一改动,使用jrebel热部署都没用,xml至少还能用
JRebel mybatisPlus extension插件能热部署,实体类完全没用,求求你改改吧,加个字段还要重启项目很累啊!!!)/** * 实体类反射获取表信息【初始化】 */ public synchronized static TableInfo initTableInfo(MapperBuilderAssistant builderAssistant, Class<?> clazz) { TableInfo targetTableInfo = TABLE_INFO_CACHE.get(clazz); final Configuration configuration = builderAssistant.getConfiguration(); if (targetTableInfo != null) { Configuration oldConfiguration = targetTableInfo.getConfiguration(); if (!oldConfiguration.equals(configuration)) { // 不是同一个 Configuration,进行重新初始化 targetTableInfo = initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz); } return targetTableInfo; } return initTableInfo(configuration, builderAssistant.getCurrentNamespace(), clazz); }@nn200433 我搞了个idea插件,可以热加载实体类,目前日常使用没问题,你可以试试,装上后jrebel方式启动项目就行了
牛逼,我试试
@TableField @TableId 等框架注解, 应该要可以支持接口的getter setter, 这样可以在MetaObjectHandler, 或者其他地方做一些抽象, 避免 实体之间的继承..
updateById这个函数在执行 sql 前检查是否除ID外所有字段都为 null,如果为 null 那么不执行 sql。 因为有时候一张表好几十个字段,如果在执行之前手动检查,代码会很丑陋。
使用配置更新策略应该可以实现你想要的效果(默认的策略应该就是只有不是Null的才会进行生成set语句) https://baomidou.com/reference/annotation/#updatestrategy https://baomidou.com/reference/#updatestrategy
updateById这个函数在执行 sql 前检查是否除ID外所有字段都为 null,如果为 null 那么不执行 sql。 因为有时候一张表好几十个字段,如果在执行之前手动检查,代码会很丑陋。使用配置更新策略应该可以实现你想要的效果(默认的策略应该就是只有不是Null的才会进行生成set语句) https://baomidou.com/reference/annotation/#updatestrategy https://baomidou.com/reference/#updatestrategy
但是这个适配mapper和service层所有的接口吗 我记得save、saveOrUpdate不适用 因为走的是默认的非空策略
以下是我的建议,希望可以参考:
-
加入绕过逻辑删除的方法
-
加入join联表查询方法
-
mapper层加入service层同样的批量处理方法,如saveBatch等
-
QueryChainWrapper和LambdaQueryChainWrapper的互转,或者LambdaQueryChainWrapper支持QueryChainWrapper类似的手写sql select语句等,譬如要加个distinct 或者sum之类的函数LambdaQueryChainWrapper不支持
