朋友開發的開源項目,喜歡的話去https://github.com/braisdom/ObjectiveSql 點個star
項目介紹
ObjectiveSQL 是一個Java ORM 框架,以ActiveRecord 模式基礎,結合JSR 269 API 實現數據庫訪問Java 代碼的動態生成,從而提高生產效率,主要特性包括:
- 動態生成數據模型訪問數據庫的 JAVA API 代碼,其中包括數據庫訪問的SELECT、INSERT、UPDATE 和DELETE
- 根據Relation 注解的定義,在查詢時自動填充關聯對象,同時也避免N+1 查詢問題
- 提供多種方式構造數據模型,主要以Java Bean PropertyDescriptor 形式,也支持Map 形式綁定屬性
- 多數據源支持,只需在DomainModel 中指定數據模型所屬的數據源
- 事務支持,只需要在模型方法中指定Transaction 注解,系統自動生成數據為事務代碼
- 靈活擴展,系統針對業務領域中可能遇見的擴展點提供Interface 和注入接口,主要包括:JDBC 執行器、數據類型轉換、SQL 查詢、SQL 持久化等
- 面向對象SQL(開發中,預計在1.4.0 版本發布)

- ObjectiveSQL 集成了Apache Dbutils 實現基礎ORM 特性,包括:SQL 的執行、數據模型與Table Row 之間的相互轉換、以及基礎的JDBC 特性。Apache Dbutils 只提供了能用的ORM 特性,缺少關聯關系,並且與應用系統之間的結合相對不夠友好,本質上是一個高度抽象、且靈活的技術框架。
- Transition 層,也是一般ORM 框架中必備的一個特性,主要用於數據模型與數據庫之間的數據轉換,它有兩個擴展方法:rising 用於將數據庫的數據轉換為Java 類型的數據,sinking 用於將Java 類型的數據轉換為數據庫類型的數據,由於不同數據庫類型也可能出現不一樣的轉換方法,DateTime 是很多數據庫的轉換方式都不一樣,所以Transition 也是高度被擴展的接口,Transition 會作為一個擴展點注入Apache Dbutils。
- API 層,是以面向對象的方式封裝高度抽象的數據庫訪問API,主要為DomainModel 生成的具體API 服務,應用系統也可以結合 Query 和Persistence 兩個接口封裝出符合業務特性的API。
- DomainModel 是對業務系統邏輯的抽象和封裝,而業務邏輯中會涉及大量數據庫的讀寫,在ObjectiveSQL 框架下,不再需要顯式的編寫相應的數據讀寫邏輯,只關注真實的業務邏輯即可。
快速開始
本文檔主要介紹:如何通過ObjectiveSQL 結合 SpringBoot 實現MySQL 數據庫的增、刪、改和查,以及關聯關系的查詢。通過示例,你可以看出ObjectiveSQL 如何通過極少的編碼,就可以實現數據庫訪問。項目完整代碼請參考:SpringBootExample。
- 1 ObjectiveSQL 依賴安裝(Maven & Gradle)
- 2 IntelliJ 插件安裝
- 3 Annotation Processor 設置
- 4 數據庫腳本
- 5 定義領域模型
- 6 使用實踐
- 7 小結
1 ObjectiveSQL 依賴安裝(Maven & Gradle)
<dependencies>
<dependency>
<groupId>com.github.braisdom</groupId>
<artifactId>objective-sql</artifactId>
<version>1.3.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>8</source>
<target>8</target>
<encoding>UTF-8</encoding>
<compilerArgs>
<arg>-Xplugin:Manifold</arg>
</compilerArgs>
<annotationProcessorPaths>
<path>
<groupId>systems.manifold</groupId>
<artifactId>manifold-ext</artifactId>
<version>2020.1.27</version>
</path>
<path>
<groupId>com.github.braisdom</groupId>
<artifactId>objective-sql</artifactId>
<version>1.3.6</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
compile group: 'com.github.braisdom', name: 'objective-sql', version: '1.3.6'
點擊“Maven 倉庫”可以找到最新版本和其它的依賴方式配置,目前最新版本為: 1.3.6
2 IntelliJ 插件安裝
- MAC 操作系統
- Preferences >> Plugins >> Marketplace >> 搜索 “ObjectiveSql” >> 安裝
- Windows 操作系統
- File >> Settings >> Plugins >> Marketplace >> 搜索 “ObjectiveSql“>> 安裝
3 Annotation Processor 設置
Settings/Preferences >> Annotation Processor >> 選擇項目后,勾選 “Enable annotation processing”
4 數據庫腳本
CREATE DATABASE IF NOT EXISTS `objective_sql` CHARACTER SET utf8 COLLATE utf8_general_ci;
CREATE TABLE IF NOT EXISTS `objective_sql`.`members`(
`id` INT UNSIGNED AUTO_INCREMENT,
`no` VARCHAR(100),
`name` VARCHAR(100),
`gender` INT(2),
`mobile` VARCHAR(11),
`other_info` VARCHAR(512),
`registered_at` DATETIME,
`updated_at` DATETIME,
PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
5 定義領域模型
@DomainModel
public class Member {
private String no;
private String name;
private Integer gender;
private String mobile;
}
所謂領域模型,基實就是Java 中是一個定義基礎數據結構的 Class,而在數據庫領域是一張表的結構定義(也稱為Schema),一行數據對應Class 的一個實例。以面向對象設計理論的基礎去理解,對數據庫表的查詢、更新、修改和刪除應當以靜態行為的形式體現在該模型中。
6 使用實踐
結合SpringBoot 我們提供了一份完整的使用示例,覆蓋了常用場景,完整代碼請參考:MembersController.java
6.1 創建會員
@PostMapping("/members")
public ResponseObject create(@RequestBody RequestObject rawMember) throws SQLException {
Member dirtyMember = Member.newInstanceFrom(rawMember, false);
Member member = Member.create(dirtyMember, true);
return ResponseObject.createSuccessResponse(member);
}
6.2 根據會員號查詢單個會員
// Querying a member by member no
@GetMapping("/members/{no}")
public ResponseObject getMember(@PathVariable("no") String memberNo) throws SQLException {
Member member = Member.queryByNo(memberNo);
return ResponseObject.createSuccessResponse(member);
}
6.3 查詢所有會員
// Querying all members
@GetMapping("/members")
public ResponseObject getMembers() throws SQLException {
List<Member> members = Member.queryAll();
return ResponseObject.createSuccessResponse(members);
}
6.4 根據會員號更新會員
// Updating a member with member no
@PutMapping("/members/{no}")
public ResponseObject updateMember(@PathVariable("no") String memberNo,
@RequestBody RequestObject rawMember) throws SQLException {
Member member = Member.queryByNo(memberNo);
Member.update(member.getId(), Member.newInstanceFrom(rawMember), true);
return ResponseObject.createSuccessResponse();
}
6.5 根據會員號刪除會員
// Deleting a member with member no
@DeleteMapping("/members/{no}")
public ResponseObject deleteMember(@PathVariable("no") String memberNo) throws SQLException {
int deleteCount = Member.destroy("member_no = ?", memberNo);
return ResponseObject.createSuccessResponse(deleteCount);
}
7 小結
通過上述示例,應用系統可以以極簡單代碼,實現對數據庫的存儲和查詢,從而將設計和編碼的重心轉移到應用系統本身,ObjectiveSql 提供了豐富的API和擴展接口,最大限度的滿足應用系統的實際需求,當前只展示示例僅僅是冰山一角,詳細內容請看后續。
IntelliJ IDEA 插件安裝
由於數據庫訪問Java API 是由ObjectiveSQL 在編譯期間生成,在IntelliJ IDEA 在編碼過程中無法識別生成的方法或屬性,ObjectiveSQL 提供了IntelliJ IDEA 插件,用於解決編碼過程中的編譯錯誤和動態代碼提示。
1 應用市場安裝

進入IntelliJ IDEA 的 Preference 對話框后,以“ObjectiveSQL” 關鍵字進行搜索,並點擊安裝
2 本地安裝最新版本
由於IntelliJ IDEA 插件倉庫審核需要一定時間,針對一些Bug 的緊急修復會臨時發布最新版本供用戶下載,可以按下列方式,從本地安裝ObjectiveSQL 插件。

下載完成后,進行Preference -> Plugins 選項中點擊 Install Plugin From Disk… 菜單,選中下載的 .zip 文件,即可完成安裝
名稱映射規則
Class 名稱與Table 名稱、字段名稱與Column 名稱的缺省映射規則是一個開發團隊成熟的重要標志,團隊成員遵循統一的規則降低了溝通成本,並且也減少了開發過程中出錯的機率,與敏捷開發中的隱喻也是有着異曲同工的作用。
Java 的開發體系中一直強調“擴展性”,認為技術型框架中存在的強制遵循的規則,阻礙了系統的可擴展性,卻不知,固化一些已經約定俗成的規則,是系統開發中效率的關鍵,就像人類社會發展了數千年,除了法律的約束外,更多的是民間存在的習俗,有了這些被人所認可的習俗,人與人之間才能夠形成有效的生產力。
規則會迭代和變化,這並不意味着規則不重要,很多人會挑戰規則的內容和形成過程,但挑戰的結果就是:又形成了一套新的規則。
1 類與字段命名規則
缺省情況下,類名遵循Java 的規范,以駝峰的單數形式命名,而表名則以下划線 “” 分隔單詞的復數形式命名,Java 字段以駝峰形式命名,而數據庫表Column名稱以下划線“” 分隔單詞,具體示例如下:
| Java 類名 | 數據庫表名 |
|---|---|
Article |
articles |
LineItem |
line_items |
Deer |
deers |
Mouse |
mice |
Person |
people |
| Java 字段名稱 | 數據庫 Column 名稱 |
|---|---|
name |
name |
restisterAt |
restister_at |
2 關聯對象名稱約束

ObjectiveSQL 定義的關聯關系主要包括三種:HAS_ONE,HAS_MANY,和BELONGS_TO,其中HAS_MANY 為復雜形式,其它均為單數形式,其它命名規則如下:
- HAS_MANY 時,主表中用於承載關聯對象的字段以駝峰形式的復數命名
- HAS_ONE 時,主表中用於承載關聯對象的字段以駝峰形式的單數命名
- BELONGS_TO 時,從表中用於承載關聯對象的字段以駝峰形式的單數命名
- 其它用於映射數據庫字段的命名規則遵循普通字段命名規則
