# 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
# 
# 本仓库使用
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
```
## 多表查询
先来看看数据库结构

### 两个表
| 班级统计 | |
| --- | --- |
| 学校 | 班级 |
| | |
| | |
```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 != '' | 否 | 不为空(仅适用于 **字符串** 类型的字段) |