HasorDB 架構(gòu)在整體上體系化,局部層面各個模塊遵循獨(dú)立原則。因此每一個模塊幾乎都可以獨(dú)立使用而且互不影響。
在整體系統(tǒng)上自低向上可以分為兩層,低層是公共組件模塊。頂層是三個不同的使用模式。
+-------------------------------------------------------+-------+
| SQL & CRUD & Mapper | |
+-----------+-------------+---------------+-------------+ Utils |
| Types | Mapping | Resource & TX | Dialect | |
+-----------+-------------+---------------+-------------+-------+
主要是指 ?net.hasor.db.types
? 軟件包。該軟件包以 ?net.hasor.db.types.TypeHandler
? 接口為中心,提供不同類型數(shù)據(jù)的寫入和讀取支持。
由于 ?TypeHandler
?接口來自于 MyBatis,因此 Types 模塊中的代碼有相當(dāng)一部分 ?TypeHandler
?的實現(xiàn)是直接從 MyBatis 移植過來。具體是 ?org.apache.ibatis.type
? 包中的部分內(nèi)容。
類 ?TypeHandlerRegistry
?的作用是負(fù)責(zé)注冊和管理 HasorDB 中的 ?TypeHandler
?,并且實現(xiàn)了 類型 中描述的查找優(yōu)先級。
此外 Types 還提供了下面四個注解的支持,具體用法請查閱 自定義類型處理器
@MappedCross
?、?@MappedCrossGroup
?、?@MappedJavaTypes
?、?@MappedJdbcTypes
?主要是指 ?net.hasor.db.mapping
?軟件包。該軟件包通過 ?@Table
?、?@Column
?、?@Ignore
?三個注解,提供簡單的 ORM 注解化映射。 并為 HasorDB 的 對象映射 機(jī)制提供實現(xiàn)。
?TableReader
?接口是該模塊的一個能力接口,它提供了 ?extractData
?和 ?extractRow
?兩個方法,可以用于根據(jù)映射信息讀取 ?ResultSet
?中的內(nèi)容。
而 ?TableMappingResolve
?接口則是一個 ?TableMapping
?解析器,包內(nèi)有一個 ?ClassTableMappingResolve
?實現(xiàn)類。 而它就是負(fù)責(zé)解析 ?@Table
?、?@Column
?、?@Ignore
? 三個注解的解析器。
主要是指 ?net.hasor.db.transaction
? 軟件包,它負(fù)責(zé)提供本地資源管理以及事務(wù)控制。具體可參考 資源與事務(wù)
該模塊主要分為兩個部分:
數(shù)據(jù)源管理
DataSourceManager
?、?ConnectionHolder
?事務(wù)管理器
TransactionTemplate
?、?TransactionManager
?、?TransactionStatus
?三個。主要是指 ?net.hasor.db.dialect
?軟件包,它負(fù)責(zé)提供不同數(shù)據(jù)庫的方言實現(xiàn)。具體可參考 分頁與方言
方言體系中一共有兩個主要的概念:?BoundSql
?、?SqlDialect
?,前者是對要執(zhí)行的 SQL與其參數(shù)的封裝后者是方言。
方言接口 ?SqlDialect
?有三個子接口分別提供了三個場景的方言方法。
ConditionSqlDialect
?條件方言,目前主要是對 like 語句進(jìn)行生成,例如:?concat('%', ? )
?InsertSqlDialect
?Insert語句方言,這個方言接口為 CRUD 模式中的 沖突策略 提供方言實現(xiàn)PageSqlDialect
?這個是分頁方言,它提供了 ?countSql
?、?pageSql
?兩個方法用于分頁語句生成HasorDB 一共提供三種數(shù)據(jù)庫操作模式,你可以在同一個項目中按照不同需要同時或者部分使用這些不同模式的 API。
主要是指? net.hasor.db.jdbc
?軟件包,SQL 模式 是 HasorDB 三大使用模式中 API 最低級別的 API。 在這個模式中開發(fā)者需要完全自己編寫 SQL 語句,并且 SQL 語句的處理需要代碼介入,這種模式對于高度定制化 SQL 將會十分友好。 比如根據(jù)某種特定場景下的通用規(guī)則來生成 SQL 語句。
這一模式下主要入口 API 為 ?JdbcTemplate
?類,該類和 Spring 的 JdbcTemplate 類同名實現(xiàn)思路也完全相同。其 API 接口中的方法大多也是從 Spring 中移植過來的。 熟知的 ?RowMapper
?、?ConnectionCallback
?、?ResultSetExtractor
?接口在 HasorDB 中也同樣存在,因此可以簡單的把它和
Spring JDBC 化作等號。
?JdbcTemplate
?架構(gòu)比 Spring 更加優(yōu)越的地方在于下面三點:
ResultSet
?數(shù)據(jù)時會使用 Types 模塊
queryForList(String,Class<?>)
? 這種方法返回一個 Bean 列表的時候會使用 Mapping 模塊
而 Spring JDBC 只有在最新的 Spring Data 中才對上面第二點有所支持。
主要是指 ?net.hasor.db.lambda
? 軟件包,CRUD 模式 中實踐了 ActiveRecord 思想,主打單表操作。
這一模式下 ?LambdaTemplate
?成為入口類,通過它可以創(chuàng)建下面四個特殊化的接口來生成不同類別的 SQL 語句。
delete
?語句insert
?語句select
?語句update
?語句從 API 設(shè)計上 HasorDB 參考了下列兩個框架的 API 風(fēng)格,因此會有不少熟悉的味道。
BeetlSql
?的 QueryMyBatis Plus
? 的條件構(gòu)造器在 CRUD 層面開始支持分頁操作,這一邏輯在下面這個方法中實現(xiàn)。
net.hasor.db.lambda.core.AbstractQueryExecute
? 的 ?getBoundSql
?方法主要是指? net.hasor.db.dal
? 軟件包,Mapper 模式 對 MyBatis 的 Mapper 映射文件有著高度的兼容。 這主要體現(xiàn)在 動態(tài) SQL 因此,如果單獨(dú)從這個維度上來講,可以說
HasorDB 是一個翻版的 MyBatis。
從架構(gòu)上來講這一部分可以分為 四個小的組成部分
dynamic
? 提供動態(tài)生成 SQL 的框架支持,包括了 HasorDB 獨(dú)特的規(guī)則機(jī)制。execute
?動態(tài) SQL 的執(zhí)行引擎,支持 ?CallableStatement
?、?PreparedStatement
?、?Statement
?repository
?負(fù)責(zé)解析 mapper 文件使其變成 dynamic 模型,同時它也為 注解化 Mapper 提供實現(xiàn)session
?是個入口,熟知的 DalSession 類就是由它提供。另外 BaseMapper 也是由它提供。dynamic 模型
模型的抽象接口是 ?DynamicSql
?,它具有多個子類和實現(xiàn)類用以表達(dá)動態(tài) SQL 的邏輯關(guān)系。這些模型位于? net.hasor.db.dal.dynamic.nodes
? 包中。
?${...}
?、?@{...}
?、?#{...}
? 三種表達(dá)式的提取是通過 ?net.hasor.db.dal.dynamic.tokens
?實現(xiàn)。 原始代碼來自于 MyBatis 同名類,HasorDB 擴(kuò)展了它的 openToken 可以支持更多的前綴。
?@{...}
?、?#{...}
?兩個表達(dá)式被歸入 規(guī)則 體系,一個規(guī)則需要實現(xiàn) ?SqlBuildRule
?接口。 HasorDB 中所有內(nèi)置規(guī)則都位于 ?net.hasor.db.dal.dynamic.rule
? 軟件包,規(guī)則類似于一個函數(shù)。允許自定義動態(tài) SQL 生成的能力。
?#{...}
? 寫法實際上是 ?arg
?規(guī)則的簡寫,?arg
?規(guī)則的源碼是 ?net.hasor.db.dal.dynamic.rule.ArgRule
?
規(guī)則雖然有固定的三段式格式 ?@{<規(guī)則名> [, <啟用條件OGNL> [, 規(guī)則內(nèi)容 ]])
?但除了規(guī)則名之外,其余部分都可以拿來自由發(fā)揮。 比如 快速條件拼接 就是將啟用條件那一段作為規(guī)則實際的內(nèi)容。
快速條件拼接,舉一個例子就是有意的將下列 動態(tài) SQL 寫法改為表達(dá)式寫法。將 XML 在有限范圍內(nèi)化作表達(dá)式還要感謝? sqltoy-orm
?框架的啟發(fā)。
<if test="age != null">
and age = #{age}
</if>
快速條件拼接寫法
@{and, age = :age}
更多建議: