目录
一、 前言
Bean Searcher 号称任何复杂的查询都可以一行代码搞定,但 Mybatis Plus 似乎也有类似的动态查询功能,那个更快,更好呢?下面我们就来讲解一下
二、 两者的区别
1、区别一(基本)
Mybatis Plus 依赖 MyBatis, 功能 CRUD 都有,而 Bean Seracher 不依赖任何 ORM,只专注高级查询。
只有使用 MyBatis 的项目才会用 Mybatis Plus,而使用 Hibernate,Data Jdbc 等其它 ORM 的人则无法使用 Mybatis Plus。但是这些项目都可以使用 Bean Searcher(可与任何 ORM 配合使用,也可单独使用)。
使用 Mybatis Plus 需要编写实体类 和 Mapper 接口,而 Bean Searcher 只需编写 实体类,无需编写任何接口。这个区别意义其实不大。
因为如果你用 Mybatis Plus,在增删改的时候还是需要定义 Mapper 接口
2、区别二(查询)
Mybatis Plus 的字段运算符是静态的,而 Bean Searcher 的是动态的。字段运算符指的是某字段参与条件时用的是 =、> 亦或是 like 这些条件类型。
不只 Mybatis Plus,一般的传统 ORM 的字段运算符都是静态的,包括 Hibernate、Spring data jdbc、JOOQ 等。
三、 BeanSearcher的特点
官网地址:点击跳转到官网
比 MyBatis 效率快 100 倍的条件检索引擎,天生支持联表,使一行代码实现复杂列表检索成为可能!
界面演示:
效率极大提高的原因:
在 Search Bean 出现之前,前端传来的检索条件都是需要业务代码处理的(因为普通的 VO 无法与数据库直接映射),而 Search Bean 出现之后,检索条件可以用 Search Bean 里的字段和参数直接表达,并且直接映射成数据库的查询语句。
所以,后端检索接口里的代码只需要收集页面的检索参数即可,就像文档首页所展示的代码一样,并不需要做太多的处理,并且 Bean Searcher 返回的 SearchBean 就是前端需要的 VO 对象,也不需要再做转换。而这,就是 Bean Searcher 之所以能 使一行代码实现复杂列表检索成为可能 的原因。
与 Hibernate MyBatis 的区别:
首先,Bean Searcher 并不是一个完全的 ORM 框架,它存在的目的不是为了替换他们,而是为了弥补他们在 列表检索领域 的不足。
从上表可以看出,Bean Searcher 只能做数据库查询,不支持 增删改。但它的 多表映射机制 与 动态字段运算符,可以让我们在做复杂列表检索时代码 以一当十,甚至 以一当百。
更关键的是,它无第三方依赖,在项目中可以和 任意 ORM 配合 使用。
四、 BeanSearcher的Demo演示案例
(1)、 Bean Searcher 的可配置项都是默认值。
public class User { // 对应数据库中的 user 表
private Long id; // ID
private String name; // 姓名
private int age; // 年龄
private int point; // 积分
// Getter and Setter ...
}
(2)、分页查询
不带参数时,默认查询 15 条数据(因为 默认分页大小为 15 ,可配置):
// 执行一条 SQL,默认查询 15 条数据
List<User> users = searcher.searchList(User.class, null);
查询第 2 页,每页 20 条(page 和 size 的参数名可配置):
Map<String, Object> params = MapUtils.builder()
.page(1, 20)
.build();
// 执行 1 条 SQL
List<User> users = searcher.searchList(User.class, params);
分页检索时,返回分页信息
// 执行 2 条 SQL
SearchResult<User> result = searcher.search(User.class, params);
// 用户列表
List<User> users = result.getDataList();
// 数据总条数
Number totalCount = result.getTotalCount();
(3)、全量查询
Sercher 实例的 searchAll 方法可检索满足条件的所有数据:
Map<String, Object> params = MapUtils.builder()
// 构造条件...
.build();
// 向 params 添加检索条件, 比如按某个字段检索..
// 执行 1 条 SQL,不分页
List<User> result = searcher.searchAll(User.class, params);
(4)、对象查询
Sercher 实例的 searchFirst 方法可检索满足条件的第一个数据:
Map<String, Object> params = MapUtils.builder()
// 构造条件...
.build();
// 向 params 添加检索条件, 比如按某个字段检索..
// 执行 1 条 SQL,limit 1
User user = searcher.searchFirst(User.class, params);
(5)、统计查询
单字段统计:
Map<String, Object> params = MapUtils.builder()
// 构造条件...
.build();
// 执行 1 条 SQL,返回满足条件的用户的总年龄
Number totalAge = searcher.searchSum(User.class, params, "age");
多字段统计:
Map<String, Object> params = MapUtils.builder()
// 构造条件...
.build();
// 执行 1 条 SQL
Number[] summaries = searcher.searchSum(User.class, params, new String[] { "age", "point" });
Number totalAge = summaries[0]; // 满足条件的用户总年龄
Number totalPoint = summaries[1];
分页列表检索时顺带统计:
Map<String, Object> params = MapUtils.builder()
// 构造条件...
.build();
// 执行 2 条 SQL
SearchResult<User> result = searcher.search(User.class, params, new String[] { "age" });
List<User> users = result.getDataList(); // 用户列表
Number[] summaries = result.getSummaries(); // 统计信息
(6)、检索方式
不同的检索方式,只是调用 Sercher 实例的检索方法时传递的第二个 Map<String, Object> 类型的参数不同而已,所以为了简化文档,下文示例代码中只列出检索参数的组装过程,不再赘述 Sercher 实例的方法的调用。
精确查询
以例说明,查询 age 等于 18 的用户:
Map<String, Object> params = MapUtils.builder()
.field(User::getAge, 18).op(Equal.class)
.build();
// ...
范围查询
以例说明,查询 age 大于 18 的用户:
Map<String, Object> params = MapUtils.builder()
.field(User::getAge, 18).op(GreaterThan.class) // age > 18
.field(User::getAge, 18).op(GreaterEqual.class) // age >= 18
.field(User::getAge, 18).op(LessThan.class) // age < 18
.field(User::getAge, 18).op(LessEqual.class) // age <= 18
.field(User::getAge, 18).op(NotEqual.class) // age != 18
.field(User::getAge, 10, 20).op(Between.class) // 10 <= age <= 20
.build();
// ...
模糊查询
以例说明,查询 name 包含字符串 ‘A’ 的用户:
Map<String, Object> params = MapUtils.builder()
.field(User::getName, "A").op(Contain.class) // 包含 A
.field(User::getName, "A").op(StartWith.class) // 以 A 开头
.field(User::getName, "A").op(EndWith.class) // 以 A 结尾
.field(User::getName, "A%", "%B", "%C%").op(OrLike.class) // 以 A 开头 或 以 B 结尾 或 包含 C
.build();
多值查询
以例说明,查询 id 等于 1 和 2 和 3 的用户:
Map<String, Object> params = MapUtils.builder()
.field(User::getId, 1, 2, 3).op(InList.class)
.build();
// ...
非空查询
以例说明,查询 name 不为空的用户:
Map<String, Object> params = MapUtils.builder()
.field(User::getName).op(NotEmpty.class)
.build();
// ...
其他的就不举例了,官方文档都讲解的有,很详细!
总结
Bean Searcher 是使用Apache开源的框架,非常好用,希望能够帮助到大家,感谢点赞支持一下!!