1. 程式人生 > 實用技巧 >Mybatis配置檔案如何進行配置呢?

Mybatis配置檔案如何進行配置呢?

Mybatis配置檔案如何進行配置呢?

如需要跟多資料請點選下方圖片⬇(掃碼加好友→備註66,不備註拒絕新增哦)

Mybatis配置檔案配置的方式

  • properties
  • settings
  • typeAliases
  • typeHandlers
  • objectFactory
  • plugins
  • environments
  • transactionManager
  • dataSource
  • mappers

案例實操

1. properties

這些屬性都是可外部配置且可動態替換的,既可以在典型的 Java 屬性檔案中配置,亦可通過 properties 元素的子元素來傳遞。例如:

<property name="driver" value="com.mysql.jdbc.Driver" />            
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />             
<property name="username" value="root" />             
<property name="password" value="root" />

其中的屬性就可以在整個配置檔案中使用來替換需要動態配置的屬性值。比如:

<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>

如何配?

在config.xml 檔案中<configuration>引入子標籤

<properties resource="jdbc.properties"></properties>

並修改原有資料來源連線相關配置如下:

<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>
</environments>

即可完成。

2. settings(瞭解)

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-bbYufDxn-1600743495185)(https://imgkr.cn-bj.ufileos.com/d0372a13-d467-4f73-a99b-45dfa35973b2.png)]

這是MyBatis 修改操作執行過程細節的重要的步驟。下方這個表格描述了這些設定項、含義和預設值。一般我們用預設即可(詳細解釋見官網文件)

對應xml配置如下(開發中一般採用預設配置即可):

<settings> 
    <setting name="cacheEnabled" value="true"/>  
    <setting name="lazyLoadingEnabled" value="true"/>  
    <setting name="multipleResultSetsEnabled" value="true"/>
    <setting name="useColumnLabel" value="true"/>  
    <setting name="useGeneratedKeys" value="false"/>  
    <setting name="autoMappingBehavior" value="PARTIAL"/>
    <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
    <setting name="defaultExecutorType" value="SIMPLE"/>  
    <setting name="defaultStatementTimeout" value="25"/> 
    <setting name="defaultFetchSize" value="100"/> 
    <setting name="safeRowBoundsEnabled" value="false"/> 
    <setting name="mapUnderscoreToCamelCase" value="false"/> 
    <setting name="localCacheScope" value="SESSION"/>  
    <setting name="jdbcTypeForNull" value="OTHER"/> 
    <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

**3.**typeAliases

類型別名是為 Java 型別設定一個短的名字。它只和 XML 配置有關,存在的意義僅在於用來減少類完全限定名的冗餘。例如:

Configuration 標籤下新增

<typeAliases>   
    <typeAlias alias="customer" type="com.xxx.pojo.Customer" />
</typeAliases>

修改CustomerMapper.xml 檔案

 <!-- 查詢客戶-->
<select id="queryCustomerById" parameterType="int" resultType="customer">
    SELECT id,user_name 'userName' FROM  yg_customer WHERE  id=#{id}
</select>

也可以指定一個包名(大家最喜歡的方式),MyBatis 會在包名下面搜尋需要的 Java Bean,比如:

<typeAliases>    
    <!-- <typeAlias alias="customer" type="com.xxx.pojo" /> -->    
    <package name="com.xxx.pojo"/>
</typeAliases>

每一個在包com.xxx.pojo 中的 Java Bean,在沒有註解的情況下,會使用 Bean 的首字母小寫的非限定類名來作為它的別名。 比如com.xxx.pojo.Customer 的別名為customer ;

若有註解,則別名為其註解值。 註解名@Alias(value=“user”)

同樣mybatis已經為我們構建了相應的類型別名,它們都是大小寫不敏感的,需要注意的是由基本型別名稱重複導致的特殊處理。

別名 對映的型別
_byte Byte
_long Long
_short Short
_int Int
_integer Int
_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 型別處理器(面試有可能會問)

無論是 MyBatis 在預處理語句(PreparedStatement)中設定一個引數時,還是從結果集中取出一個值時, 都會用型別處理器將獲取的值以合適的方式轉換成 Java 型別。下表描述了一些預設的型別處理器。

BooleanTypeHandler java.lang.Boolean, boolean 資料庫相容的 BOOLEAN
ByteTypeHandler java.lang.Byte, byte 資料庫相容的 NUMERIC 或 BYTE
ShortTypeHandler java.lang.Short, short 資料庫相容的 NUMERIC 或 SHORT INTEGER
IntegerTypeHandler java.lang.Integer, int 資料庫相容的 NUMERIC 或 INTEGER
LongTypeHandler java.lang.Long, long 資料庫相容的 NUMERIC 或 LONG INTEGER
FloatTypeHandler java.lang.Float, float 資料庫相容的 NUMERIC 或 FLOAT
DoubleTypeHandler java.lang.Double, double 資料庫相容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandler java.math.BigDecimal 資料庫相容的 NUMERIC 或 DECIMAL
StringTypeHandler java.lang.String CHAR, VARCHAR
ClobReaderTypeHandler java.io.Reader -
ClobTypeHandler java.lang.String CLOB, LONGVARCHAR
NStringTypeHandler java.lang.String NVARCHAR, NCHAR
NClobTypeHandler java.lang.String NCLOB
BlobInputStreamTypeHandler java.io.InputStream -
ByteArrayTypeHandler byte[] 資料庫相容的位元組流型別
BlobTypeHandler byte[] BLOB, LONGVARBINARY
DateTypeHandler java.util.Date TIMESTAMP
DateOnlyTypeHandler java.util.Date DATE
TimeOnlyTypeHandler java.util.Date TIME
SqlTimestampTypeHandler java.sql.Timestamp TIMESTAMP
SqlDateTypeHandler java.sql.Date DATE
SqlTimeTypeHandler java.sql.Time TIME
ObjectTypeHandler Any OTHER 或未指定型別
EnumTypeHandler Enumeration Type VARCHAR-任何相容的字串型別,儲存列舉的名稱(而不是索引)
EnumOrdinalTypeHandler Enumeration Type 任何相容的 NUMERIC 或 DOUBLE 型別,儲存列舉的索引(而不是名稱)。

你可以重寫型別處理器或建立你自己的型別處理器來處理不支援的或非標準的型別。 具體做法為:實現 org.apache.ibatis.type.TypeHandler 介面, 或繼承一個很便利的類 org.apache.ibatis.type.BaseTypeHandler, 然後可以選擇性地將它對映到一個 JDBC 型別。

5. 物件工廠(objectFactory)(瞭解)

MyBatis 每次建立結果物件的新例項時,它都會使用一個物件工廠(ObjectFactory)例項來完成。預設的物件工廠需要做的僅僅是例項化目標類,要麼通過預設構造方法,要麼在引數對映存在的時候通過引數構造方法來例項化。預設情況下,我們不需要配置,mybatis會呼叫預設實現的objectFactory。從這個類的外部看,這個類的主要作用就是根據一個類的型別得到該類的一個實體物件,比如,我們給他一個User的type,他將會給我們一個Tiger的實體物件,我們給他一個java.lang.List物件,他將會給我們一個List的實體物件。類似於spring 工廠例項化bean

6. plugins 外掛

MyBatis 允許你在已對映語句執行過程中的某一點進行攔截呼叫。預設情況下,MyBatis 允許使用外掛來攔截的方法呼叫包括:

· Executor (sql執行時, update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)

· ParameterHandler (引數的處理, getParameterObject, setParameters)

· ResultSetHandler (結果集的處理, handleResultSets, handleOutputParameters)

· StatementHandler (申明語句的處理, prepare, parameterize, batch, update, query)

這些類中方法的細節可以通過檢視每個方法的簽名來發現,或者直接檢視 MyBatis 的發行包中的原始碼。 假設你想做的不僅僅是監控方法的呼叫,那麼你應該很好的瞭解正在重寫的方法的行為。 因為如果在試圖修改或重寫已有方法的行為的時候,你很可能在破壞 MyBatis 的核心模組。 這些都是更低層的類和方法,所以使用外掛的時候要特別當心。

通過 MyBatis 提供的強大機制,使用外掛是非常簡單的,只需實現 Interceptor 介面,並指定了想要攔截的方法簽名即可。

總配置新增

 <!-- 外掛 -->   
<plugins>   
    <plugin interceptor="com.xxx.plugins.ExamplePlugin">          
        <property name="someProperty" value="100" />   
    </plugin>
</plugins>

外掛demo:

@Intercepts({   
    @Signature(      
        type=Executor.class,       
        /**         
        * 攔截所有方法    
        */     
        method="query",       
        /**          
        * 引數定義     
        */          
        args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class}            )
}) 
public class ExamplePlugin implements Interceptor {   
    /**    
    * 每個外掛必須實現以下三個方法   
    */    
    /**    
    * Object intercept(Invocation invocation)是實現攔截邏輯的地方,  
    * 內部要通過invocation.proceed()顯式地推進責任鏈前進,也就是呼叫下一個攔截器攔截目標方法。 
    */   
    public Object intercept(Invocation invocation) throws Throwable {       					 System.out.println("intercept");     
         return invocation.proceed();  
      }      
    /**    
    * Object plugin(Object target) 就是用當前這個攔截器生成對目標target的代理,   
    * 實際是通過Plugin.wrap(target,this) 來完成的,把目標target和攔截器this傳給了包裝函式。   
    */   
    public Object plugin(Object target) {    
        return Plugin.wrap(target, this);   
    }       
    /**    
    * setProperties(Properties properties)用於設定額外的引數,引數配置在攔截器的Properties節點裡。   
    */   
    public void setProperties(Properties properties) {       		 							System.out.println(properties.get("hello"));  
    }
}

7. 配置環境(environments)(熟悉 配多個數據源)

MyBatis 可以配置成適應多種環境,這種機制有助於將 SQL 對映應用於多種資料庫之中, 現實情況下有多種理由需要這麼做。例如,開發、測試和生產環境需要有不同的配置;或者共享相同 Schema 的多個生產資料庫, 想使用相同的 SQL 對映。許多類似的用例。

不過要記住:儘管可以配置多個環境,每個 SqlSessionFactory 例項只能選擇其一。

所以,如果你想連線兩個資料庫,就需要建立兩個 SqlSessionFactory 例項,每個資料庫對應一個。而如果是三個資料庫,就需要三個例項,依此類推,記起來很簡單:

· 每個資料庫對應一個 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="${driver2}" />
            <property name="url" value="${url2}" />
            <property name="username" value="${username2}" />
            <property name="password" value="${password2}" />
        </dataSource>
    </environment>
</environments>
## development
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8
username=root
password=root


## test
driver2=com.mysql.jdbc.Driver
url2=jdbc:mysql://127.0.0.1:3306/mybatis2?useUnicode=true&amp;characterEncoding=utf8
username2=root
password2=root

測試sqlSessionFactory

public void test02() {   
    InputStream in;   
    try {        
        in = Resources.getResourceAsStream(this.getClass().getClassLoader()
        		, "config.xml");      
         // 預設開發庫     
         //SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(in);          // 測試庫       
         SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(in,"test");       
         UserDao userDao=new UserDaoImpl(sqlSessionFactory);      
         User user= userDao.queryUserById(1);     
         System.out.println(user); 
        } catch (IOException e) {    
        e.printStackTrace();    
    }
}

8. 事務管理器(transactionManager)(瞭解)

在 MyBatis 中有兩種型別的事務管理器(也就type=”[JDBC|MANAGED]”):

  • JDBC – 這個配置就是直接使用了 JDBC 的提交和回滾設定,它依賴於從資料來源得到的連線來管理事務範圍。

  • MANAGED – 這個配置幾乎沒做什麼。它從來不提交或回滾一個連線,而是讓容器來管理事務的整個生命週期。 預設情況下它會關閉連線,然而一些容器並不希望這樣,因此需要將 closeConnection 屬性設定為 false 來阻止它預設的關閉行為。例如:

<transactionManager type="MANAGED">  
    <property name="closeConnection" value="false"/>
</transactionManager>

如果你正在使用 Spring + MyBatis,則沒有必要配置事務管理器, 因為 Spring 模組會使用自帶的管理器來覆蓋前面的配置。(整合時會講到)

9.dataSource 資料來源(瞭解)

dataSource 元素使用標準的 JDBC 資料來源介面來配置 JDBC 連線物件的資源。

資料來源型別有三種:UNPOOLED,POOLED,JNDI

UNPOOLED

這個資料來源的實現只是每次被請求時開啟和關閉連線。雖然有一點慢,它對在及時可用連線方面沒有效能要求的簡單應用程式是一個很好的選擇。 不同的資料庫在這方面表現也是不一樣的,所以對某些資料庫來說使用連線池並不重要,這個配置也是理想的。

  • driver – 這是 JDBC 驅動的 Java 類的完全限定名(並不是JDBC驅動中可能包含的資料來源類)。
  • url – 這是資料庫的 JDBC URL 地址。
  • username – 登入資料庫的使用者名稱。
  • password – 登入資料庫的密碼。
  • defaultTransactionIsolationLevel – 預設的連線事務隔離級別。

作為可選項,你也可以傳遞屬性給資料庫驅動。要這樣做,屬性的字首為“driver.”,例如:

  • driver.encoding=UTF8

這將通過DriverManager.getConnection(url,driverProperties)方法傳遞值為 UTF8 的 encoding 屬性給資料庫驅動。

POOLED

​ 這種資料來源的實現利用“池”的概念將 JDBC 連線物件組織起來,避免了建立新的連線例項時所必需的初始化和認證時間。 這是一種使得併發 Web 應用快速響應請求的流行處理方式。(一般選用這種)

  • poolMaximumActiveConnections – 在任意時間可以存在的活動(也就是正在使用)連線數量,預設值:10

  • poolMaximumIdleConnections – 任意時間可能存在的空閒連線數。

  • poolMaximumCheckoutTime – 在被強制返回之前,池中連線被檢出(checked out)時間,預設值:20000 毫秒(即 20 秒)

  • poolTimeToWait – 這是一個底層設定,如果獲取連線花費的相當長的時間,它會給連線池列印狀態日誌並重新嘗試獲取一個連線(避免在誤配置的情況下一直安靜的失敗),預設值:20000 毫秒(即 20 秒)。

  • poolPingQuery – 傳送到資料庫的偵測查詢,用來檢驗連線是否處在正常工作秩序中並準備接受請求。預設是“NO PING QUERY SET”,這會導致多數資料庫驅動失敗時帶有一個恰當的錯誤訊息。

  • poolPingEnabled – 是否啟用偵測查詢。若開啟,也必須使用一個可執行的 SQL 語句設定 poolPingQuery 屬性(最好是一個非常快的 SQL),預設值:false。

  • poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的使用頻度。這可以被設定成匹配具體的資料庫連線超時時間,來避免不必要的偵測,預設值:0(即所有連線每一時刻都被偵測 — 當然僅當 poolPingEnabled 為 true 時適用)。

JNDI

​ 這個資料來源的實現是為了能在如 EJB 或應用伺服器這類容器中使用,容器可以集中或在外部配置資料來源,然後放置一個 JNDI 上下文的引用。

  • initial_context – 這個屬性用來在 InitialContext 中尋找上下文(即initialContext.lookup(initial_context))。這是個可選屬性,如果忽略,那麼 data_source 屬性將會直接從 InitialContext 中尋找。
  • data_source – 這是引用資料來源例項位置的上下文的路徑。提供了 initial_context 配置時會在其返回的上下文中進行查詢,沒有提供時則直接在 InitialContext 中查詢。和其他資料來源配置類似,可以通過新增字首“env.”直接把屬性傳遞給初始上下文。比如:
  • env.encoding=UTF8

這就會在初始上下文(InitialContext)例項化時往它的構造方法傳遞值為 UTF8 的 encoding 屬性。

10.mappers 對映器(四種配置)(熟悉)

這裡是告訴mybatis去哪尋找對映SQL 的語句。可以使用類路徑中的資源引用,或者使用字元,輸入確切的URL 引用。

!— sqlmapper配置檔案路徑 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>

<!—url絕對路徑形式-->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>

<!—介面 列表配置形式  註解sql-->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>

<!—對映包下所有介面-->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

這些配置會告訴了 MyBatis 去哪裡找對映檔案,剩下的細節就應該是每個 SQL 對映檔案。

擴充套件

封裝Dao

1新建介面CustomerDao

介面定義:

public interface CustomerDao {
    Customer queryCustomerByName(String userName);
}

2 xml對映檔案

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xxx.dao.CustomerDao">
    <!-- 查詢客戶-->
    <select id="queryCustomerByName" parameterType="string" resultType="com.xxx.pojo.Customer">
      SELECT id,user_name 'userName',user_balance 'userBalance' FROM  yg_customer WHERE  user_name=#{userName}
    </select>
</mapper>

3 mappers對映器配置

<mappers>
       <!-- <mapper resource="com/xxx/mapper/CustomerDao.xml" />-->
        <package name="com.xxx.dao"/>
</mappers>

4 測試

public class App 
{
    public static void main( String[] args ) throws IOException {
        //1 載入配置檔案
        InputStream is = Resources.getResourceAsStream("mybatis.xml");
        //2 建立sqlsessionfactor工廠
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //3 構建資料庫會話
        SqlSession session = factory.openSession();
       /* Customer customer = session.selectOne("com.xxx.mapper.customerMapper.queryCustomerById", 2);
        System.out.println(customer);*/
        CustomerDao customerDao = session.getMapper(CustomerDao.class);
        Customer customer = customerDao.queryCustomerByName("zhaoliying");
        System.out.println(customer);
        session.close();
    }
}

onFactory factory = new SqlSessionFactoryBuilder().build(is); //3 構建資料庫會話 SqlSession session = factory.openSession(); /* Customer customer = session.selectOne("com.xxx.mapper.customerMapper.queryCustomerById", 2); System.out.println(customer);*/ CustomerDao customerDao = session.getMapper(CustomerDao.class); Customer customer = customerDao.queryCustomerByName("zhaoliying"); System.out.println(customer); session.close(); } }