Bean Searcher v4.3.0 重大更新!

本文涉及的产品
PolarClaw,2核4GB
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS DuckDB + QuickBI 企业套餐,8核32GB + QuickBI 专业版
简介: Bean Searcher 是一款专注高级查询的只读 ORM 开源项目。本次更新带来了大家期待已久的功能 ...

往期阅读:

Bean Searcher 是什么?

Bean Searcher 是一款专注高级查询的只读 ORM 开源项目,其官网如下:

image.png

// SpringBoot / Grails 项目直接使用该依赖
implementation 'cn.zhxu:bean-searcher-boot-starter:4.3.0'
// Solon 项目直接使用该依赖(功能同 bean-searcher-boot-starter)
implementation 'cn.zhxu:bean-searcher-solon-plugin:4.3.0'
// 非 SpringBoot / Grails / Solon 项目,直接使用核心依赖,
implementation 'cn.zhxu:bean-searcher:4.3.0'

本次更新内容

1、新增用于在后端嵌套构造复杂条件的 and(..)or(..) 方法:

例如,后端想查询满足 {[(name = 'Jack' 且 忽略大小写) 并且 (gender = 'Male')] 或者 [name = 'Alice' 并且 gender = 'Female']} 并且 (age >= 20) 条件的所有 User 数据,则可以:

  • v4.3.0 新增的 后端构造检索条件 的写法:
// 构造检索参数
var params = MapUtils.builder()
        .or(o -> o
            .and(a -> a
                .field(User::getName, "Jack").ic()
                .field(User::getGender, "Male")
            )
            .and(a -> a
                .field(User::getName, "Alice")
                .field(User::getGender, "Female")
            )
        )
        .field(User::getAge, "20").op(GreateEqual.class)
        .build();
// 执行查询
List<User> users = beanSearcher.searchAll(User.class, params);

使用 and(..)or(..) 方法后,无需在手动调用 groupExpr(..) 设置逻辑表达式,因为它会自动生成了。

  • v4.3.0 之前的 后端构造检索条件 的写法:
// 构造检索参数
var params = MapUtils.builder()
        .group("A")             // A 组开始
        .field(User::getName, "Jack").ic()
        .field(User::getGender, "Male")
        .group("B")             // B 组开始
        .field(User::getName, "Alice")
        .field(User::getGender, "Female")
        .group("C")             // C 组开始
        .field(User::getAge, "20").op(GreateEqual.class)
        .groupExpr("(A|B)&C")   // 组间逻辑关系(组表达式)
        .build();
// 执行查询
List<User> users = beanSearcher.searchAll(User.class, params);
  • 当然,同样的检索条件,后端可以只写一行代码,由前端传参控制:

前端只需传参:

A.name=Jack      // A 组条件
A.name-ic=true
A.gender=Male
B.name=Alice     // B 组条件
B.gender=Female
C.age=20         // C 组条件
C.age-op=ge
gexpr=(A|B)&C    // 组间的逻辑关系

然后,在后端一行代码实现查询:

@GetMapping("/users")
public SearchResult<User> users(HttpServletRequest request) {
   
   
    // 接收前端参数,执行查询(无需担心非法参数,框架会自动过滤)
    return beanSearcher.search(User.class, MapUtils.flat(request.getParameterMap())); 
}

参考:https://bs.zhxu.cn/guide/param/group.html

2、前端传参的 关系表达式 与 后端参数构建器构建的逻辑关系支持合并:

例如,前端传参:

A.name=Jack      // A 组条件
B.name=Alice     // B 组条件
gexpr=A|B        // 组间的逻辑关系

然后,后端也构建了逻辑关系:

@GetMapping("/users")
public SearchResult<User> users(HttpServletRequest request) {
   
   
    // 接收前端参数
    var params = MapUtils.flatBuilder(request.getParameterMap())
            // 附加一些条件
            .or(o -> o
                .field(User::getGender, "Female")
                .field(User::getAge, "20").op(LessThan.class)
            )
            .build();
    // 执行查询
    return beanSearcher.search(User.class, params); 
}

则实际生成的条件为:(name = 'Jack' 或者 name = 'Alice') 并且 (gender = 'Female' 或者 age < 20)

参考:https://bs.zhxu.cn/guide/param/group.html#%E8%A1%A8%E8%BE%BE%E5%BC%8F%E5%90%88%E5%B9%B6-since-v4-3-0

3、拼接参数,支持直接使用 集合参数值

例如在 SearchBean 中定义了一个 ages 拼接参数:

@SearchBean(where = "age in (:ages:)")
public class User {
   
   
    // ...
}

然后在检索时,可以为其直接添加集合参数值:

var params = MapUtils.builder()
        .put("ages", Arrays.asList(20,30,40))   // 直接使用 List 参数值,也可以使用 Set
        .build();
List<User> users = searcher.searchList(User.class, params);

也可以使用数组作为参数值:

var params = MapUtils.builder()
        .put("ages", new int[] {
   
   20,30,40})     // 可以使用原生数组
        .put("ages", new Integer[] {
   
   20,30,40}) // 也可以使用对象数组
        .build();
List<User> users = searcher.searchList(User.class, params);

v4.3.0 之前,只能使用字符串:

var params = MapUtils.builder()
        .put("ages", "20,30,40")               // v4.3.0 之前的用法,只能传字符串
        .build();
List<User> users = searcher.searchList(User.class, params);

参考:https://bs.zhxu.cn/guide/param/embed.html#%E6%8B%BC%E6%8E%A5%E5%8F%82%E6%95%B0

4、支持前端同名参数传多个值的用法

例如,前端这样请求用户查询接口:

  • 新支持的方式:GET /users ? age=20 & age=30 & age-op=bt

则其与下面的方式等效:

  • 原始传参方式:GET /users ? age-0=20 & age-1=30 & age-op=bt

bt 是什么?请参考:https://bs.zhxu.cn/guide/param/field.html

5、支持后缀运算符的简化传参形式

例如,前端原本的两个参数 age=20 & age-op=ge,现在可以简化成一个:age-ge=20

即使进行了逻辑分组,也可以被简化,例如:

A.age=30
A.age-op=gt

可以简化为

A.age-gt=30

参考:https://bs.zhxu.cn/guide/advance/filter.html#suffixopparamfilter

6、支持让前端以 JSON 数组的方式传递多个参数值

例如,原来的传参形式(age between 20 and 30):

age-0=20
age-1=30
age-op=bt

现在可以简化为:

age=[20,30]
age-op=bt

当然还可以进一步简化:

age-bt=[20,30]

参考:https://bs.zhxu.cn/guide/advance/filter.html#jsonarrayparamfilter

7、新增 AlwaysTrue(恒真:at)与 AlwaysFalse(恒假:af)运算符

  • AlwaysTrue(恒真:at)始终生成条件 1
  • AlwaysFalse(恒真:af)始终生成条件 0

例如,前端传参 name=Jack & age = 30 两个参数进行用户查询,后端接口里想忽略前端的 age 字段,则可以:

@GetMapping("/users")
public SearchResult<User> users(HttpServletRequest request) {
   
   
    var params = MapUtils.flatBuilder(request.getParameterMap())
            field(User::getAge).op(AlwaysTrue.class) // 使用 恒真 运算符
            .build();
    return beanSearcher.search(User.class, params); 
}

则,最终生成的 SQL 条件为 ... where name = 'Jack' and 1,起到吧 age 参数忽略的目的。当然,我们还可以使用 条件约束,直接声明 age 字段不能参与 where 条件,来到达通用的效果:

public class User {
   
   
    @DbField(conditional = false)
    private int age;
    // ...
}

只不过使用这种方式,age 字段就再也不能动态作为条件了。所以,这两种方式分别适用于不同的场景。

8、升级了 Oracle 方言的分页语法

升级了 OracleDialect, 采用了 offset ? rows fetch next ? rows only 分页语法,该语法在 Oracle 12c(2013年6月发布)及以上版本支持。

所以如果你使用的是 12c 以前的 Oracle 版本,在使用 Bean Searcher v4.3+ 时,则需要将老版本的 OracleDialect(点击查看方言代码) 拷贝到自己的项目中,作为自定义方言使用。

参考:https://bs.zhxu.cn/guide/advance/dialect.html

9、升级 BeanMetaSearchSql 与 参数构建器,优化或增加了一些 API

  • BeanMeta 新增了 getSqlSnippets() 方法,用户可以在 过滤器拦截器 中 使用该方法获取该实体类上所有已解析的 SQL 片段;
  • SearchSql 新增了 getSearchParam() 方法,用户可以在 拦截器 中使用该方法获取到解析后的检索参数;
  • 优化参数构建器的 field(FieldFn, Collection)field(String, Collection) 方法,使其第二个参数兼容传入 null 的用法,例如下面的代码将不再报错:
// List 参数,但是值为 null,最终该参数条件会被忽略
List<Long> idList = null;

var params = MapUtils.builder()
        .field(User::getId, idList).op(InList.class)
        .build();
List<User> users = beanSearcher.search(User.class, params);
  • 参数构建器新增 buildForRpc() 方法,用于在后端请求其它服务的 Bean Searcher 查询接口,例如:
// 组织检索参数
var params = MapUtils.builder()
        .field(User::getAge, 20, 30).op(Between.class)
        .page(0, 20)
        .buildForRpc();
// 调用远程服务中的接口
List<User> users = romoteApi.getUserList(params);

参考:https://bs.zhxu.cn/guide/usage/rpc.html

10、新增 5 个配置项

bean-searcher:
    params:
        group:
            # 指定组表达式是否可合并,默认 true
            mergeable: true
        filter:
            # 是否启用 SizeLimitParamFilter,默认 true
            use-size-limit: true
            # 是否启用 ArrayValueParamFilter,默认 true
            use-array-value: true
            # 是否启用 SuffixOpParamFilter,默认 false
            use-suffix-op: true
            # 是否启用 JsonArrayParamFilter,默认 false
            use-json-array: true

参考:https://bs.zhxu.cn/guide/info/versions.html#v4-3-%E7%9A%84%E6%96%B0%E7%89%B9%E6%80%A7-v4-3-0

最后:点个 STAR 吧

如果觉得文本不错,动手点个赞吧 ^_^

往期阅读:

相关文章
|
1月前
|
SQL Java 数据库
【MyBatis-Plus】Spring Boot + MyBatis-Plus 进行各种数据库操作(附完整 CRUD 项目代码示例)
本文详解Spring Boot集成MyBatis-Plus全流程:从依赖引入、数据源配置、Mapper扫描到分页/乐观锁/逻辑删除等核心插件配置;涵盖BaseMapper基础CRUD、LambdaQueryWrapper条件查询、Service层封装、自定义XML多表关联及批量优化实践,附完整可运行示例。
|
SQL Java 数据库连接
JPA 之 QueryDSL-JPA 使用指南
JPA 之 QueryDSL-JPA 使用指南
1484 0
|
人工智能 开发框架 Java
重磅发布!AI 驱动的 Java 开发框架:Spring AI Alibaba
随着生成式 AI 的快速发展,基于 AI 开发框架构建 AI 应用的诉求迅速增长,涌现出了包括 LangChain、LlamaIndex 等开发框架,但大部分框架只提供了 Python 语言的实现。但这些开发框架对于国内习惯了 Spring 开发范式的 Java 开发者而言,并非十分友好和丝滑。因此,我们基于 Spring AI 发布并快速演进 Spring AI Alibaba,通过提供一种方便的 API 抽象,帮助 Java 开发者简化 AI 应用的开发。同时,提供了完整的开源配套,包括可观测、网关、消息队列、配置中心等。
11137 122
|
存储 运维 应用服务中间件
Docker Image即Docker镜像
Docker 镜像是 Docker 容器的基础,包含了运行应用程序所需的一切。通过 Dockerfile 可以方便地创建自定义镜像,并且利用 Docker 提供的命令可以轻松管理和使用这些镜像。掌握 Docker 镜像的创建、管理和使用,是进行容器化应用开发和部署的基础技能。希望本文能帮助读者更好地理解 Docker 镜像的概念和操作,提高开发和运维效率。
1526 13
|
人工智能 Java 程序员
AI程序员(通义灵码)
本文聚焦通义灵码在项目开发中的应用,详细介绍以IntelliJ IDEA 2024.3为平台,安装通义灵码插件的步骤,为后续开发筑牢基础。以开发英语单词默写考试应用为例,阐述从新建Spring Boot项目、配置相关参数与依赖,到借助通义灵码输入精确提示词进行项目代码生成的完整流程。在开发过程中,提示词经过十余次调整,优化为涵盖项目概况、功能明细及优化要求的结构,如同与开发人员深度沟通协作,确保项目满足预期。项目成功启动并完成测试,展现通义灵码的强大助力。文章最后指出,掌握AI工具的人将在竞争中占据优势,AI如同工业革命时期的新生产工具,并非取代人类,而是推动工作效率提升与行业变革。
547 3
|
Web App开发 Windows
FFmpeg开发笔记(十五)详解MediaMTX的推拉流
MediaMTX是开源轻量级流媒体服务器,提供RTSP, RTMP, HLS, WebRTC和SRT服务。启动后,它在不同端口监听。通过FFmpeg的推拉流测试,证明了MediaMTX成功实现HLS流媒体转发,但HLS播放兼容性问题可能因缺少音频流导致。推流地址为rtsp://127.0.0.1:8554/stream,RTMP地址为rtmp://127.0.0.1:1935/stream,HLS播放地址为http://127.0.0.1:8888/stream(Chrome)和http://127.0.0.1:8888/stream/index.m3u8(其他播放器可能不支持)。
3487 2
FFmpeg开发笔记(十五)详解MediaMTX的推拉流
|
XML 前端开发 Java
SpringBoot参数校验@Validated、@Valid(javax.validation)详解
SpringBoot参数校验@Validated、@Valid(javax.validation)
3521 4
IDEA 利用groovy脚本生成注释
【10月更文挑战第29天】在 IntelliJ IDEA 中,可以通过创建和运行 Groovy 脚本来自动生成 Java 类方法的 Javadoc 注释。首先,创建一个 Groovy 文件并编写脚本,该脚本会检查每个方法是否已有注释,如果没有,则生成包含方法描述、参数列表和返回值的基本注释。接着,通过“Tools”菜单下的“Groovy Console”运行脚本,确保脚本中的包版本与当前使用的 IntelliJ IDEA 版本匹配。运行后,脚本将自动为选定类的方法添加注释。建议在执行前备份代码,以防意外。
584 2
|
机器学习/深度学习 Ubuntu 数据挖掘
Ubuntu系统部署Anaconda环境及Python语言的详细流程
以上就是在Ubuntu系统中安装Anaconda环境及Python语言的详细流程。Anaconda为Python科学计算提供了便捷的管理方式,帮助用户轻松处理不同项目之间依赖管理的复杂性。通过以上步骤,你现在应该有了一个完全可用的Anaconda环境,可以开始在Ubuntu上进行Python编程和数据科学项目的探索了。
1051 5
|
XML 安全 Java
一个不用写代码的案例,来看看Flowable到底给我们提供了哪些功能?
一个不用写代码的案例,来看看Flowable到底给我们提供了哪些功能?
1161 1
下一篇
开通oss服务