當應用需要支援不同資料庫產商
,並且依賴了不同資料庫特有的函式或者語法時,我們通常需要書寫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不支援的,就更不要說其它的特性了。那麼,如果我們的使用者是未知的,並不知道將來使用這個系統的使用者使用的是什麼...