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