Mybatis學習筆記-核心配置檔案概述
- properties
Mybatis核心配置檔案包含了資料庫連線的核心配置和mybatis框架的基礎配置,是mybatis的核心描述檔案。
下面逐一介紹該配置檔案中的常用配置。
1.properties標籤
該標籤常用於定義mybatis環境的常量值,例如資料庫連線的url,username,password等。
1)在標籤中指定key和value
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="zhangdd" />
<property name="password" value="zd1991.." />
</properties>
然後在當前配置檔案中的其他位置就可以利用key來引用對應的值。
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
2)引用外部popoerties檔案到標籤中
當不想在配置檔案內部定義資料時,也可以用該標籤引用一個外部的properties檔案,mybatis會自動讀取該檔案中的內容並放入配置檔案的全域性範圍。
dbConfig.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
username=zhangdd
password=zd1991..
在配置檔案中就可以像這樣來引用該properties檔案:
<properties resource="dbConfig.properties"/>
獲取其中的值的方式同上:
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
3)載入順序
當properties檔案,properties標籤和Java程式碼中都存在相同的可以時,mybatis是按照一定的載入順序去載入這些資料,並最後被載入的回覆蓋先載入的資料。
載入順序為:
(1)類路徑下的properties檔案。
(2)配置檔案中的properties標籤。
(3)java程式碼中的Properties物件。
2.settings
settings標籤用於對mybatis執行時環境的一些重要引數的設定,利用該標籤可以設定以下引數:
1)cacheEnabled 開啟或禁用二級快取
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
mybatis二級快取被啟用後,客戶端就可以在sqlMapper中對具體的快取產品,引數設定及具體的使用方式進行設定。預設情況下二級快取是開啟狀態。
2)lazyLoadingEnabled 全域性啟用或禁用延時載入。
<setting name="lazyLoadingEnabled" value="true"/>
預設情況下開啟全域性延時載入。
3)aggressiveLazyLoading 當啟用時, 有延遲載入屬性的物件在被 呼叫時將會完全載入任意屬性。否則, 每種屬性將會按需要載入。
<setting name="multipleResultSetsEnabled" value="true"/>
預設為開啟狀態。
4)multipleResultSetsEnabled 允許或不允許多種結果集從一個單獨 的語句中返回(需要適合的驅動)
<setting name="multipleResultSetsEnabled" value="true"/>
預設為允許。
5)useColumnLabel 使用列標籤代替列名。 不同的驅動在這 方便表現不同。 參考驅動文件或充分測 試兩種方法來決定所使用的驅動。
<setting name="useColumnLabel" value="true"/>
預設值為true。
6)useGeneratedKeys 允許 JDBC 支援生成的鍵。 需要適合的 驅動。 如果設定為 true 則這個設定強制 生成的鍵被使用, 儘管一些驅動拒絕兼 容但仍然有效(比如 Derby)
<setting name="useGeneratedKeys" value="false"/>
預設值為false。
7)autoMappingBehavior 指定 MyBatis 如何自動對映列到欄位/ 屬性。PARTIAL 只會自動對映簡單, 沒有巢狀的結果。FULL 會自動對映任 意複雜的結果(巢狀的或其他情況)
<setting name="autoMappingBehavior" value="PARTIAL"/>
型別包括:NONE, PARTIAL, FULL
預設為PARTIAL
8)defaultExecutorType 配置預設的執行器。SIMPLE 執行器沒 有什麼特別之處。REUSE 執行器重用 預處理語句。BATCH 執行器重用語句 和批量更新 .
<setting name="defaultExecutorType" value="SIMPLE"/>
型別包括:SIMPLE REUSE BATCH
預設為SIMPLE
9)defaultStatementTimeout 設定超時時間, 它決定驅動等待一個數 據庫響應的時間
<setting name="defaultStatementTimeout" value="25"/>
預設沒有設定。
3.typeAliases
類型別名,在mybatis的配置檔案中通常需要制定某個型別的全名,方便起見,利用該標籤可以配置某一型別的別名。
<typeAliases>
<typeAlias type="com.mybatis.test.entity.Pet" alias="Pet"/>
<typeAlias type="com.mybatis.test.entity.Department" alias="Department"/>
<typeAlias type="com.mybatis.test.entity.Employee" alias="Employee"/>
<typeAlias type="com.mybatis.test.handler.MyTypeHandler" alias="MyTypeHandler"/>
</typeAliases>
這樣在SqlMapper.xml中引用型別的時候就可以使用型別的別名。
<!-- resultMap : POJO與資料庫表字段對映 -->
<resultMap type="Pet" id="petMap">
...
也可以用mybatis提供的註解來為某個類制定別名:
@Alias("Pet")
public class Pet implements Serializable{
...
..
mybatis中提供了豐富的基本資料型別和常用的引用資料型別、集合等對應的別名,方便開發者描述配置檔案:
基本資料型別:
_byte ---------------------------------------- byte
_short---------------------------------------- short
_int ------------------------------------------- int
_integer -------------------------------------- int
_long ----------------------------------------- long
_double --------------------------------------double
_float -----------------------------------------float
_boolean ------------------------------------boolean
引用資料型別:
string --------------------------------------- String
byte ----------------------------------------- Byte
long ----------------------------------------- Long
short ---------------------------------------- Short
int ------------------------------------------- Integer
integer -------------------------------------- Integer
double -------------------------------------- Double
float ----------------------------------------- Float
boolean ------------------------------------- Boolean
date ----------------------------------------- Date
decimal ------------------------------------- BigDecimal
bigdecimal --------------------------------- BigDecimal
object --------------------------------------- Object
map ------------------------------------------ Map
hashmap ------------------------------------ HashMap
list ---------------------------------------------List
arraylist -------------------------------------- ArrayList
collection ----------------------------------- Collection
iterator -------------------------------------- Iterator
4.typeHandlers
改標籤用於自定義型別轉換器,對一些特殊型別引數和結果集進行處理來實現資料庫中資料型別和JavaBean中Java型別的指定方式的轉換。
利用typeHandlers宣告自定義型別轉換器時,首先要編寫自己的型別轉器類,該類需要實現TypeHandler介面,並複寫其中的方法,在對sql中的引數的賦值和取值處自定義處理方式。
eg:對控制做特殊處理
package com.mybatis.test.handler;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
public class MyStringTypeHandler implements TypeHandler<String>{
@Override
public void setParameter(PreparedStatement ps, int i, String parameter,
JdbcType jdbcType) throws SQLException {
if("".equals(parameter) || "null".equals(parameter)
|| parameter == null || "NULL".equals(parameter)){
parameter = "blank";
}
ps.setString(i, parameter);
}
@Override
public String getResult(ResultSet rs, String columnName)
throws SQLException {
String result = rs.getString(columnName);
if("null".equals(result) || "".equals(result)
|| result == null || "NULL".equals(result)){
result = "blank";
}
return result;
}
@Override
public String getResult(ResultSet rs, int columnIndex) throws SQLException {
String result = rs.getString(columnIndex);
if("null".equals(result) || "".equals(result)
|| result == null || "NULL".equals(result)){
result = "blank";
}
return result;
}
@Override
public String getResult(CallableStatement cs, int columnIndex)
throws SQLException {
String result = cs.getString(columnIndex);
if("null".equals(result) || "".equals(result)
|| result == null || "NULL".equals(result)){
result = "blank";
}
return null;
}
}
定義好自己的結果處理器後需要在mybatis核心配置檔案中用typeHandlers進行宣告:
<typeHandlers>
<typeHandler javaType="string" jdbcType="VARCHAR" handler="com.mybatis.test.handler.MyStringTypeHandler"/></typeHandlers>
在此處宣告自定義的型別處理器後,就可以在對?賦值和自定義結果集時對某個特定的欄位指定自定義結果集,對其按照自定義的方式進行處理。
在結果集中指定型別轉換器:
<resultMap type="com.mybatis.test.entity.Pet" id="petMap">
<!-- 制定結果構造器 -->
<constructor>
<!--
<idArg column="id" javaType="int"/>
-->
<!--
column ,
javaType,
jdbcType ,
typeHandler
-->
<arg column="name" javaType="string"/>
<arg column="species" javaType="string"/>
<arg column="sex" javaType="string"/>
</constructor>
<result column="name" property="name" javaType="string" jdbcType="VARCHAR"/>
<result column="species" property="species" javaType="string" jdbcType="VARCHAR" typeHandler="com.mybatis.test.handler.MyStringTypeHandler"/>
<result column="sex" property="sex" typeHandler="com.mybatis.test.handler.MyStringTypeHandler"/>
</resultMap>
這樣在執行查詢時我們將得到下面的結果:
<!-- custom type handler select test -->
<select id="cthSelect" resultMap="petMap">
select <include refid="column"/>
from pet
</select>
/**
* custom type handler test two
* */
@Test
public void cutomTypeHandlerTwo(){
session = sessionFactory.openSession();
List<Pet> pets = session.selectList("com.mybatis.test.entity.Pet.cthSelect");
Iterator<Pet> pi = pets.iterator();
while(pi.hasNext()){
System.out.println(pi.next());
}
}
Pet [name=bb, species=blank, sex=blank]
向表中插入一條記錄,結果如下:
<!-- custom type handler insert test -->
<insert id="cthInsert" parameterType="hashmap">
insert into pet (<include refid="column"/>)
values (#{name,javaType=string,jdbcType=VARCHAR,typeHandler=com.mybatis.test.handler.MyStringTypeHandler},
#{species,typeHandler=com.mybatis.test.handler.MyStringTypeHandler},
#{sex,javaType=string,jdbcType=VARCHAR})
</insert>
/**
* custom type handler test
* */
@Test
public void customTypeHandler(){
session = sessionFactory.openSession();
Map<String,String> map = new HashMap<String,String>();
map.put("name", null);
map.put("species", null);
map.put("sex", null);
session.insert("com.mybatis.test.entity.Pet.cthInsert", map);
session.commit();
}
MyBatis提供了一部分型別處理器用於處理一些基本的資料型別和引用資料型別結果集:
BooleanTypeHandler
ByteTypeHandler
ShortTypeHandler
IntegerTypeHandler
LongTypeHandler
FloatTypeHandler
DoubleTypeHandler
BigDecimalTypeHandler
StringTypeHandler
ClobTypeHandler
NStringTypeHandler
NClobTypeHandler
ByteArrayTypeHandler
BlobTypeHandler
DateTypeHandler
DateOnlyTypeHandler
TimeOnlyTypeHandler
SqlTimestampTypeHandler
SqlDateTypeHandler
SqlTimeTypeHandler
ObjectTypeHandler
EnumTypeHandler
EnumOrdinalTypeHandler
5.objectFactory
mybatis的一個重要功能就是對結果集到bean物件的自動封裝,建立bean物件的過程就是有ObjectFactory來完成的,在沒有配置objectFactory標籤時,mybatis使用預設的ObjectFactory的實現類DefaultBeanFactory來完成bean物件的建立,但是DefaultObjectFactory並沒有做什麼有意義的事情,所有我們也可以通過繼承DefaultObjectFactory來覆蓋其中的部分或全部方法,以實現對mybatis的擴充套件。
package com.mybatis.test.factory;
import java.util.List;
import java.util.Properties;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
@SuppressWarnings("serial")
public class CustomObjectFactory extends DefaultObjectFactory{
//呼叫bean物件的預設構造器
@Override
public <T> T create(Class<T> type) {
System.out.println("create object by auto constructor");
return super.create(type);
}
//當在sqlMapper中的bean對映中使用了<constroctor>標籤時,
//建立bean物件時會呼叫該方法
@Override
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes,
List<Object> constructorArgs) {
// TODO Auto-generated method stub.print
System.out.println("create object by arg constructor");
return super.create(type, constructorArgTypes, constructorArgs);
}
@Override
public <T> boolean isCollection(Class<T> type) {
// TODO Auto-generated method stub
return super.isCollection(type);
}
@Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub
super.setProperties(properties);
}
@Override
protected Class<?> resolveInterface(Class<?> type) {
// TODO Auto-generated method stub
return super.resolveInterface(type);
}
}
用objectFactory標籤配置自定義的ObjectFactory:
<objectFactory type="com.mybatis.test.factory.CustomObjectFactory"/>
5.plugins
Mybatis採用責任鏈模式,通過動態代理組織多個攔截器(外掛),通過這些攔截器可以改變Mybatis的預設行為(諸如SQL重寫之類的)
自定義外掛:
package com.mybatis.test.plugin;
import java.util.Properties;
import java.util.concurrent.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
/**
* Mybatis plugin
* */
@Intercepts({@Signature(type = Executor.class,method="update",
args = {MappedStatement.class, Object.class})})
public class ExamplePlugin implements Interceptor{
@Override
public Object intercept(Invocation invocation) throws Throwable {
//實現攔截邏輯,通過proceed() 推進聯結器
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
//生成代理物件
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub
}
}
配置自定義外掛:
<plugins>
<plugin interceptor="com.mybatis.test.plugin.ExamplePlugin"/>
</plugins>
6.environments
該標籤用於配置資料庫連線的基礎設定,例如事務管理器,連線池等。
mybatis可配置多個數據庫連線,注意沒一個數據庫連線對應一個SqlSessionFactory,所以若想同時連線兩個資料庫,則需要建立兩個mybatis的核心配置檔案,並對應到相應的資料庫。
下面是mybatis中一個environments配置示例:
<environments default="mysql_environment">
<environment id="mysql_environment">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="zhangdd" />
<property name="password" value="zd1991.." />
</dataSource>
</environment>
</environments>
其中一個environment對應一個數據庫連線配置,可以利用environments的default屬性來制定當前所使用的資料庫連線配置,例如在開發時,連線測試資料庫環境,在應用上線時連線生成環境,就可以實現進行配置,並利用default屬性進行切換,使用起立很方便。
1)transactionManager
該標籤用於設定事務管理器。mybatis提供了兩種實物管理器:
JdbcTransaction(JDBC),ManagedTransaction(MANAGED),其中JdbcTransaction直接沿用了java-JDBC的事務管理機制,依賴於資料庫連線來管理事務。而ManagedTransaction幾乎什麼都沒有做,檢視其原始碼就可見一斑:
public void commit() throws SQLException {
// Does nothing
}
public void rollback() throws SQLException {
// Does nothing
}
public void close() throws SQLException {
if (this.closeConnection && this.connection != null) {
if (log.isDebugEnabled()) {
log.debug("Closing JDBC Connection [" + this.connection + "]");
}
this.connection.close();
}
}
mybatis的事務管理頂級介面是Transaction:
public interface Transaction {
Connection getConnection() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
void close() throws SQLException;
}
兩個實現類JdbcTransaction、ManagedTransaction,其中JdbcTransaction提供了設定事務是否自動提交的介面:
protected void setDesiredAutoCommit(boolean desiredAutoCommit)
若將mybatis與spring進行整合,則不需要配置事務管理器,因為spring的宣告式事務處理以及將資料庫操作的事務納入管理範圍。
2)dataSource
該標籤用來配置資料來源,一個簡單的例子如下:
...
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test" />
<property name="username" value="zhangdd" />
<property name="password" value="zd1991.." />
</dataSource>
...
mybatis提供了三種資料來源的實現:UNPOOLED、POOLED、JNDI
UNPOOLED
該型別的資料來源沒有實現任何對資料庫連線的快取,而是已最原始的方法去連線資料庫,即每次操作資料庫都建立一個新的可用連線,然後釋放掉。通常情況下需要配置以下選項:
driver – 這是 JDBC 驅動的 Java 類的完全限定名(如果你的驅動包含,它也不是 資料來源類)。
url – 這是資料庫的 JDBC URL 地址。
username – 登入資料庫的使用者名稱。
password – 登入資料庫的密碼。
defaultTransactionIsolationLevel – 預設的連線事務隔離級別。
也可以通過driver.Xxxx的形式來制定與資料庫先關的屬性。
POOLED
這種型別的資料來源是基本的JDBC資料庫連線的連線池實現,是比較常用的一種資料來源型別,除了上述的url、username、password、defaultTransactionIsolationLevel外,還可以對資料來源的一個基本屬性進行設定,具體如下:
poolMaximumActiveConnections:任意時間存在的活動連線數。預設為10。
poolMaximumIdleConnections:空閒連線數。
poolMaximumCheckoutTime:連線被強制返回到池中的超時時間。
poolPingQuery: 傳送到資料的偵測查詢,用來驗證連線是否正常工作,並且準
備接受請求。預設是“NO PING QUERY SET”
poolPingEnabled – 這是開啟或禁用偵測查詢,預設為false。
JNDI
這個資料來源的實現是為了使用如 Spring 或應用伺服器這類的容器, 容器可以集中或在外部配置資料來源,然後放置一個 JNDI 上下文的引用。這個資料來源配置只需要兩個屬性:
initial_context:這個屬性用來從初始上下文中尋找環境(也就是 initialContext.lookup(initial——context) 。這是個可選屬性,如果被忽略,那麼 data_source 屬性將會直接以 initialContext 為背景再次尋找。
data_source:這是引用資料來源例項位置的上下文的路徑。它會以由 initial_context 查詢返回的環境為背景來查詢,如果 initial_context 沒有返回結果時,直接以初始上下文為環境來查詢。
env:和其他資料來源配置相似, 它也可以通過名為 “env.” 的字首直接向初始上下文傳送屬性。比如: env.encoding=UTF8在初始化之後,這就會以值“UTF8”向初始上下文的構造方法傳遞名為“encoding” 的屬性。
也可以引用第三方的資料來源,例如DBCP或C3P0,只需要將dateSource標籤的type屬性制定到特定的DataSource類就可以,例如:
<dataSource type="org.myproject.C3P0DataSourceFactory">
<property name="driver" value="org.postgresql.Driver"/>
<property name="url" value="jdbc:postgresql:mydb"/>
<property name="username" value="postgres"/>
<property name="password" value="root"/>
</dataSource>
7.mappers
該標籤用來引用Bean的sql對映檔案,應用sql對映的方式有四種,分別是:
1)引入類路徑下的xml檔案
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
2)使用檔案系統的絕對路徑
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
3)使用介面是引用(對sql的對映也可以利用介面+註解的形式來完成)
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
4)使用包名來執行某些包下的所有對映
mappers>
<package name="org.mybatis.builder"/>
</mappers>