企業應用面臨的問題
- 高效編寫數據庫訪問代碼
- 內置CRUD,不需要寫SQL
- 支持OR/Mapping
- 悲觀鎖,樂觀鎖,邏輯刪除等輔助支持等
- 即支持簡單的CRUD,也支持數十行,上百行SQL編寫
- 跨數據庫平臺支持,Oracle,Postgres,Mysql,以及SQLServer,DB2,H2,SQLLite,包括翻頁,排序,還有各個廠商特殊語法
- 易於維護
- 重構支持
- 易於修改
- DBA友好
- 豐富的調試手段,詳細日誌輸出
- Interceptor支持:具備SQL執行監控,SQL重寫
- 支持POJO或者Map,或者混合模型
BeetlSQL 使用方式
- 內置API調用完成
- Query鏈式查詢
- MarkDown 維護複雜SQL
- 支持POJO,也支持Map或者混合模型
- 主從支持和Sharding-JDBC分表分庫集成
內置API
void insert(T entity);
void insertBatch(List<T> list);
int updateById(T entity);
int updateTemplateById(T entity);
int deleteById(Object key);
T unique(Object key);
T single(Object key);
T lock(Object key);
List<T> all();
List<T> template(T entity);
<T> T templateOne(T entity);
List<T> execute(String sql,Object... args);
int executeUpdate(String sql,Object... args );
Query<T> createQuery();
LambdaQuery<T> createLambdaQuery();
Query 鏈式操作
Query<User> query = sqlManager.query(User.class);
long count = query.andEq("name", "new name")
.orEq("id", 1637).limit(1, 10).count();
Java8
LambdaQuery<User> query = sqlManager.lambdaQuery(User.class);
User user = query.andEq(User::getId, 1641).single();
user = query.andEq(User::getId, 1642).single();
處理複雜SQL
select
@pageTag(){
u.*,o.name org_name
@}
from core_user u left join core_org o on u.org_id=o.id where 1=1 and u.del_flag = 0
@//數據權限,該sql語句功能點
and #function("user.query")#
@if(!isEmpty(orgId)){
and u.org_id =#orgId#
@}
@if(!isEmpty(orgId)){
and u.org_id =#orgId#
@}
@if(!isEmpty(code)){
and u.code like #"%"+code+"%"#
@}
@if(!isEmpty(name)){
and u.name like #"%"+name+"%"#
@}
@if(!isEmpty(state)){
and u.state = #state#
@}
超簡單的Dao實現
@SqlResource("console.user")
public interface UserConsoleDao extends BaseMapper<CoreUser> {
PageQuery<CoreUser> queryByCondtion(PageQuery<CoreUser> query);
void batchDelUserByIds( List<Long> ids);
void batchUpdateUserState(List<Long> ids, GeneralStateEnum state);
List<CoreUserRole> queryUserRole( Long id,Long orgId,Long roleId);
}
- console.user 指明瞭SQL文件的位置,方法名對應了SQL片段名稱。
- 繼承BaseMapper可以獲得內置的CRUD等若干現成方法
調試
內置DebugInterceptor,也支持擴展,用於安全監控,性能監控,改寫SQL
┏━━━━━ Debug [user.selectUserAndDepartment] ━━━
┣ SQL: select * from user where 1 = 1
┣ 參數: []
┣ 位置: org.beetl.sql.test.QuickTest.main(QuickTest.java:47)
┣ 時間: 23ms
┣ 結果: [3]
┗━━━━━ Debug [user.selectUserAndDepartment] ━━━
完美定位到業務場景發生代碼,消費時間,輸入輸出。
簡單支持複雜關係映射查詢
selectUserAndDepartment
===
select * from user where user_id=#userId#
@ orm.single({"departmentId":"id"},"Department");
@ orm.many({"id":"userId"},"user.selectRole","Role");
user.selectRole
===
select r.* from user_role ur left join role r on ur.role_id=r.id
where ur.user_id=#userId#
一個用戶關聯一個部門,關聯多個角色
跨數據平臺
- 內置操作都是跨數據庫平臺,依賴不同的XXDBStyle
- 提供翻頁內置操作,支持不同數據庫
- MarkDown 管理不同數據庫平臺的有差異的SQL
- sql/user.md,
- sql/oracle/user.md
- sql/mysql/user.md
一句話總結其他Dao工具問題
每個Dao工具都有特定使用範圍和歷史背景,沒有最好的工具,只有適合自己的工具
- JPA: 缺少管理複雜SQL能力,OR/Mapping 太強大容易用錯。
- Spring Data: 主要目的是SQL和NOSQL統一api,應用場景較爲簡單。其他缺點同JPA
- MyBatis: 缺少內置功能,XML管理SQL不方便,出錯調試難度大(沒有自己的語法體系),OR/Mapping 功能弱
- MyBatis-Plus: 國內基於Mybatis封裝功能,具備內置功能和Lock,邏輯刪除等方便的功能。缺點同BeetlSQL一樣,都是國內個人維護。
- JOOQ:應用場景較爲簡單,類似BeetlSQL Query功能,實際使用起來比較複雜
- EBean:功能同JPA,比Hiberante弱,比JPA強。缺點同JPA
- Spring-JDBCTemplate: 幾乎沒有提供企業應用需要的任何功能,還需要二次封裝才能使用
總結BeetlSQL
- 混合JPA,MyBatis,JOOQ功能
- 創立Markdown管理複雜SQL
學習曲線
- Hibernate 1個月入門,半年精通
- JPA 一週入門,3個月年精通
- MyBatis 一週入門,一個月精通
- BeetlSQL 3天入門,2周精通