Bean Searcher v3.8.0 A wave of new features is coming

Previous: What is the difference between the recently popular Bean Searcher and MyBatis Plus?

introduce

Bean Searcher is a read-only ORM that focuses on advanced queries. It naturally supports joint tables and avoids DTO/VO conversion, making it possible to realize complex list retrieval with one line of code!

We can use it like a basic component ORM , and at the same time have a development efficiency close to low-code.

scenes to be used

Bean Searcher addresses complex non-transactional retrieval requirements such as:

  • Normal backend query

image.png

  • Dynamic search method

image.png

  • Dynamic group query

image.png

In the above scenarios, Bean Searcher can implement back-end code with one line of code.

Design thinking (starting point)

bs.zhxu.cn/guide/lates…

The reason why development efficiency can be greatly improved

bs.zhxu.cn/guide/lates…

Frame performance

Performance is not the main selling point, but it is also an average of 2 to 5 times better than traditional ORM frameworks (Java layer performance)

Details: gitee.com/troyzhxu/be…

code repository

Documentation and Blog

Changes in the new version v3.8.0

1. Improve database compatibility

Added parameter converter mechanism to make Oracle, PgSql and other databases as smooth as MySQL.

Reference: gitee.com/troyzhxu/be…

2. The parameter builder supports custom SQL conditions

自定义 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、其它变更

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

future features

If you feel good, click Star:

Please continue to pay attention, thank you for supporting Bean Searcher along the way, we will strive to do better.

Previous: What is the difference between the recently popular Bean Searcher and MyBatis Plus?

Guess you like

Origin juejin.im/post/7116736773065343012