比 MyBatis 快 100 倍,天生支持聯(lián)表!
今日推薦
答應(yīng)我, 不要再用 if (obj != null) 判空了
20個示例!詳解 Java8 Stream 用法,從此告別shi山(垃圾代碼)
利用Java8新特征,重構(gòu)傳統(tǒng)設(shè)計模式,你學(xué)會了嗎?
1
開源項目簡介
1

比 MyBatis 效率快 100 倍的條件檢索引擎,天生支持聯(lián)表,使一行代碼實現(xiàn)復(fù)雜列表檢索成為可能!

比 MyBatis 效率快 100 倍的條件檢索引擎,天生支持聯(lián)表,使一行代碼實現(xiàn)復(fù)雜列表檢索成為可能!
?
2
使用Apache-2.0開源協(xié)議
使用Apache-2.0開源協(xié)議
3
界面展示
3

你的產(chǎn)品給你畫了以上一張圖,還附帶了一些要求:
檢索結(jié)果分頁展示
可以按任意字段排序
按檢索條件統(tǒng)計某些字段值
這時候,后臺接口該怎么寫???使用 Mybatis 或 Hibernate 寫 100 行代碼是不是還打不住?而使用 Bean Searcher,只需?一行代碼?便可實現(xiàn)上述要求!!!

你的產(chǎn)品給你畫了以上一張圖,還附帶了一些要求:
檢索結(jié)果分頁展示
可以按任意字段排序
按檢索條件統(tǒng)計某些字段值
這時候,后臺接口該怎么寫???使用 Mybatis 或 Hibernate 寫 100 行代碼是不是還打不住?而使用 Bean Searcher,只需?一行代碼?便可實現(xiàn)上述要求!!!
4
特性
支持?實體多表映射 支持?動態(tài)字段運算符 支持?分組聚合 查詢 支持?Select | Where | From 子查詢 支持?實體類嵌入?yún)?shù) 支持?字段轉(zhuǎn)換器 支持?Sql 攔截器 支持?數(shù)據(jù)庫 Dialect 擴展 支持?多數(shù)據(jù)源 與 動態(tài)數(shù)據(jù)源 支持?注解缺省 與 自定義 支持?字段運算符 擴展 等等
支持?實體多表映射 支持?動態(tài)字段運算符 支持?分組聚合 查詢 支持?Select | Where | From 子查詢 支持?實體類嵌入?yún)?shù) 支持?字段轉(zhuǎn)換器 支持?Sql 攔截器 支持?數(shù)據(jù)庫 Dialect 擴展 支持?多數(shù)據(jù)源 與 動態(tài)數(shù)據(jù)源 支持?注解缺省 與 自定義 支持?字段運算符 擴展 等等
快速開發(fā)
使用 Bean Searcher 可以極大節(jié)省后端的復(fù)雜列表檢索接口的開發(fā)時間
集成簡單
可以和任意 Java Web 框架集成,如:SpringBoot、Grails、Jfinal 等
可以和任意 Java Web 框架集成,如:SpringBoot、Grails、Jfinal 等
擴展性強
面向接口設(shè)計,用戶可自定義擴展 Bean Searcher 中的任何組件
面向接口設(shè)計,用戶可自定義擴展 Bean Searcher 中的任何組件
支持 注解缺省
約定優(yōu)于配置,可省略注解,可復(fù)用原有域類,同時支持自定義注解
約定優(yōu)于配置,可省略注解,可復(fù)用原有域類,同時支持自定義注解
支持 多數(shù)據(jù)源
分庫分表?在這里特別簡單,告別分庫分表帶來的代碼熵值增高問題
分庫分表?在這里特別簡單,告別分庫分表帶來的代碼熵值增高問題
支持 Select 指定字段
同一個實體類,可指定只 Select 其中的某些字段,或排除某些字段
同一個實體類,可指定只 Select 其中的某些字段,或排除某些字段
支持 參數(shù)過濾器
支持添加多個參數(shù)過濾器,可自定義參數(shù)過濾規(guī)則
支持添加多個參數(shù)過濾器,可自定義參數(shù)過濾規(guī)則
支持 字段轉(zhuǎn)換器
支持添加多個字段轉(zhuǎn)換器,可自定義數(shù)據(jù)庫字段到實體類字段的轉(zhuǎn)換規(guī)則
支持添加多個字段轉(zhuǎn)換器,可自定義數(shù)據(jù)庫字段到實體類字段的轉(zhuǎn)換規(guī)則
支持 SQL 攔截器
支持添加多個 SQL 攔截器,可自定義 SQL 生成規(guī)則
支持添加多個 SQL 攔截器,可自定義 SQL 生成規(guī)則
5
框架目的:只一行代碼實現(xiàn):多表聯(lián)查分頁搜索任意字段組合過濾任意字段排序多字段統(tǒng)計
架構(gòu)圖:

為什么用
框架目的:只一行代碼實現(xiàn):多表聯(lián)查分頁搜索任意字段組合過濾任意字段排序多字段統(tǒng)計
架構(gòu)圖:

為什么用
這絕不是一個重復(fù)的輪子
雖然?增刪改?是 hibernate 和 mybatis、data-jdbc 等等 ORM 的強項,但查詢,特別是有?多條件、聯(lián)表、分頁、排序?的復(fù)雜的列表查詢,卻一直是它們的弱項。
傳統(tǒng)的 ORM 很難用較少的代碼實現(xiàn)一個復(fù)雜的列表檢索,但 Bean Searcher 卻在這方面下足了功夫,這些復(fù)雜的查詢,幾乎只用一行代碼便可以解決。
例如,這樣的一個典型的需求:

后端需要寫一個檢索接口,而如果用傳統(tǒng)的 ORM 來寫,代碼之復(fù)雜是可以想象的。
而 Bean Searcher 卻可以:
雖然?增刪改?是 hibernate 和 mybatis、data-jdbc 等等 ORM 的強項,但查詢,特別是有?多條件、聯(lián)表、分頁、排序?的復(fù)雜的列表查詢,卻一直是它們的弱項。
傳統(tǒng)的 ORM 很難用較少的代碼實現(xiàn)一個復(fù)雜的列表檢索,但 Bean Searcher 卻在這方面下足了功夫,這些復(fù)雜的查詢,幾乎只用一行代碼便可以解決。
例如,這樣的一個典型的需求:

后端需要寫一個檢索接口,而如果用傳統(tǒng)的 ORM 來寫,代碼之復(fù)雜是可以想象的。
而 Bean Searcher 卻可以:
只一行代碼實現(xiàn)以上功能
首先,你有一個實體類:
@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...
}
然后你就可以用一行代碼實現(xiàn)這個用戶檢索接口:
@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"?});
????}
??
}
這一行代碼實現(xiàn)了以下功能:
多表聯(lián)查
分頁搜索
組合過濾
任意字段排序
字段統(tǒng)計
例如,該接口支持如下請求:
GET: /user/index 無參請求(默認分頁): { "dataList":?[ { "id":?1, "username":?"Jack", "status":?1, "level":?1, "age":?25, "gender":?"Male", "joinDate":?"2021-10-01"?},?...?//?默認返回?15?條數(shù)據(jù)?], "totalCount":?100, "summaries":?[?2500?//?age?字段統(tǒng)計?] } GET: /user/index? page=1 & size=10 指定分頁參數(shù) 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?字段
首先,你有一個實體類:
@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...
}
然后你就可以用一行代碼實現(xiàn)這個用戶檢索接口:
@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"?});
????}
??
}這一行代碼實現(xiàn)了以下功能:
多表聯(lián)查
分頁搜索
組合過濾
任意字段排序
字段統(tǒng)計
例如,該接口支持如下請求:
GET: /user/index 無參請求(默認分頁): { "dataList":?[ { "id":?1, "username":?"Jack", "status":?1, "level":?1, "age":?25, "gender":?"Male", "joinDate":?"2021-10-01"?},?...?//?默認返回?15?條數(shù)據(jù)?], "totalCount":?100, "summaries":?[?2500?//?age?字段統(tǒng)計?] } GET: /user/index? page=1 & size=10 指定分頁參數(shù) 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?字段
參數(shù)構(gòu)建器
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,?20,?30).op(Opetator.Between)?// 過濾:age between 20 and 30
????????.orderBy(User::getAge,?"asc")?// 排序:年齡,從小到大
????????.page(0,?15)?// 分頁:第 0 頁, 每頁 15 條
????????.build();
List users = beanSearcher.searchList(User.class, params);
快速開發(fā)
使用 Bean Searcher 可以極大地節(jié)省后端的復(fù)雜列表檢索接口的開發(fā)時間!
普通的復(fù)雜列表查詢只需一行代碼
單表檢索可復(fù)用原有?Domain,無需定義?SearchBean
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,?20,?30).op(Opetator.Between)?// 過濾:age between 20 and 30
????????.orderBy(User::getAge,?"asc")?// 排序:年齡,從小到大
????????.page(0,?15)?// 分頁:第 0 頁, 每頁 15 條
????????.build();
List users = beanSearcher.searchList(User.class, params);
快速開發(fā)
使用 Bean Searcher 可以極大地節(jié)省后端的復(fù)雜列表檢索接口的開發(fā)時間!
普通的復(fù)雜列表查詢只需一行代碼
單表檢索可復(fù)用原有?Domain,無需定義?SearchBean
集成簡單
可以和任意 Java Web 框架集成,如:SpringBoot、Spring MVC、Grails、Jfinal 等等。
可以和任意 Java Web 框架集成,如:SpringBoot、Spring MVC、Grails、Jfinal 等等。
Spring Boot 項目,添加依賴即集成完畢:
implementation?'com.ejlchina:bean-searcher-boot-stater:3.6.0'
接著便可在 Controller 或 Service 里注入檢索器:
/**
?* 注入 Map 檢索器,它檢索出來的數(shù)據(jù)以 Map 對象呈現(xiàn)
?*/
@Autowired
private?MapSearcher mapSearcher;
/**
?* 注入 Bean 檢索器,它檢索出來的數(shù)據(jù)以 泛型 對象呈現(xiàn)
?*/
@Autowired
private?BeanSearcher beanSearcher;
implementation?'com.ejlchina:bean-searcher-boot-stater:3.6.0'接著便可在 Controller 或 Service 里注入檢索器:
/**
?* 注入 Map 檢索器,它檢索出來的數(shù)據(jù)以 Map 對象呈現(xiàn)
?*/
@Autowired
private?MapSearcher mapSearcher;
/**
?* 注入 Bean 檢索器,它檢索出來的數(shù)據(jù)以 泛型 對象呈現(xiàn)
?*/
@Autowired
private?BeanSearcher beanSearcher;其它框架,使用如下依賴:
implementation?'com.ejlchina:bean-searcher:3.6.0'
然后可以使用 SearcherBuilder 構(gòu)建一個檢索器:
DataSource dataSource = ...?// 拿到應(yīng)用的數(shù)據(jù)源
// DefaultSqlExecutor 也支持多數(shù)據(jù)源
SqlExecutor sqlExecutor =?new?DefaultSqlExecutor(dataSource);
// 構(gòu)建 Map 檢索器
MapSearcher mapSearcher = SearcherBuilder.mapSearcher()
????????.sqlExecutor(sqlExecutor)
????????.build();
// 構(gòu)建 Bean 檢索器
BeanSearcher beanSearcher = SearcherBuilder.beanSearcher()
????????.sqlExecutor(sqlExecutor)
????????.build();
implementation?'com.ejlchina:bean-searcher:3.6.0'然后可以使用 SearcherBuilder 構(gòu)建一個檢索器:
DataSource dataSource = ...?// 拿到應(yīng)用的數(shù)據(jù)源
// DefaultSqlExecutor 也支持多數(shù)據(jù)源
SqlExecutor sqlExecutor =?new?DefaultSqlExecutor(dataSource);
// 構(gòu)建 Map 檢索器
MapSearcher mapSearcher = SearcherBuilder.mapSearcher()
????????.sqlExecutor(sqlExecutor)
????????.build();
// 構(gòu)建 Bean 檢索器
BeanSearcher beanSearcher = SearcherBuilder.beanSearcher()
????????.sqlExecutor(sqlExecutor)
????????.build();擴展性強
面向接口設(shè)計,用戶可自定義擴展 Bean Searcher 中的任何組件!
比如你可以:
自定義?FieldOp?來支持更多的字段運算符 自定義?FieldConvertor?來支持任意的 特殊字段類型 自定義?DbMapping?來實現(xiàn)自定義注解,或讓 Bean Searcher 識別其它 ORM 的注解 自定義?ParamResolver?來支持其它形式的檢索參數(shù) 自定義?Dialect?來支持更多的數(shù)據(jù)庫 等等..
面向接口設(shè)計,用戶可自定義擴展 Bean Searcher 中的任何組件!
比如你可以:
自定義?FieldOp?來支持更多的字段運算符 自定義?FieldConvertor?來支持任意的 特殊字段類型 自定義?DbMapping?來實現(xiàn)自定義注解,或讓 Bean Searcher 識別其它 ORM 的注解 自定義?ParamResolver?來支持其它形式的檢索參數(shù) 自定義?Dialect?來支持更多的數(shù)據(jù)庫 等等..
6
Gitee:https://gitee.com/ejlchina-zhxu/bean-searcher
GitHub:https://github.com/ejlchina/bean-searcher
最后,再給大家推薦一個GitHub項目,該項目整理了上千本常用技術(shù)PDF,技術(shù)書籍都可以在這里找到。
GitHub地址:https://github.com/hello-go-maker/cs-books
電子書已經(jīng)更新好了,拿走不謝,記得點一個star,持續(xù)更新中...

Gitee:https://gitee.com/ejlchina-zhxu/bean-searcher
GitHub:https://github.com/ejlchina/bean-searcher
最后,再給大家推薦一個GitHub項目,該項目整理了上千本常用技術(shù)PDF,技術(shù)書籍都可以在這里找到。
GitHub地址:https://github.com/hello-go-maker/cs-books
電子書已經(jīng)更新好了,拿走不謝,記得點一個star,持續(xù)更新中...
