mybatis 多資料庫支援

2021-10-01 14:47:57 字數 4352 閱讀 9071

當應用需要支援不同資料庫產商,並且依賴了不同資料庫特有的函式或者語法時,我們通常需要書寫2套或以上是sql來支援不同的場景。

獲取列表:oracle 12c後使用listagg(),而mysql使用group_concat()其他場景…

假設沒有標籤的情況下,我們可以如何實現我們的需求?我們用獲取列表的場景來展示:

使用不同的statemetnid區分不用資料庫的sql,缺點是api會十分臃腫

"listaccountwithoracle"

resulttype

="hashmap"

>

select owner, listagg(name, ',') as accounts from account group by owner

select

>

"listaccountwithmysql"

resulttype

="hashmap"

>

select owner, group_concat(name) as accounts from account group by owner

select

>

public

inte***ce

"listaccount"

resulttype

="hashmap"

>

select owner, group_concat(name) as accounts from account group by owner

select

>

"listaccount"

resulttype

="hashmap"

>

select owner, listagg(name, ',') as accounts from account group by owner

select

>

public

inte***ce

>

>

resource

=/>

>

configuration

>

回顧以上2個方案的缺點

因此,使用mybatis提供的可以解決不同資料庫的sql執行。

問題1:如何告訴mybatis,當前執行sql是哪個資料庫產商語法?

聰明的你肯定會想到,能否給statement新增乙個標籤/屬性來指定其所屬於的資料庫語法,答案是肯定的。

mybatis支援給每個statement新增屬性databaseid,關於statement支援的屬性,可以閱讀官方文件有關的這部分描述。

"listaccount"

resulttype

="hashmap"

databaseid

="oracle"

>

select owner, listagg(name, ',') as accounts from account group by owner

select

>

"listaccount"

resulttype

="hashmap"

databaseid

="mysql"

>

select owner, group_concat(name) as accounts from account group by owner

select

>

問題2:隨之產生的疑問:mybatis怎麼知道databaseid="oracle"是使用oracle資料庫呢?畢竟這只是乙個字串值。

mybatis是不允許使用相同的statementid的,對於上面提供的語句,使用的卻是相同的id,只是databaseid不一樣。難道是mybatis是組合多種屬性來區分的?no,答案是否定的。

mybatis會在啟動的時候解析標籤,獲取支援的資料庫產品。

>

type

="db_vendor"

>

name

="oracle"

value

="oracle"

/>

name

="mysql"

value

="mysql"

/>

databaseidprovider

>

configuration

>

mybatis啟動的時候,會偵測當前使用的資料庫,如果是oracle(name=「oracle」)的話,對於擁有相同statementid的語句,則會選擇執行帶有databaseid="oracle"的語句。

問題3:如果細心你的閱讀到這裡,肯定會發現乙個問題,上述name=「oracle」,其中oracle也是乙個字串,如果我要支援postgresql,這個字串值我應該如何定?遺憾的是這些字串值並不是定義在mybatis的源**中的,請往下看。

/**

* retrieves the name of this database product.

* * @return database product name

* @exception sqlexception if a database access error occurs

*/string getdatabaseproductname()

throws sqlexception;

該方法會返回當前資料庫的產品名字,所以mybatis會用這個名字來匹配在標籤中配置的名字(name屬性),進一步確定哪些statement會生效。大家可以寫一段簡單的jdbc連線,然後呼叫該介面方法來確定具體的名字,如下:

// 省略非關鍵**

connection conn = drivermanager.

getconnection()

;databasemetadata metadata = conn.

getmetadata()

;

string productname = metadata.

getdatabaseproductname()

;

public

inte***ce

"listaccount"

resulttype

="hashmap"

databaseid

="oracle"

>

select owner, listagg(name, ',') as accounts from account group by owner

select

>

"listaccount"

resulttype

="hashmap"

databaseid

="mysql"

>

select owner, group_concat(name) as accounts from account group by owner

select

>

>

type

="db_vendor"

>

name

="oracle"

value

="oracle"

/>

name

="mysql"

value

="mysql"

/>

databaseidprovider

>

configuration

>

專案支援多資料庫

基本與jdbc連線資料庫的 差不多,要支援多資料庫,最關鍵的是分頁的語句。解決思路 編寫乙個統一處理sql的方法,接收業務sql,根據不同的資料庫型別,返回最終處理好的分頁sql。repository public class basedao return ret 參考文件 mybatis 16my...

Mybatis多資料庫環境切換

可以配置多個enviroment,根據id區分 配置default選擇環境 控制某個sql標籤只在指定資料庫環境中使用的方法 首先在mybatis配置檔案中新增自己需要的資料庫環境 然後在對映檔案中的標籤中設定databaseid,可以指定當前標籤只會在mysql環境中使用 在spring中如何配置...

使用反射實現多資料庫的支援

現今資料庫行業中可供選擇的資料庫有很多,oracle,sql,access等等,而且不同的資料庫又有不同的標準,即使同樣由微軟推出的sql和access也有一些語句是sql支援而access不支援的,就更不要說其它的特性了。那麼,如果我們的使用者是未知的,並不知道將來使用這個系統的使用者使用的是什麼...