用過 Hibernate 的人都知道,Hibernate 是可以配置 show_sql 顯示 自動生成的 SQL 語句,用 format_sql 可以格式化 SQL 語句,但如果用 Mybatis 怎么實現(xiàn)這個功能呢, 可以通過配置日志來實現(xiàn)的,比如配置我們最常用的 log4j.properties 來實現(xiàn)。
log4j.properties 內(nèi)容
log4j.rootCategory=info, stdout , R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=D:/my_log.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
log4j.logger.com.ibatis=debug
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
log4j.logger.java.sql.Connection=debug
log4j.logger.java.sql.Statement=debug
log4j.logger.java.sql.PreparedStatement=debug,stdout
在用 Mybatis 做查詢的時候,通常會傳遞多個參數(shù),一般來說,這種情況下有兩種解決辦法:
<select id="selectByDate" parameterType="map" resultMap="campaignStats">
<![CDATA[
Select * FROM CampaignStats Where statsDate >= #{start} AND statsDate <= #{end}
]]>
</select>
對應的 Java 代碼為
public List<DpCampaignStats> selectByDate(Date start, Date end){
SqlSession session = sqlSessionFactory.openSession();
try {
Map<String, Date> map = new HashMap<String, Date>();
map.put("start", start);
map.put("end", end);
List<DpCampaignStats> list = session.selectList("DpCampaignStats.selectByDate", map);
return list;
} finally {
session.close();
}
}
<select id="selectByDate" resultMap="campaignStats">
<![CDATA[
Select * FROM CampaignStats Where statsDate >= #{param1} AND statsDate <= #{param2}
]]>
</select>
請注意,這個時候沒有 parameterType, 但用到了類似 #{param1} 類似的參數(shù). 同樣 Java 代碼也需要做出改變
public List<DpCampaignStats> selectByDate(Date start, Date end){
SqlSession session = sqlSessionFactory.openSession();
try {
List<DpCampaignStats> list = session.selectList("DpCampaignStats.selectByDate", start,end);
return list;
} finally {
session.close();
}
}
推薦使用 hashMap 來傳遞多個參數(shù)。
許多應用程序,為了提高性能而增加緩存, 特別是從數(shù)據(jù)庫中獲取的數(shù)據(jù). 在默認情況下,Mybatis 的一級緩存是默認開啟的。類似于 Hibernate, 所謂一級緩存,也就是基于同一個 sqlsession 的查詢語句,即 session 級別的緩存,非全局緩存,或者非二級緩存.
如果要實現(xiàn) Mybatis 的二級緩存,一般來說有如下兩種方式:
在 SQL 語句映射文件中加入
緩存元素的所有特性都可以通過屬性來修改。比如:
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
首先需要在 Mybatis 的官網(wǎng)上下載相關(guān)jar 包:https://code.google.com/p/mybatis/ 寫文檔的時候下載的是:mybatis-ehcache-1.0.2.zip ,里面包括了
mybatis-ehcache-1.0.2.jar
ehcache-core-2.6.5.jar
slf4j-api-1.6.1.jar
當然,采用 ehcache 就必須在 classpath 下 加入 ehcache 的配置文件 ehcache.xml:
<cache name="default"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="3600"
timeToLiveSeconds="10"
overflowToDisk="true"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="120"
maxElementsOnDisk="10000"
/>
那么在 SQL 映射文件中要如何配置呢,參考如下:
<cache type="org.mybatis.caches.ehcache.LoggingEhcache" >
<property name="timeToIdleSeconds" value="3600"/><!--1 hour-->
<property name="timeToLiveSeconds" value="3600"/><!--1 hour-->
<property name="maxEntriesLocalHeap" value="1000"/>
<property name="maxEntriesLocalDisk" value="10000000"/>
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
總結(jié):無論是采用 Mybatis 自身的 cache 還是三方的 cache , 這樣的配置,就是對所有的 select 語句都全局緩存,但事實上,并不總是這樣,比如,我在這系列教程實現(xiàn) Mybatis 分頁 ,自己寫的分頁算法,就不能用這種情況。需要禁止掉 cache ,所以需要如下方法:
<select id="selectArticleListPage" resultMap="resultUserArticleList" useCache="false">
.......
注意到 useCache="false" 了嗎? 這可以避免使用緩存。