Bean Searcher v3.8.0 一大波新特性来袭

上篇:最近火起的 Bean Searcher 与 MyBatis Plus 倒底有啥区别?

介绍

Bean Searcher 是一款专注高级查询的只读 ORM,天生支持联表,免 DTO/VO 转换,使一行代码实现复杂列表检索成为可能!

我们可以像用 基础组件 ORM 那样使用 它,同时可以拥有 接近低代码 的开发效率。

使用场景

Bean Searcher 专克非事务性的复杂检索需求,例如:

  • 普通后端查询

image.png

  • 动态检索方式

image.png

  • 动态分组查询

image.png

以上场景 Bean Searcher 都可以一行代码实现后端代码。

设计思想(出发点)

bs.zhxu.cn/guide/lates…

开发效率可以极大提升的原因

bs.zhxu.cn/guide/lates…

框架性能

性能不是主要卖点,但也比传统 ORM 框架平均提升 2 ~ 5 倍(Java 层性能)

详情:gitee.com/troyzhxu/be…

代码仓库

文档与博客

新版本 v3.8.0 的变更

1、提升数据库兼容性

新增 参数转换器 机制,使 Oracle、PgSql 等数据库也同 MySQL 般顺滑。

参考:gitee.com/troyzhxu/be…

2、参数构建器支持 自定义 SQL 条件

自定义 SQL 条件,只能在后端通过参数构建器使用,例如

 Map<String, Object> params = MapUtils.builder()
       // 生成 SQL 条件:u.id in (select user_id from xxx)
       .field(User::getId).sql("$1 in (select user_id from xxx)")
       .build();
List<User> users = searcher.searchList(User.class, params);

用 $n 来表示所需引用的第 n 个字段,再如:

 Map<String, Object> params = MapUtils.builder()
       // 生成 SQL 条件:id < 100 or age > 10
       .field(User::getId, User::getAge).sql("$1 < 100 or $2 > 10")
       .build();
List<User> users = searcher.searchList(User.class, params);

也可以在自定义的 SQL 片段中使用参数占位符 ?(作为 JDBC 参数),例如:

Map<String, Object> params = MapUtils.builder()
       // 生成 SQL 条件:id < ? or age > ?,两个占位符参数分别为:100,10
       .field(User::getId, User::getAge).sql("$1 < ? or $2 > ?", 100, 10)
       .build();
List<User> users = searcher.searchList(User.class, params);

3、分组动态查询条件生成机制

  • 分组字段 生成 where 条件,其它字段 生成 having 条件

例如一个指定了 groupBy 的 SearchBean:

@SearchBean(
    tables = "student_course", 
    groupBy = "course_id"            // 按课程 ID 分组
) 
public class CourseScore {

    @DbField("course_id")
    private long courseId;

    @DbField("sum(score)")           // 该课程的总分(聚合函数:sum)
    private long totalScore;

}

当以 courseId 为条件时:

Map<String, Object> params = MapUtils.builder()
       .field(CourseScore::getCourseId, 101).op(LessThan.class)
       .build();
List<CourseScore> list = searcher.searchList(CourseScore.class, params);

执行 SQL(条件在 where 里):

select course_id, sum(score) from student_course where course_id < 101 group by course_id

当以 totalScore 为条件时:

Map<String, Object> params = MapUtils.builder()
       .field(CourseScore::getTotalScore, 500).op(GreateThan.class)
       .build();
List<CourseScore> list = searcher.searchList(CourseScore.class, params);

执行 SQL(条件在 having 里):

select course_id, sum(score) 
from student_course 
group by course_id 
having sum(score) > 500

当然两者还可以组合:

Map<String, Object> params = MapUtils.builder()
       .field(CourseScore::getCourseId, 101).op(LessThan.class)
       .field(CourseScore::getTotalScore, 500).op(GreateThan.class)
       .build();
List<CourseScore> list = searcher.searchList(CourseScore.class, params);

执行 SQL:

select course_id, sum(score) 
from student_course 
where course_id < 101 
group by course_id 
having sum(score) > 500

4、新增 NotLike 运算符

目前内置的运算符已经有 19 个:

运算符 缩写 SQL 片段 是否忽略空值 含义
Equal eq x = ? 等于(是缺省默认的运算符)
NotEqual ne x != ? 不等于
GreaterThan gt x > ? 大于
GreaterEqual ge x >= ? 大于等于
LessThan lt x < ? 小于
LessEqual le x <= ? 小于等于
Between bt x between ?1 and ?2 / x >= ?1 / x <= ?2 在...之间(范围查询)
NotBetween nb x not between ?1 and ?2 / x < ?1 / x > ?2 不在...之间(范围查询)(since v3.3
Contain ct x like '%?%' 包含(模糊查询)(since v3.2
StartWith sw x like '?%' 以...开头(模糊查询)
EndWith ew x like '%?' 以...结尾(模糊查询)
OrLike ol x like ?1 or x like ?2 or ... 模糊或匹配(可有多个参数值)(since v3.7
NotLike nk x not like ? 反模糊匹配(since v3.8
InList il / mv x in (?, ?, ...) 多值查询(InList / il 自 v3.3 新增,之前是 MultiValue / mv
NotIn ni x not in (?, ?, ...) 多值查询(since v3.3
IsNull nl x is null 为空(since v3.3
NotNull nn x is not null 不为空(since v3.3
Empty ey x is null or x = '' 为空(仅适用于 字符串 类型的字段)
NotEmpty ny x is not null and x != '' 不为空(仅适用于 字符串 类型的字段)

5、优化注解省略机制

原本若要在实体类字段上省略 @DbFeild 时,必须满足以下三条件之一:

  • 实体类省略了 @SearchBean 注解
  • 实体类的 @SearchBean 没有指定 tables 属性
  • 实体类的 @SearchBean 指定了 autoMapTo 属性

v3.8.0 之前,tablesautoMapTo 必须 同时出现同时消失 才可以省略 @DbFeild 注解,例如改成这样即可:

@SearchBean(tables="user", autoMapTo="user")
public class UserVO {
    private Long id;    // 省略注解 @DbFeild
    private Long name;  // 省略注解 @DbFeild
}

但是总有小伙伴,不想不想省略 tables,又不想指向 autoMapTo,写成这样:

@SearchBean(tables="user")
public class UserVO {
    private Long id;    // 省略注解 @DbFeild
    private Long name;  // 省略注解 @DbFeild
}

结果让不少人都收到了异常,参考:github.com/ejlchina/be…

为了让大家少踩坑,v3.8.0 让这也兼容了这种的写法。现在要省略 @DbFeild,只需满足以下四个条件之一即可:

  • 实体类省略了 @SearchBean 注解
  • 实体类的 @SearchBean 没有指定 tables 属性
  • 实体类的 @SearchBean.tables 只含一张表(since v3.8.0)
  • 实体类的 @SearchBean 指定了 autoMapTo 属性

6、其它变更

其它变更就不一一列列举了,大家可以在这里查看:

未来特性

如果觉得不错,点个 Star 吧:

请大家继续关注,感谢一路走来支持 Bean Searcher 的你们,我们会努力做到更好。

上篇:最近火起的 Bean Searcher 与 MyBatis Plus 倒底有啥区别?

猜你喜欢

转载自juejin.im/post/7116736773065343012