HasorDB 架構(gòu)設(shè)計(jì)

2021-12-29 11:29 更新

HasorDB 架構(gòu)在整體上體系化,局部層面各個(gè)模塊遵循獨(dú)立原則。因此每一個(gè)模塊幾乎都可以獨(dú)立使用而且互不影響。

在整體系統(tǒng)上自低向上可以分為兩層,低層是公共組件模塊。頂層是三個(gè)不同的使用模式。

+-------------------------------------------------------+-------+
|                   SQL & CRUD & Mapper                 |       |
+-----------+-------------+---------------+-------------+ Utils |
|   Types   |   Mapping   | Resource & TX |   Dialect   |       |
+-----------+-------------+---------------+-------------+-------+

公共模塊?

Types 模塊?

主要是指 ?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?

Mapping 模塊

主要是指 ?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è)注解的解析器。

Resource & TX 模塊

主要是指 ?net.hasor.db.transaction? 軟件包,它負(fù)責(zé)提供本地資源管理以及事務(wù)控制。具體可參考 資源與事務(wù)

該模塊主要分為兩個(gè)部分:

數(shù)據(jù)源管理

  • 這部分核心接口有 ?DataSourceManager?、?ConnectionHolder?
  • 前者提供 本地同步 的實(shí)現(xiàn),后者負(fù)責(zé)連接復(fù)用。

事務(wù)管理器

  • 這部分核心接口有 ?TransactionTemplate?、?TransactionManager?、?TransactionStatus ?三個(gè)。
  • 其中前兩個(gè)分別是操作數(shù)據(jù)庫(kù)事務(wù)的兩個(gè)方式,后一個(gè)接口用來(lái)表示一個(gè)具體的事務(wù)。

Dialect 模塊

主要是指 ?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。

SQL 模式

主要是指? 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 模塊
  • 可以處理多語(yǔ)句查詢(xún)并且獲取多語(yǔ)句的執(zhí)行結(jié)果。

而 Spring JDBC 只有在最新的 Spring Data 中才對(duì)上面第二點(diǎn)有所支持。

CRUD 模式

主要是指 ?net.hasor.db.lambda? 軟件包,CRUD 模式 中實(shí)踐了 ActiveRecord 思想,主打單表操作。

這一模式下 ?LambdaTemplate ?成為入口類(lèi),通過(guò)它可以創(chuàng)建下面四個(gè)特殊化的接口來(lái)生成不同類(lèi)別的 SQL 語(yǔ)句。

  • LambdaDelete 負(fù)責(zé)生成和執(zhí)行 ?delete ?語(yǔ)句
  • LambdaInsert 負(fù)責(zé)生成和執(zhí)行 ?insert ?語(yǔ)句
  • LambdaQuery 負(fù)責(zé)生成和執(zhí)行單表的 ?select ?語(yǔ)句
  • LambdaUpdate 負(fù)責(zé)生成和執(zhí)行 ?update ?語(yǔ)句

從 API 設(shè)計(jì)上 HasorDB 參考了下列兩個(gè)框架的 API 風(fēng)格,因此會(huì)有不少熟悉的味道。

  • ?BeetlSql ?的 Query
  • ?MyBatis Plus? 的條件構(gòu)造器

在 CRUD 層面開(kāi)始支持分頁(yè)操作,這一邏輯在下面這個(gè)方法中實(shí)現(xiàn)。

  • 類(lèi) ?net.hasor.db.lambda.core.AbstractQueryExecute? 的 ?getBoundSql ?方法

Mapper 模式

主要是指? 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á)式體系

?${...}?、?@{...}?、?#{...}? 三種表達(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}


以上內(nèi)容是否對(duì)您有幫助:
在線(xiàn)筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)