前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >比MyBatis快100倍,天生支持联表!

比MyBatis快100倍,天生支持联表!

作者头像
猿天地
发布2022-05-27 23:41:45
1K0
发布2022-05-27 23:41:45
举报
文章被收录于专栏:猿天地猿天地

点击上方蓝色字体,选择“设为星标”

回复”学习资料“获取学习宝典

文章来源:https://c1n.cn/my8R6

目录

  • 简介
  • 开源协议
  • 界面展示
  • 功能概述
  • 技术选型
  • 源码地址

简介

对于 Java 程序员来说,MyBatis、Hibernate 等都是常见的 ORM 框架,对于一些简单的 CRUD,事务支持非常不错。

但是有时候用起来可能比较繁琐,最近看到一个新的类似 ORM 的框架,具备了 ORM 框架的功能,同时也还有一点 GraphQL 语法的味道。

比 MyBatis 效率快 100 倍的条件检索引擎,天生支持联表,使一行代码实现复杂列表检索成为可能,绝无夸张之语!

开源协议

使用 Apache-2.0 开源协议。

界面展示

如下图:

你的产品给你画了以上一张图,还附带了一些要求:

  • 检索结果分页展示
  • 可以按任意字段排序
  • 按检索条件统计某些字段值

这时候,后台接口该怎么写???使用 Mybatis 或 Hibernate 写 100 行代码是不是还打不住?而使用 Bean Searcher,只需一行代码便可实现上述要求!!!

功能概述

特性如下:

  • 支持实体多表映射
  • 支持动态字段运算符
  • 支持分组聚合、查询
  • 支持Select | Where | From 子查询
  • 支持实体类嵌入参数
  • 支持字段转换器
  • 支持?Sql 拦截器
  • 支持数据库 Dialect 扩展
  • 支持多数据源与动态数据源
  • 支持注解缺省与自定义
  • 支持字段运算符扩展
  • 等等
| 快速开发

使用 Bean Searcher 可以极大节省后端的复杂列表检索接口的开发时间。

| 集成简单

可以和任意 Java Web 框架集成,如:SpringBoot、Grails、Jfinal 等。

| 扩展性强

面向接口设计,用户可自定义扩展 Bean Searcher 中的任何组件。

| 支持注解缺省

约定优于配置,可省略注解,可复用原有域类,同时支持自定义注解。

| 支持多数据源

分库分表?在这里特别简单,告别分库分表带来的代码熵值增高问题。

| 支持 Select 指定字段

同一个实体类,可指定只 Select 其中的某些字段,或排除某些字段。

| 支持参数过滤器

支持添加多个参数过滤器,可自定义参数过滤规则。

| 支持字段转换器

支持添加多个字段转换器,可自定义数据库字段到实体类字段的转换规则。

| 支持 SQL 拦截器

支持添加多个 SQL 拦截器,可自定义 SQL 生成规则。

技术选型

框架目的:只一行代码实现多表联查分页搜索任意字段组合过滤任意字段排序多字段统计。

架构图如下:

为什么用?这绝不是一个重复的轮子。

虽然增删改是 hibernate 和 mybatis、data-jdbc 等等 ORM 的强项,但查询,特别是有?多条件、联表、分页、排序的复杂的列表查询,却一直是它们的弱项。

传统的 ORM 很难用较少的代码实现一个复杂的列表检索,但 Bean Searcher 却在这方面下足了功夫,这些复杂的查询,几乎只用一行代码便可以解决。

例如,这样的一个典型的需求:

后端需要写一个检索接口,而如果用传统的 ORM 来写,代码之复杂是可以想象的,而 Bean Searcher 却可以只一行代码实现以上功能。

首先,你有一个实体类:

代码语言:javascript
复制
@SearchBean(tables="user?u,?role?r",?joinCond="u.role_id?=?r.id",?autoMapTo="u")

public?class?User?{
??private?long?id;
??private?String?username;
??private?int?status;
??private?int?age;
??private?String?gender;
??private?Date?joinDate;
??private?int?roleId;
??@DbField("r.name")
??private?String?roleName;
??//?Getters?and?setters...
}

然后你就可以用一行代码实现这个用户检索接口:

代码语言:javascript
复制
@RestController
@RequestMapping("/user")
public?class?UserController?{

????@Autowired
????private?BeanSearcher?beanSearcher;?//?注入?BeanSearcher?的检索器

????@GetMapping("/index")
????public?SearchResult<User>?index(HttpServletRequest?request)?{
????????//?这里只写一行代码
????????return?beanSearcher.search(User.class,?MapUtils.flat(request.getParameterMap()),?new?String[]{?"age"?});
????}

}

这一行代码实现了以下功能:

  • 多表联查
  • 分页搜索
  • 组合过滤
  • 任意字段排序
  • 字段统计

例如,该接口支持如下请求:

GET: /user/index:无参请求(默认分页)。

代码如下:

代码语言:javascript
复制
{
??"dataList":?[
????{
??????"id":?1,
??????"username":?"Jack",
??????"status":?1,
??????"level":?1,
??????"age":?25,
??????"gender":?"Male",
??????"joinDate":?"2021-10-01"
????},
????...?????//?默认返回?15?条数据
??],
??"totalCount":?100,
??"summaries":?[
????2500????//?age?字段统计
??]
}

GET: /user/index? page=1 & size=10:指定分页参数。

GET: /user/index? status=1:返回 status = 1 的用户。

GET: /user/index? name=Jac & name-op=sw:返回 name 已 Jac 开头的用户。

GET: /user/index? name=Jack & name-ic=true:返回 name = Jack(忽略大小写)的用户。

GET: /user/index? sort=age & order=desc:按字段 age 降序查询。

GET: /user/index? onlySelect=username,age:只检索 username 与 age 两个字段。

代码如下:

代码语言:javascript
复制
{
??"dataList":?[
????{
??????"username":?"Jack",
??????"age":?25
????},
????...
??],
??"totalCount":?100,
??"summaries":?[
????2500
??]
}

GET: /user/index? selectExclude=joinDate:检索时排除 joinDate 字段。

| 参数构建器
代码语言:javascript
复制
Map<String,?Object>?params?=?MapUtils.builder()
????????.selectExclude(User::getJoinDate)?????????????????//?排除?joinDate?字段
????????.field(User::getStatus,?1)????????????????????????//?过滤:status = 1
????????.field(User::getName,?"Jack").ic()????????????????//?过滤:name =?'Jack'?(case ignored)
????????.field(User::getAge,?20,?30).op(Opetator.Between)?//?过滤:age between 20 and 30
????????.orderBy(User::getAge,?"asc")?????????????????????//?排序:年龄,从小到大
????????.page(0,?15)??????????????????????????????????????//?分页:第?0?页, 每页 15 条
????????.build();
List<User>?users?=?beanSearcher.searchList(User.class,?params);
| 快速开发

使用 Bean Searcher 可以极大地节省后端的复杂列表检索接口的开发时间:

  • 普通的复杂列表查询只需一行代码
  • 单表检索可复用原有?Domain,无需定义?SearchBean
| 集成简单

可以和任意 Java Web 框架集成,如:SpringBoot、Spring MVC、Grails、Jfinal 等等。

SpringBoot 项目,添加依赖即集成完毕:

代码语言:javascript
复制
implementation?'com.ejlchina:bean-searcher-boot-stater:3.6.0'

接着便可在 Controller 或 Service 里注入检索器:

代码语言:javascript
复制
/**
?*?注入?Map?检索器,它检索出来的数据以?Map?对象呈现
?*/
@Autowired
private?MapSearcher?mapSearcher;

/**
?*?注入?Bean?检索器,它检索出来的数据以?泛型?对象呈现
?*/
@Autowired
private?BeanSearcher?beanSearcher;

其他框架,使用如下依赖:

代码语言:javascript
复制
implementation?'com.ejlchina:bean-searcher:3.6.0'

然后可以使用 SearcherBuilder 构建一个检索器:

代码语言:javascript
复制
DataSource?dataSource?=?...?????//?拿到应用的数据源

//?DefaultSqlExecutor?也支持多数据源
SqlExecutor?sqlExecutor?=?new?DefaultSqlExecutor(dataSource);

//?构建?Map?检索器
MapSearcher?mapSearcher?=?SearcherBuilder.mapSearcher()
????????.sqlExecutor(sqlExecutor)
????????.build();

//?构建?Bean?检索器
BeanSearcher?beanSearcher?=?SearcherBuilder.beanSearcher()
????????.sqlExecutor(sqlExecutor)
????????.build();
| 扩展性强

面向接口设计,用户可自定义扩展 Bean Searcher 中的任何组件!

比如你可以:

  • 自定义?FieldOp?来支持更多的字段运算符
  • 自定义?FieldConvertor?来支持任意的 特殊字段类型
  • 自定义?DbMapping?来实现自定义注解,或让 Bean Searcher 识别其它 ORM 的注解
  • 自定义?ParamResolver?来支持其它形式的检索参数
  • 自定义?Dialect?来支持更多的数据库
  • 等等..

源码地址

代码语言:javascript
复制
Gitee:https://gitee.com/ejlchina-zhxu/bean-searcher
GitHub:https://github.com/ejlchina/bean-searcher
代码语言:javascript
复制
推荐一款基于Java Agent实现的自测,联调Mock利器:https://github.com/yinjihuan/fox-mock-------------? END??-------------扫描下方二维码,加入技术群。暗号:加群
本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-05-27,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 猿天地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如下图:
  • 特性如下:
  • 使用 Bean Searcher 可以极大节省后端的复杂列表检索接口的开发时间。
  • SpringBoot 项目,添加依赖即集成完毕:
  • 其他框架,使用如下依赖:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com