故事相關的源碼
https://gitee.com/noear/solon_demo/tree/master/demo08.solon_mybatis
故事開講
Solon 是Java世界裏一個新的極易上手的Web框架,像是個清秀的年輕小夥。。。
Mybatis 是個資深的前輩,好像阿里系挺喜歡這前輩,說是喜歡它的SQL透明性(Xml sql 確實有透明性)。
以住的歷史上,Mybatis 基本上是在 Spring 家族合作搞工程的。
今天主要是讓 Mybatis 和 Solon 搭夥過日子試試,看看是不是合得來。
本次搭夥主要有這些挑點:
- 簡單的配置
- 多數據源支持(分區模式 和 註解模式)
- 事務支持(solon 是不支持註解事務的)
- 支持分頁組件(這個,其實破壞了SQL的透明性......但業務很流行)
開始...
一、環境說明
環境 | 版本 |
---|---|
IDEA | 2020.2 |
Maven | 4.0 |
Solon | 1.0.10 |
mybatis-solon-plugin | 1.0.10 (本例用到的關鍵框架) |
mybatis-sqlhelper-solon-plugin | 1.0.10 |
Mybatis | 5.3.3 |
JDK | 1.8 |
二、代碼
新建個空白的Maven項目:solon_mybatis
,下面開始操作:
- (一)在
pom.xml
文件裏添加依賴
<parent>
<groupId>org.noear</groupId>
<artifactId>solon-parent</artifactId>
<version>1.0.10</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:
typeAliases: #支持包名 或 類名(.class 結尾)
- "webapp.model"
mappers: #支持包名 或 類名(.class 結尾)或 xml(.xml結尾)
- "webapp.dso.mapper.AppxMapper.class"
#再定義個新配置(爲了體現多數據源性 - 應該簡單吧?)
mybatis.db2f:
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
- (三)添加配置器(完成會話工廠的構建 及 Mapper 的描述與關聯;看上去,挺簡潔的)
基於 Spring
的@MapperScan實現,需要多個配置器纔可以完成;mybatis-solon-plugin
把它調整爲一個函數,故多個數據源可以整到一個配置器裏:
@XConfiguration
public class Config {
@XBean("db1f")
public SqlSessionFactory db1f(@XInject("${test.db1}") HikariDataSource dataSource) {
//
//可以用默認的配置
//
return new MybatisAdapter(dataSource)
.mapperScan() //完成Spring 的 @MapperScan註解的功能(相對來說,改成函數可以把多個 mapperScan 安排在一個 Config裏)
.getFactory();
}
@XBean("db2f")
public SqlSessionFactory db2f(
@XInject("${test.db2}") HikariDataSource dataSource,
@XInject("${mybatis.db2f}") Properties props) {
//
//可以指定配置 ${mybatis.db2f}
//
return new MybatisAdapter(dataSource, props)
.mapperScan()
.getFactory();
}
}
- (四)添加控制器
關於多數據源的分包模式示例:
/**
* 分包模式,一開始就被會話工廠mapperScan()並關聯好了
* */
@XMapping("/demo/")
@XController
public class DemoController {
@XInject
AppxMapper appxMapper; //已被db1f mapperScan 了,可直接注入
@XInject
Appx2Mapper appxMapper2; //已被db2f mapperScan 了,可直接注入
@XMapping("test")
public AppxModel test(){
return appxMapper.appx_get();
}
@XMapping("test2")
public AppxModel test2(){
return appxMapper2.appx_get2(48);
}
}
關於多數據源的註解模式示例:
/**
* 註解模式,通過@Db注入,並指定具體的會話工廠
*
* @Df 可注入 Mapper, SqlSession, SqlSessionFactory, MybatisProxy
* */
@XMapping("/demo2/")
@XController
public class Demo2Controller {
@Df("db1f")
AppxMapper appxMapper; //使用@Db 指定會話工廠並注入
@Df("db2f")
Appx2Mapper appxMapper2;
@XMapping("test")
public AppxModel test(){
return appxMapper.appx_get();
}
@XMapping("test2")
public AppxModel test2(){
return appxMapper2.appx_get2(48);
}
}
關於事務的示例:(分佈式環境下,儘量用消息代理JDBC事務)
/**
* 事務演示
*
* @Df 可注入 Mapper, SqlSession, SqlSessionFactory, MybatisProxy
* */
@XMapping("/tran/")
@XController
public class TranController {
@XInject
AppxMapper appxMapper;
/**
* mybatis-solon-plugin 的事務,需要通過 MybatisProxy 發起
*
* solon 不目前支持註解事務,說是出於性能和細顆粒度的考慮;以及現在都流行引入消息處理事務了。
* */
@Df("db1f")
MybatisProxy proxy;
@XMapping("test")
public Object test() throws Throwable{
return proxy.tran((s)->{
s.result = appxMapper.appx_get();
});
}
}
關於分頁的示例:(本案用的是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();
}
}
- (五)略過的代碼文件(看開頭的相關源碼)
//這幾個文件不是重點,可以直接看源碼
//Appx2Mapper.java
//AppxMapper.java
//Appx2Mapper.xml
//AppxMapper.xml
這裏只測試了查詢的方法,當然如果需要別的,可以自行添加試試。
故事結尾
所有搭夥挑戰完成,OY...