对一个 Java 后端程序员来说,MyBatis、Hibernate、Data Jdbc 等都是我们常用的 ORM 框架。它们有时候很好用,比如简单的 CRUD,事务的支持都非常棒。但有时候用起来也非常繁琐,比如接下来我们要聊到的一个常见的开发需求,而对这类需求,本文会给出一个比直接使用这些 ORM 开发效率至少会提高 100 倍的方法(绝无夸张)。
首先数据库有两张表
用户表(user):(简单起见,假设只有 4 个字段)
字段名 |
类型 |
含义 |
id |
bitint |
用户 ID |
name |
varchar(45) |
用户名 |
age |
int |
年龄 |
role_id |
int |
角色 ID |
角色表(role):(简单起见,假设只有 2 个字段)
字段名 |
类型 |
含义 |
id |
int |
角色 ID |
name |
varchar(45) |
角色名 |
接下来我们要实现一个用户查询的功能
这个查询有点复杂,它的要求如下:
- 可按用户名字段查询,要求: 可精确匹配(等于某个值) 可全模糊匹配(包含给定的值) 可后模糊查询(以...开头) 可前模糊查询(以.. 结尾) 可指定以上四种匹配是否可以忽略大小写
- 可按年龄字段查询,要求: 可精确匹配(等于某个年龄) 可大于匹配(大于某个值) 可小于匹配(小于某个值) 可区间匹配(某个区间范围)
- 可按角色ID查询,要求:精确匹配
- 可按用户ID查询,要求:同年龄字段
- 可指定只输出哪些列(例如,只查询 ID 与 用户名 列)
- 支持分页(每次查询后,页面都要显示满足条件的用户总数)
- 查询时可选择按 ID、用户名、年龄 等任意字段排序
后端接口该怎么写呢?
试想一下,对于这种要求的查询,后端接口里的代码如果用 MyBatis、Hibernate、Data Jdbc 直接来写的话,100 行代码 能实现吗?
反正我是没这个信心,算了,我还是直接坦白,面对这种需求后端如何 只用一行代码搞定 吧(有兴趣的同学可以 MyBatis 等写个试试,最后可以对比一下)
手把手:只一行代码实现以上需求
首先,重点人物出场啦:Bean Searcher, 它是一个专注于高级查询的 只读 ORM,对于这种列表检索,无论简单还是复杂,统统一行代码搞定!而且它还非常轻量,且无第三方依赖(可与任何其它 ORM 在同一项目中使用)。
假设我们项目使用的框架是 Spring Boot(当然 Bean Searcher 对框架没有要求,但在 Spring Boot 中使用更加方便)
添加依赖
Maven :
<dependency>
<groupId>com.ejlchina</groupId>
<artifactId>bean-searcher-boot-starter</artifactId>
<version>3.6.0</version>
</dependency>
复制代码
Gradle :
implementation 'com.ejlchina:bean-searcher-boot-starter:3.6.0'
复制代码
然后写个实体类来承载查询的结果
@SearchBean(tables="user u, role r", joinCond="u.role_id = r.id", autoMapTo="u")
public class User {
private Long id; // 用户ID(u.id)
private String name; // 用户名(u.name)
private int age; // 年龄(u.age)
private int roleId; // 角色ID(u.role_id)
@DbField("r.name") // 指明这个属性来自 role 表的 name 字段
private String role; // 角色名(r.name)
// Getter and Setter ...
}
复制代码
接着就可以写用户查询接口了
接口路径就叫 /user/index 吧:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private MapSearcher mapSearcher; // 注入检索器(由 bean-searcher-boot-starter 提供)
@GetMapping("/index")
public SearchResult<Map<String, Object>> index(HttpServletRequest request) {
// 这里咱们只写一行代码
return mapSearcher.search(User.class, MapUtils.flat(request.getParameterMap()));
}
}
复制代码
上述代码中的 MapUtils 是 Bean Searcher 提供的一个工具类,MapUtils.flat(request.getParameterMap()) 只是为了把前端传来的请求参数统一收集起来,然后剩下的,就全部交给 MapSearcher 检索器了。
这样就完了?那我们来测一下这个接口,看看效果吧
(1)无参请求
- GET /user/index
- 返回结果:
{
"dataList