既然已經入”坑“mybatis了,你竟然還想著掙脫,我是不會讓你掙脫的~
當然我有一個算是掙脫的辦法。那就是把它學會、理解透。這樣我們也就不用在坑裡一直徘徊,也算得上是一種掙脫吧!
我在上一篇文章(mybatis入“坑”第一步)中對建立一個mybatis專案過程中有過的簡單的解釋,這篇文章對增加mybatis生命週期和更加詳細的配置的說明和解釋以及在配置的可能會遇到的關鍵問題。
一、mybatis作用域與生命週期
如下圖是mybatis簡易的生命週期圖。首先mybatis通過IO流的方式獲取配置檔案mybatis.config.xml的資訊,然後利用SqlSessionFactoryBuilder建立SqlSessionFactory,而SqlSessionFactory是在一個mybatis中是以單例形式存在的,接著利用SqlSessionFactory生產SqlSession,接著利用SqlSession呼叫SQL Mapper去處理具體的業務。
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder的作用就是用來建立SqlSessionFactory的,所以建立完成SqlSessionFactory後便可以將其丟棄,所以SqlSessionFactoryBuilder的作用域最好就是在區域性方法中。當需要它是可以再次重用,但是不要一直保留。
SqlSessionFactory
SqlSessionFactory被建立成功後,你應該保證它在執行期間一直存在,因為每一個業務都需要同樣的SqlSessionFactory去建立SqlSession。因此 SqlSessionFactory 的最佳作用域是應用作用域。也就是要使SqlSessionFactory在每一個mybatis中都是以單例形式存在的。
SqlSession
SqlSession 的例項不是執行緒安全的,是不能被共享的,所以作用域最好是在區域性方法中。同時對於每一次請求SqlSession,返回一個響應後,應該及時關閉它。
Mapper對映器例項
Mapper對映器介面的例項是從 SqlSession 中獲得的,最好將對映器放在方法作用域內,這樣可以更好的管理。Mapper代表的是一個具體的業務處理,所以當處理完該業務時就可以丟棄。Mapper是隨著SqlSession的關閉而消失廢棄的
二、mybatis關鍵配置詳解
properties屬性
properties標籤:可以動態配置屬性。
可以全部在外部進行配置,如下:
<properties resource="db.properties" />
也可以在通過property標籤一部分在外部進行內部配置另一部分在內部進行配置(如下),增加配置的靈活性。
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
當外部的db.properties檔案進行配置之後,在property標籤中又配置一遍後會使用哪一個配置呢?
這就需要考慮優先順序的問題,通過方法引數傳遞的屬性具有最高優先順序,resource/url 屬性中指定的配置檔案次之,最低優先順序的則是 properties 元素中指定的屬性。這裡我們的db.properties檔案時通過resource指定的,所以優先順序大於properties元素指定的屬性。所以優先使用外部的db.properties檔案中的配置。
typeAliases型別別名
配置Mapper.xml的型別別名可以降低書寫冗餘的全限定類名。通過對實體類別名的配置,簡化開發人員的書寫的程式碼量。比如需要書寫com.wkx.pojo.User的全限定類名,在配置別名後便可以僅僅書寫user。
那麼如何去配置型別別名呢?
第一種:通過typeAlias的標籤去配置,這樣需要對每一個實體類進行分別配置。type屬性中為實體類的路徑,alias屬性為別名名稱。
<!--配置別名-->
<typeAliases>
<typeAlias type="com.wkx.pojo.User" alias="user"/>
</typeAliases>
第二種:通過package標籤屬性去配置,name屬性為實體類所在的包路徑。
在無註解的情況下,使用 Bean 的首字母小寫的非限定類名來作為它的別名,比如com.wkx.pojo.User的別名便是user
<!--配置別名-->
<typeAliases>
<package name="com.wkx.pojo"/>
</typeAliases>
在有註解的情況下,使用註釋的別名進行配置。
@Alias("wkx")
public class User {
...
...
}
使用註解後便可以通過註解的內容進行型別配置
<mapper namespace="com.wkx.dao.UserMapper">
<select id="getUser" resultType="wkx">
select * from user
</select>
</mapper>
下面列出關於Java型別內建的型別別名,這裡只列出一部分,其他的型別的別名可以依次類推。比如別名為_double,對映型別為double;別名為double,對應對映型別為Double。
別名 | 對映的型別 |
---|---|
_int | int |
_integer | int |
int | Integer |
integer | Integer |
map | Map |
hashMap | HashMap |
environments環境配置
用於配置資料的環境。可配置多個資料庫環境,但是SqlSessionFactory只能選擇一個去使用。如下:
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
可以在不同的環境下切換不同的資料環境,只需要修改environments標籤中的default屬性對應不同環境下的id屬性,比如development和test不同的環境。
-
事務管理器(transactionManager)
在mybatis中有兩種不同的事務管理器,即type="JDBC"或者type="MANAGED"
JDBC的事務型別是直接使用了 JDBC 的提交和回滾設施,它依賴從資料來源獲得的連線來管理事務作用域。
MANAGED的事務型別配置幾乎沒有做什麼,從不提交或回滾一個連線,而是讓容器來管理事務的整個生命週期。
-
資料來源(dataSource)
主要有三種資料來源型別,即type="[UNPOOLED|POOLED|JNDI]"。
UNPOOLED的資料來源型別是不使用連線池,每次請求時都會開啟和關閉連線,顯然這樣的連線資料來源型別效率不高。
POOLED的資料來源型別是使用連線池的概念,每次請求可以直接從“池”子裡拿出活躍的連線,避免了重複的建立連線,提高效率。
JNDI的資料來源型別實現是為了能讓在 EJB 或應用伺服器這類容器中使用,容器可以集中或在外部配置資料來源,然後放置一個 JNDI 上下文的資料來源引用。
mappers對映器
定義對映的路徑,告訴mybatis去哪裡找對應的語句。我們可以是使用類路徑的資源引用方式(推薦使用):
<!-- 使用相對於類路徑的資源引用 -->
<mappers>
<mapper resource="com/wkx/dao/AuthorMapper.xml"/>
</mappers>
可以通過使用完全限定資源定位符(URL)的方式(方式二):
<!-- 使用完全限定資源定位符(URL) -->
<mappers>
<mapper url="file:///E:/UserMapper.xml"/>
</mappers>
可以通過對映器介面實現類的完全限定類名的方式(方式三):
<!-- 使用對映器介面實現類的完全限定類名 -->
<mappers>
<mapper class="com.wkx.dao.UserMapper"/>
</mappers>
可以包的形式將對映器介面全部註冊為對映器的方式(方式四):
<mappers>
<package name="com.wkx.dao"/>
</mappers>
注意:方式三和方式四使用需要具備兩個條件,一個是介面和Mapper的名稱一致,比如UserMapper.java介面和UserMapper.xml必須都是UserMapper,也就是一致的。另一個是介面和Mapper的包名一致。