Mybatis 和 Solon 勾搭在一起,也是個漂亮組合

故事相關的源碼

https://gitee.com/noear/solon_demo/tree/master/demo08.solon_mybatis

故事開講

Solon 是Java世界裏一個新的極易上手的Web框架,像是個清秀的年輕小夥。。。

Mybatis 是個資深的前輩,好像阿里系挺喜歡這前輩,說是喜歡它的SQL透明性(Xml sql 確實有透明性)。

以住的歷史上,Mybatis 基本上是在 Spring 家族合作搞工程的。

今天主要是讓 Mybatis 和 Solon 搭夥過日子試試,看看是不是合得來。

本次搭夥主要有這些挑點:

  1. 簡單的配置
  2. 多數據源支持(分區模式 和 註解模式)
  3. 事務支持(solon 是不支持註解事務的)
  4. 支持分頁組件(這個,其實破壞了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...

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章