# bean_searcher_test **Repository Path**: yangzhous_admin/bean_searcher_test ## Basic Information - **Project Name**: bean_searcher_test - **Description**: 今天给大家介绍一个java数据库查询的开源项目,叫BeanSearcher(Apache2.0)。 我们使用java操作数据库很多时候使用的是mybatis、Hibernate、jpa等等,都是具有完整的CRUD功能的,而BeanSearcher专做查询功能,对多表查询支持的比较好。优点灵活小巧,即可以像使用sql语句查询一样的方便,又保留了ORM的面向对象编程特点。在使用时不必再纠结mybati - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2023-09-25 - **Last Updated**: 2023-09-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ![image.png](https://cdn.nlark.com/yuque/0/2022/png/643671/1664259143976-f9827902-d2c7-437c-8536-c4e1131a5b94.png#clientId=u68b4cfae-ff2f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=366&id=ua2262880&margin=%5Bobject%20Object%5D&name=image.png&originHeight=366&originWidth=1197&originalType=binary&ratio=1&rotation=0&showTitle=false&size=66215&status=done&style=none&taskId=u2f615d53-90a0-47a7-a247-0dfd64edccd&title=&width=1197) # 本仓库使用 1. mysql执行init.sql初始化数据库。 2. 修改application.ymal数据库配置文件。 3. 执行test包下的BeanSearcherApplicationTests初始化数据。 # 概述 今天给大家介绍一个java数据库查询的开源项目,叫BeanSearcher(Apache2.0)。 我们使用java操作数据库很多时候使用的是mybatis、Hibernate、jpa等等,都是具有完整的CRUD功能的,而BeanSearcher只有查询的能力,他的优点我觉得就是灵活小巧,即可以像使用sql语句查询一样的方便,又保留了ORM的面向对象编程特点。在使用时不必再纠结mybatis的各种映射,do和vo的转换,能够极大的提高我们的开发效率,又不增加维护难度,实在是居家开发的利器。 **Bean Searcher[官网链接](https://bs.zhxu.cn)** # 特点&优点 1. 集成简单,注解开发,学习难度低,可以很快上手使用 2. 支持参数过滤、字段转换器、Select指定字段、SQL拦截 3. 可以快速方便的进行多表查询 4. 简化了DO/VO的转换 5. 扩展性强 6. 支持多数据源 在BeanSearcher有MapSearcher和BeanSearcher两个检索器,是我们用来进行查询的最重要的工具,其中MapSearcher查询出的结果都是以Map对象呈现,BeanSearcher的结果以Bean或者叫VO的对象呈现,根据实际开发的需求,我们可以选择不通的检索器。 下边我们写两个小例子来看看BeanSearcher是如何使用的。 # # 基本功能 ## 项目集成 首先看一下如何集成BeanSearcher,我们这里已经准备了一个springboot+mybatis的项目,我们将beanSearcher集成上来。 ```xml com.ejlchina bean-searcher 3.8.0 com.ejlchina bean-searcher-boot-starter 3.8.0 ``` ## 基本配置 了解参数配置查看 # 查询 ## 无参查询 ```java beanSearcher.searchList(UserDO.class,null); ``` 可以使用searchFirst来查询一个数据,如果查询出多个结果是不会抛异常的。 ```java beanSearcher.searchFirst(UserDO.class,null); ``` ## 查询参数的使用 ### 通过构造一个Map进行查询参数 ```java public List userList( String name, Integer age){ Map params = new HashMap<>(); params.put("name",name); params.put("age",age); params.put("age-op","gt"); return beanSearcher.searchList(UserDO.class,params); } // ``` 这里有一个`age-op`是来设置查询`age`是的运算符,(这里的op,可以通过参数进行设置),默认每个参数都会有一个`eq`的运算符,我们在这里设置了`age`字段的运算符是`>`。 很明显这么查询也会很慢,这里我们就可以来看看BeanSearcher给我们提供的MapUtils了,使用这个工具可以更方便的进行查询参数的拼装工作。 ```java @RequestMapping(value = "users2") public List userList2( String name, Integer age){ return beanSearcher.searchList(UserDO.class, MapUtils.builder() .field(UserDO::getName,name).op(Equal.class) .field(UserDO::getAge,age).op(GreaterThan.class) .build() ); } ``` 虽然代码很多,但是好消息是我们变成了一行,而且我们不用再去拼接字段名了,一切看起来都挺顺利。那如果这个时候产品经理说了用户名称需要进行模糊查询怎么办,又要改界面,加参数。不不不~~MapUtils还有办法。 ```java @RequestMapping(value = "users3") public List userList3(HttpServletRequest request){ return beanSearcher.searchList(UserDO.class, MapUtils.flat(request.getParameterMap()) ); } ``` 通过flat方法将一个 value 为数组的 Map 对象,拉平为 value 为单值的 Map 对象,我们这里直接将界面上的参数map传过去,然后对我们界面的入参调整一下,完成了,以后再加什么参数都无所谓啦,只需要调整前端入参就可以了。 ```java age=32&name=mi&age-op=gt&name-op=ct ``` ## 多表查询 先来看看数据库结构 ![image.png](https://cdn.nlark.com/yuque/0/2022/png/643671/1664340808170-2a66afe5-3a87-42d2-8306-dec19e37ccdb.png#clientId=ue7047c25-f5a6-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=801&id=xGgoN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=801&originWidth=935&originalType=binary&ratio=1&rotation=0&showTitle=false&size=101187&status=done&style=none&taskId=udf15557b-ea29-4336-aec7-703e5970691&title=&width=935) ### 两个表 | 班级统计 | | | --- | --- | | 学校 | 班级 | | | | | | | ```java @SearchBean( tables = "school s , class c", where = "s.id = c.school_id", autoMapTo = "c" ) @Data public class StatisticVO { @DbField("s.name") String name; String grade; String num; } ``` ```java @RequestMapping(value ="statistic") public List statistic(HttpServletRequest request){ return beanSearcher.searchList(StatisticVO.class, MapUtils.flat(request.getParameterMap())); } ``` ### 多个表 | 班级统计 | | | | --- | --- | --- | | 学校 | 班级 | 学生 | | | | | | | | | ```java @SearchBean( tables = "school s " + "left join class c on c.school_id = s.id " + "left join student st on st.class_id = c.id", autoMapTo = "c" ) @Data public class Statistic1VO { @DbField("s.name") String name; String grade; String num; @DbField("st.name") String studentName; } ``` ```java @RequestMapping(value ="statistic1") public List statistic1(HttpServletRequest request){ return beanSearcher.searchList(Statistic1VO.class, MapUtils.flat(request.getParameterMap())); } ``` ### 子查询 | 班级统计 | | | | | --- | --- | --- | --- | | 学校 | 班级 | 学生 | 总成绩 | | | | | | | | | | | ```java @SearchBean( tables = "school s " + "left join class c on c.school_id = s.id " + "left join student st on st.class_id = c.id", autoMapTo = "c" ) @Data public class Statistic1VO { @DbField("s.name") String name; String grade; String num; @DbField("st.name") String studentName; } ``` ```java @RequestMapping(value ="statistic2") public List statistic2(HttpServletRequest request){ return beanSearcher.searchList(Statistic2VO.class, MapUtils.flat(request.getParameterMap())); } ``` ### 分组查询 统计一下每个班级的成绩,要求根据批次和科目统计 | 班级统计 | | | | --- | --- | --- | | 学校 | 班级 | 总成绩 | | | | | | | | | ```java @SearchBean( tables = "performance p " + "left join student stu on stu.id = p.student_id " + "left join class c on c.id = stu.class_id " + "left join school sc on sc.id = c.school_id", autoMapTo = "c", groupBy = "sc.name,c.grade,c.num" ) @Data public class Statistic3VO { @DbField("sc.name") String name; @DbField("concat(c.grade,'年',c.num,'班')") String gradeClass; @DbField("sum(p.score)") Double sumScore; } ``` ```java public List statistic3(HttpServletRequest request){ return beanSearcher.searchList(Statistic3VO.class, MapUtils.flat(request.getParameterMap())); } ``` # 配置 ## 排序约束配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.sql.default-mapping.sort-type | 默认排序约束 | ALLOW_PARAM、ONLY_ENTITY | ALLOW_PARAM | ## 表名注解缺省配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.sql.default-mapping.table-prefix | 表名前缀 | 字符串 | null | | bean-searcher.sql.default-mapping.underline-case | 表名和字段名是否驼峰转小写下划线(since v3.7.0) | 布尔值 | true | | bean-searcher.sql.default-mapping.upper-case | 表名和字段名是否大写 | 布尔值 | false | | bean-searcher.sql.default-mapping.redundant-suffixes | 类名的冗余后缀(可配多个)(since v3.3.0) | 冗余后缀 | null | ## 默认继承方式配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.sql.default-mapping.inherit-type | 默认继承类型 | ALL、TABLE、FIELD、NONE | ALL | ## 全局属性忽略配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.sql.default-mapping.ignore-fields | 需要全局忽略的属性名(可指定多个) | 字符串数组 | null | ## 分页参数配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.params.pagination.type | 分页类型 | page、offset | page | | bean-searcher.params.pagination.default-size | 默认每页查询条数 | 正整数 | 15 | | bean-searcher.params.pagination.max-allowed-size | 每页最大查询条数(分页保护) | 正整数 | 100 | | bean-searcher.params.pagination.page | 页码参数名(在 type = page 时有效) | 字符串 | page | | bean-searcher.params.pagination.size | 每页大小参数名 | 字符串 | size | | bean-searcher.params.pagination.offset | 偏移参数名(在 type = offset 时有效) | 字符串 | offset | | bean-searcher.params.pagination.start | 起始页码 或 起始偏移量 | 自然数 | 0 | ## 排序参数配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.params.sort | 排序字段参数名 | 字符串 | sort | | bean-searcher.params.order | 排序方法参数名 | 字符串 | order | | bean-searcher.params.order-by | 排序参数名(since v3.4.0) | 字符串 | orderBy | ## 字段参数配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.params.separator | 字段参数名分隔符 | 字符串 | - | | bean-searcher.params.operator-key | 字段运算符参数名后缀 | 字符串 | op | | bean-searcher.params.ignore-case-key | 是否忽略大小写字段参数名后缀 | 字符串 | ic | ## 逻辑分组参数配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.params.group.enable | 是否开启逻辑分组功能 | 布尔 | true | | bean-searcher.params.group.expr-name | 逻辑表达式参数名 | 字符串 | gexpr | | bean-searcher.params.group.expr-cache-size | 表达式解析缓存(个数) | 整型 | 50 | | bean-searcher.params.group.separator | 组名分隔符 | 字符串 | . | ## 指定Select字段配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.params.only-select | onlySelect 参数名 | 字符串 | onlySelect | | bean-searcher.params.select-exclude | selectExclude 参数名 | 字符串 | selectExclude | ## SQL方言配置 | 配置键名 | 含义 | 可选值 | 默认值 | | --- | --- | --- | --- | | bean-searcher.sql.dialect | SQL 方言 | MySQL、Oracle、PostgreSQL、SqlServer | MySQL | ## 慢SQL日志与监听 | 配置键名 | 含义 | 类型 | 默认值 | | --- | --- | --- | --- | | bean-searcher.sql.slow-sql-threshol | 慢 SQL 阈值(单位:毫秒) | int | 500 | # 字段运算符 | 运算符 | 缩写 | SQL 片段 | 是否忽略空值 | 含义 | | --- | --- | --- | --- | --- | | Equal | eq | x = ? | 是 | 等于(是缺省默认的运算符) | | NotEqual | ne | x != ? | 是 | 不等于 | | GreaterThan | gt | x > ? | 是 | 大于 | | GreaterEqual | ge | x >= ? | 是 | 大于等于 | | LessThan | lt | x < ? | 是 | 小于 | | LessEqual | le | x <= ? | 是 | 小于等于 | | Between | bt | x between ?1 and ?2 / x >= ?1 / x <= ?2 | 是 | 在...之间(范围查询) | | NotBetween | nb | x not between ?1 and ?2 / x < ?1 / x > ?2 | 是 | 不在...之间(范围查询)(**since v3.3**) | | Contain | ct | x like '%?%' | 是 | 包含(模糊查询)(**since v3.2**) | | StartWith | sw | x like '?%' | 是 | 以...开头(模糊查询) | | EndWith | ew | x like '%?' | 是 | 以...结尾(模糊查询) | | OrLike | ol | x like ?1 or x like ?2 or ... | 是 | 模糊或匹配(可有多个参数值)(**since v3.7**) | | NotLike | nk | x not like ? | 是 | 反模糊匹配(**since v3.8**) | | InList | il/ mv | x in (?, ?, ...) | 是 | 多值查询(InList / il **自 v3.3 新增**,之前是 MultiValue/ mv) | | NotIn | ni | x not in (?, ?, ...) | 是 | 多值查询(**since v3.3**) | | IsNull | nl | x is null | 否 | 为空(**since v3.3**) | | NotNull | nn | x is not null | 否 | 不为空(**since v3.3**) | | Empty | ey | x is null or x = '' | 否 | 为空(仅适用于 **字符串** 类型的字段) | | NotEmpty | ny | x is not null and x != '' | 否 | 不为空(仅适用于 **字符串** 类型的字段) |