前言:
在工作中項目提了個動態切換多數據庫的需求(具體需求見文章末尾),爬了N多的博客文章總結了大概有以下幾種方法:
1、用springboot的AOP進行切面處理配置datasource(service層),然後進行mybaties的配置;(優點:實現難度低。缺點:操作粒度大,難以在一個service的方法中進行數據庫切換)
2、同樣是使用springboot的AOP進行切面編程,但是是對mapper接口進行切面,這需要對mapper進行包裝,接口不能被AOP切面;(優點:實現難度低,同時又可以進行mapper級別細粒度的數據庫切換。缺點:每寫一個mapper接口,要進行相應的寫一個實現類進行靜態代理)
3、深入改造mybties的excuctor(寫一個myExcutor),在myexcuctor的生成connection的時候進行改變datasouce。實現大概的思路:對mapper接口進行註解,在myexcuctor中獲取ms(mapper statement)對象的屬性Id(mapper.xml的namespace+id),然後利用反射進行獲取對應的mapper接口上的註解值(加上前端傳過來的值拼接mysql的url)生成datasource,然後進行數據庫操作。(優點:一次編寫,以後開發業務可不用再去處理數據庫切換問題,實現mapper級別的數據庫切換。缺點:技術難度高)
4、開發mybaties插件,對excuctor對象進行攔截處理,和3的方法差不多。
以上實現方法會在該系列文章結束時給出。
重點:也是應爲該次的項目需求,才又這一系列的學習探索之路。將這些探索的過程記錄下來,分享一下。才疏學淺,班門弄斧,望各位大佬指導指導。
一、 手動配置Mybaties,引進mybaties.jar包
1、idea中建maven工程,在pom中引入mybaties依賴,如下圖:
同時引入mysql-jdbc、junit、lombok,全部pom的內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:mybaties//maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>MyBatiesDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
2、從XML中構建SqlSessionFactory
2.1、瞭解mybaties的基本結構
基於SqlMapConfig.xml (Mybaties配置文件), SqlSessionFactory創建SqlSession(對外提供數據庫操作接口),SqlSession操作Executor進行數據庫操作,Executor對象中操作數據庫的sql語句爲Mapped statement 處理(動態代理)mapper.xml轉化而來方法,查詢後封裝數據返回。其底層核心爲jdbc中內容,在jdbc之上對SQL進行進行xml化,讀取xml中的內容與對應的接口進行動態代理,用代理的方法放到jdbc中,查詢的結果進行封裝。而這其中增加了緩存等一些配置處理,這就是mybaties的本質。不熟悉後者忘記jdbc的內容可以看以下代碼:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DbUtil {
public static final String URL = "jdbc:mysql://localhost:3306/imooc";
public static final String USER = "xiong";
public static final String PASSWORD = "123456";
public static void main(String[] args) throws Exception {
//1.加載驅動程序
Class.forName("com.mysql.jdbc.Driver");
//2. 獲得數據庫連接
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
//3.操作數據庫,實現增刪改查
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT user_name, age FROM imooc_goddess");
//如果有數據,rs.next()返回true
while(rs.next()){
System.out.println(rs.getString("user_name")+" 年齡:"+rs.getInt("age"));
}
}
}
2.2、構建SqlSessionFactory
每個基於 MyBatis 的應用都是以一個 SqlSessionFactory 的實例爲核心的。SqlSessionFactory 的實例可以通過 SqlSessionFactoryBuilder 獲得。而 SqlSessionFactoryBuilder 則可以從 XML 配置文件或一個預先配置的 Configuration 實例來構建出 SqlSessionFactory 實例。
從 XML 文件中構建 SqlSessionFactory 的實例非常簡單,建議使用類路徑下的資源文件進行配置。 但也可以使用任意的輸入流(InputStream)實例,比如用文件路徑字符串或 file:// URL 構造的輸入流。MyBatis 包含一個名叫 Resources 的工具類,它包含一些實用方法,使得從類路徑或其它位置加載資源文件更加容易。
夜深人靜,該睡覺了!
------見Mybaties學習之路二
項目需求:編寫一個軟件級別的平臺,要求進行租戶數據隔離,而且業務中每個模塊的數據也進行隔離。所以有N+M的數據庫隔離。
即所謂的SaaS平臺,具體概念如下(百度):
SaaS即Software-as-a-Service(軟件即服務)是隨着互聯網技術的發展和應用軟件的成熟, 在21世紀開始興起的一種完全創新的軟件應用模式。傳統模式下,廠商通過License將軟件產品部署到企業內部多個客戶終端實現交付。SaaS定義了一種新的交付方式,也使得軟件進一步迴歸服務本質。企業部署信息化軟件的本質是爲了自身的運營管理服務,軟件的表象是一種業務流程的信息化,本質還是第一種服務模式,SaaS改變了傳統軟件服務的提供方式,減少本地部署所需的大量前期投入,進一步突出信息化軟件的服務屬性,或成爲未來信息化軟件市場的主流交付模式。