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

猿天地

共 4844字,需浏览 10分钟

 · 2022-05-28

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


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

文章来源: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 却可以只一行代码实现以上功能。


首先,你有一个实体类:
@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...
}


然后你就可以用一行代码实现这个用户检索接口:
@RestController
@RequestMapping("/user")
public class UserController {

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

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

}


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

  • 多表联查

  • 分页搜索

  • 组合过滤

  • 任意字段排序

  • 字段统计


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


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

代码如下:

{
  "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 两个字段。


代码如下:
{
  "dataList": [
    {
      "username""Jack",
      "age"25
    },
    ...
  ],
  "totalCount"100,
  "summaries": [
    2500
  ]
}


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


| 参数构建器

Map 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, 2030).op(Opetator.Between) // 过滤:age between 20 and 30
        .orderBy(User::getAge, "asc")                     // 排序:年龄,从小到大
        .page(015)                                      // 分页:第 0 页, 每页 15 条
        .build();
List users = beanSearcher.searchList(User.class, params);


| 快速开发

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

  • 普通的复杂列表查询只需一行代码

  • 单表检索可复用原有 Domain,无需定义 SearchBean


| 集成简单

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


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

implementation 'com.ejlchina:bean-searcher-boot-stater:3.6.0'


接着便可在 Controller 或 Service 里注入检索器:
/**
 * 注入 Map 检索器,它检索出来的数据以 Map 对象呈现
 */

@Autowired
private MapSearcher mapSearcher;

/**
 * 注入 Bean 检索器,它检索出来的数据以 泛型 对象呈现
 */

@Autowired
private BeanSearcher beanSearcher;


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

implementation 'com.ejlchina:bean-searcher:3.6.0'


然后可以使用 SearcherBuilder 构建一个检索器:
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 来支持更多的数据库

  • 等等..


源码地址


Gitee:https://gitee.com/ejlchina-zhxu/bean-searcher
GitHub:https://github.com/ejlchina/bean-searcher


推荐一款基于Java Agent实现的自测,联调Mock利器:
https://github.com/yinjihuan/fox-mock
-------------  END  -------------
扫描下方二维码,加入技术群。暗号:加群


浏览 6
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报