https://mp.weixin.qq.com/s/d5190iFM3TJnBGT_nhtZSA
Stream-Query诞生背景
自从用了Mybatis-Plus后,谓爱不释手,捧读其源码,贡献其代码…慢慢地,我不仅是Hutool的Committer,也成为了Mybatis-Plus的Committer
于是我产生了一个思考,能不能让Hutool的静态工具类概念,用在Mybatis-Plus中呢?
这样我就可以不需要每张表都使用代码生成器去生成继承了ServiceImpl的Service
而是针对某一域的业务去新建Service,避免很多可以省略掉的Service类(比如除了主键外只包含user_id、role_id这两个字段的关联表)
然后我就编写了Db类,放到了Mybatis-Plus的3.5.3版本中:
List<UserInfo> users = Db.list(UserInfo.class);
但我还不满足,此时我仍然需要编写一个UserRoleMapper,用于Mybatis-Plus去动态代理
那么我就又研究了下源码,发现了一种实现动态Mapper的方法,那就是使用Byte-Buddy,让其在JVM运行时动态生成Mapper,然后再交给Mybatis-Plus去代理…
最终,我实现了这一功能:
安装——引入依赖:
<dependency>
<groupId>org.dromara</groupId>
<artifactId>stream-plugin-mybatis-plus</artifactId>
<version>1.4.4</version>
</dependency>
在启动类加上注解态@EnableMybatisPlusPlugin
的
接下来只需要配置需要生成动态Mapper的实体类
@Bean
public DynamicMapperHandler dynamicMapperHandler(SqlSessionFactory sqlSessionFactory) throws Exception {
// 扫描po包下的所有类,作为entity
String entityPackagePath = "org.dromara.streamquery.stream.plugin.mybatisplus.pojo.po";
// 这里传入的 entityClassList 即是数据库对应实体类的集合,你可以使用任何你能想到的方式传入,例如Lists.of(UserInfo.class)或者将包路径改为配置文件
final List<Class<?>> entityClassList = ClassHelper.scanClasses(entityPackagePath);
return new DynamicMapperHandler(sqlSessionFactory, entityClassList);
}
然后就可以使用啦:
// 查询集合
List<UserInfo> list = Database.list(Wrappers.lambdaQuery(UserInfo.class));
// 批量更新
boolean isSuccess = Database.updateBatchById(list);
如果已有对应实体类的Mapper类,则使用Database进行数据库操作时,获取到的Mapper会是自己定义的Mapper
对于一些连表查询,还提供了针对列表查询后使用Stream进行内存中数据处理的封装:
// 返回map key为id,value为entity对象,如果in函数中的userIds为空,则不会进行查询
Map<Long, UserInfo> idUserMap = OneToOne.of(UserInfo::getId).in(userIds).query();
// 返回map key为id,value为查询到entity的name,且只会查询id和name字段
Map<Long, String> userIdNameMap = OneToOne.of(UserInfo::getId).in(userIds)
.value(UserInfo::getName).query();
// 返回key为id,value为判断条件(userInfo的name是否不为null,并且包含a字符串)的map
// eq/in函数如果省略的话,则查询全表并按key转换为map,可以通过下面的condition函数限制查询条件
Map<Long, String> userIdHasANameMap = OneToOne.of(UserInfo::getId)
.condition(w -> w.select(UserInfo::getId, UserInfo::getName))
.value(userInfo -> userInfo.getName() != null &&
userInfo.getName().contains("a"))
.query();
除了OneToOne,Stream-Query还提供了OneToMany
// 返回map key为age,value中list的包装对象为entity对象(在进行peek等操作,且大数据量情况下的时候可以考虑并行)
Map<Integer, List<UserInfo>> ageUsersMap = OneToMany.of(UserInfo::getAge)
.in(userAges).peek(user -> userIds.add(user.getId())).parallel().query();
还有诸多特性,可以去官方文档查阅:
官方文档:https://stream-query.dromara.org/
官方文档(国内访问快):https://dromara.gitee.io/stream-query/
最后编辑:Jeebiz 更新时间:2024-10-05 00:01