Solon詳解系列文章:
Solon詳解(一)- 快速入門
Solon詳解(二)- Solon的核心
Solon詳解(三)- Solon的web開發
Solon詳解(四)- Solon的事務傳播機制
Solon詳解(五)- Solon擴充套件機制之Solon Plugin
Solon詳解(六)- Solon的校驗擴充套件框架使用與擴充套件
Solon詳解(七)- Solon Ioc 的註解對比Spring及JSR330
Solon詳解(八)- Solon的快取框架使用和定製
Solon詳解(九)- 渲染控制之定製統一的介面輸出
Solon詳解(十)- 怎麼用 Solon 開發基於 undertow jsp tld 的專案?
Solon詳解(11)- Mybatis 與 Solon 相親相愛
相關的原始碼
https://gitee.com/noear/solon_demo/tree/master/demo08.solon_mybatis_multisource
故事開講
Mybatis 是個資深的前輩,多年來它基本上只和 Spring 的家族企業合作。今天他嘗試和年輕選手Solon組團做業務;Solon 是Java世界裡一個新的極易上手的Web框架(哎,如同十八線的演員,沒人知道的啦。。。但業務活也是一流的)
本次組隊需要完成如下挑戰:
- 簡單的配置
- 多資料來源支援(分割槽模式 和 註解模式)
- 事務支援
- 支援分頁元件(這個,其實破壞了SQL的透明性......但業內很流行)
Action...
一、環境說明
環境 | 版本 |
---|---|
IDEA | 2020.2 |
Maven | 4.0 |
Solon | 1.0.43 |
mybatis-solon-plugin | 1.0.43 |
mybatis-sqlhelper-solon-plugin | 1.0.43 |
Mybatis | 5.3.3 |
JDK | 1.8 |
二、現在程式碼走起
新建個空白的Maven專案:solon_mybatis_multisource
,下面開始操作:
- (一)在
pom.xml
檔案裡新增依賴
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>1.1</version>
<relativePath />
</parent>
<dependencies>
<dependency>
<groupId>org.noear</groupId>
<artifactId>solon-web</artifactId>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>mybatis-solon-plugin</artifactId>
</dependency>
<dependency>
<groupId>org.noear</groupId>
<artifactId>mybatis-sqlhelper-solon-plugin</artifactId>
</dependency>
<!-- 其它依賴參考原始碼,不然佔板面太多了 -->
</dependencies>
- (二)修改屬性檔案
application.yml
(新增多資料來源和分頁元件的配置)
Solon 沒有特定的資料來源配置,所以隨便自己起個頭就可以;配置項與使用的資料來源匹配即可。本例用的是HikariCP
:
#資料庫1的配置
test.db1:
schema: rock
jdbcUrl: jdbc:mysql://localdb:3306/rock?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
driverClassName: com.mysql.cj.jdbc.Driver
username: demo
password: UL0hHlg0Ybq60xyb
#資料庫2的配置(其實我用的是同一個庫)
test.db2:
schema: rock
jdbcUrl: jdbc:mysql://localdb:3306/rock?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
driverClassName: com.mysql.cj.jdbc.Driver
username: demo
password: UL0hHlg0Ybq60xyb
#預設(與資料來源名一一對應)
mybatis.db1:
typeAliases: #支援包名 或 類名(.class 結尾)
- "webapp.model"
mappers: #支援包名 或 類名(.class 結尾)或 xml(.xml結尾)
- "webapp.dso.mapper.AppxMapper.class"
#再定義個新配置(為了體現多資料來源性 - 應該簡單吧?)
mybatis.db2:
typeAliases:
- "webapp.model"
mappers:
- "webapp.dso.mapper.Appx2Mapper.class"
#分頁元件的配置
sqlhelper:
mybatis:
instrumentor:
dialect: "mysql"
cache-instrumented-sql: true
subquery-paging-start-flag: "[PAGING_StART]"
subquery-paging-end-flag: "[PAGING_END]"
pagination:
count: true
default-page-size: 10
use-last-page-if-page-no-out: true
count-suffix: _COUNT
- (三)新增配置器(完成資料來源的構建即可;看上去,極簡潔的。。)
在Solon的適配下,只需要完成資料來源的配置就完事了。其它的,根據配置已自動掃描或處理。
@XConfiguration
public class Config {
//
//資料來源名字與mybatis的配置名要對應上
//
@XBean(value = "db1", typed = true)
public DataSource db1(@XInject("${test.db1}") HikariDataSource ds) {
return ds;
}
@XBean("db2")
public DataSource db2(@XInject("${test.db2}") HikariDataSource ds) {
return ds;
}
}
- (四)新增控制器
關於多資料來源的分包模式示例:
/**
* 分包模式,一開始就被會話工廠mapperScan()並關聯好了
* */
@XMapping("/demo/")
@XController
public class DemoController {
@XInject
AppxMapper appxMapper; //已被db1 mapperScan 了(內部自動處理),可直接注入
@XInject
Appx2Mapper appxMapper2; //已被db2 mapperScan 了(內部自動處理),可直接注入
@XMapping("test")
public AppxModel test(){
return appxMapper.appx_get();
}
@XMapping("test2")
public AppxModel test2(){
return appxMapper2.appx_get2(48);
}
}
關於多資料來源的註解模式示例:
/**
* 註解模式,通過@Db注入,並指定具體的資料來源
*
* @Db 可注入 Mapper, SqlSession, SqlSessionFactory 型別的欄位
* */
@XMapping("/demo2/")
@XController
public class Demo2Controller {
@Db("db1")
AppxMapper appxMapper; //使用@Db 指定會話工廠並注入
@Db("db2")
Appx2Mapper appxMapper2;
@XMapping("test")
public AppxModel test(){
return appxMapper.appx_get();
}
@XMapping("test2")
public AppxModel test2(){
return appxMapper2.appx_get2(48);
}
}
關於事務的示例:(分散式環境下,儘量用訊息代理JDBC事務)
/**
* 事務演示
* */
@XMapping("/tran/")
@XController
public class TranController {
@XInject
AppxMapper appxMapper;
/**
* mybatis-solon-plugin 的事務,由 @XTran 註解發起(更詳細的說明,參考其它文章)
* */
@XTran
@XMapping("test")
public Object test() throws Throwable{
appxMapper.appx_get();
}
}
關於多資料來源事務的示例,需要用到Service層:(分散式環境下,儘量用訊息代理JDBC事務)
/**
* 多資料來源事務演示
* */
@XMapping("/tran2/")
@XController
public class Tran2Controller {
@XInject
AppService appService; //這是定義的Service類,裡面的函式註解了@XTran("db1")
@XInject
App2Service app2Service; //同上
/**
* 這是一個多資料來源的事務組
* */
@XTran
@XMapping("test")
public void test() throws Throwable {
//內部走的是db2的事務
app2Service.add();
//內部走的是db1的事務
appService.add();
}
}
關於分頁的示例:(本案用的是sqlhelper)
@XMapping("/page/")
@XController
public class PageController {
@XInject
AppxMapper appxMapper;
@XMapping("test")
public Object test() throws Throwable{
SqlPaginations.preparePagination(2,2);
return appxMapper.appx_get_page();
}
}
- (五)略過的一些程式碼檔案(直接看開頭的相關原始碼)
故事結尾
加了事務註解後,更加的簡潔優雅了。。。所有組團挑戰全部完成,OY...