Mybatis 补充

2年前 阅读 305 评论 0 赞 0

Mybatis 补充

在控制台显示 SQL 语句

用过 Hibernate 的人都知道,Hibernate 是可以配置 show_sql 显示 自动生成的 SQL 语句,用 format_sql 可以格式化 SQL 语句,但如果用 Mybatis 怎么实现这个功能呢, 可以通过配置日志来实现的,比如配置我们最常用的 log4j.properties 来实现。

log4j.properties 内容

  1. log4j.rootCategory=info, stdout , R
  2. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  3. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  4. log4j.appender.stdout.layout.ConversionPattern=[QC] %p [%t] %C.%M(%L) | %m%n
  5. log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
  6. log4j.appender.R.File=D:/my_log.log
  7. log4j.appender.R.layout=org.apache.log4j.PatternLayout
  8. log4j.appender.R.layout.ConversionPattern=%d-[TS] %p %t %c - %m%n
  9. log4j.logger.com.ibatis=debug
  10. log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
  11. log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
  12. log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
  13. log4j.logger.java.sql.Connection=debug
  14. log4j.logger.java.sql.Statement=debug
  15. log4j.logger.java.sql.PreparedStatement=debug,stdout

传递多个参数的方法

在用 Mybatis 做查询的时候,通常会传递多个参数,一般来说,这种情况下有两种解决办法:

  • 利用 hashMap 去做。
  • 利用 Mybatis 自身的多个参数传递方式去做。

利用 hashMap 传递多个参数

  1. <select id="selectByDate" parameterType="map" resultMap="campaignStats">
  2. <![CDATA[
  3. Select * FROM CampaignStats Where statsDate >= #{start} AND statsDate <= #{end}
  4. ]]>
  5. </select>

对应的 Java 代码为

  1. public List<DpCampaignStats> selectByDate(Date start, Date end){
  2. SqlSession session = sqlSessionFactory.openSession();
  3. try {
  4. Map<String, Date> map = new HashMap<String, Date>();
  5. map.put("start", start);
  6. map.put("end", end);
  7. List<DpCampaignStats> list = session.selectList("DpCampaignStats.selectByDate", map);
  8. return list;
  9. } finally {
  10. session.close();
  11. }
  12. }

Mybatis 自带的多个参数传递方法

  1. <select id="selectByDate" resultMap="campaignStats">
  2. <![CDATA[
  3. Select * FROM CampaignStats Where statsDate >= #{param1} AND statsDate <= #{param2}
  4. ]]>
  5. </select>

请注意,这个时候没有 parameterType, 但用到了类似 #{param1} 类似的参数. 同样 Java 代码也需要做出改变

  1. public List<DpCampaignStats> selectByDate(Date start, Date end){
  2. SqlSession session = sqlSessionFactory.openSession();
  3. try {
  4. List<DpCampaignStats> list = session.selectList("DpCampaignStats.selectByDate", start,end);
  5. return list;
  6. } finally {
  7. session.close();
  8. }
  9. }

推荐使用 hashMap 来传递多个参数。

缓存的使用

许多应用程序,为了提高性能而增加缓存, 特别是从数据库中获取的数据. 在默认情况下,Mybatis 的一级缓存是默认开启的。类似于 Hibernate, 所谓一级缓存,也就是基于同一个 sqlsession 的查询语句,即 session 级别的缓存,非全局缓存,或者非二级缓存.

如果要实现 Mybatis 的二级缓存,一般来说有如下两种方式:

  1. 采用 Mybatis 内置的 cache 机制。
  2. 采用三方 cache 框架, 比如 ehcache, oscache 等等。

采用 Mybatis 内置的 cache 机制

在 SQL 语句映射文件中加入 语句 , 并且相应的 model 类要实现 java Serializable 接口,因为缓存说白了就是序列化与反序列化的过程,所以需要实现这个接口. 单纯的 表示如下意思:

  1. 所有在映射文件里的 select 语句都将被缓存。
  2. 所有在映射文件里 insert,update 和 delete 语句会清空缓存。
  3. 缓存使用“最近很少使用”算法来回收
  4. 缓存不会被设定的时间所清空。
  5. 每个缓存可以存储 1024 个列表或对象的引用(不管查询出来的结果是什么) 。
  6. 缓存将作为“读/写”缓存,意味着获取的对象不是共享的且对调用者是安全的。不会有其它的调用者或线程潜在修改。

缓存元素的所有特性都可以通过属性来修改。比如:

  1. <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />

采用 ehcache 来实现 Mybatis 的二级缓存

首先需要在 Mybatis 的官网上下载相关jar 包:https://code.google.com/p/mybatis/ 写文档的时候下载的是:mybatis-ehcache-1.0.2.zip ,里面包括了

  1. mybatis-ehcache-1.0.2.jar
  2. ehcache-core-2.6.5.jar
  3. slf4j-api-1.6.1.jar

当然,采用 ehcache 就必须在 classpath 下 加入 ehcache 的配置文件 ehcache.xml:

  1. <cache name="default"
  2. maxElementsInMemory="10000"
  3. eternal="false"
  4. timeToIdleSeconds="3600"
  5. timeToLiveSeconds="10"
  6. overflowToDisk="true"
  7. diskPersistent="true"
  8. diskExpiryThreadIntervalSeconds="120"
  9. maxElementsOnDisk="10000"
  10. />

那么在 SQL 映射文件中要如何配置呢,参考如下:

  1. <cache type="org.mybatis.caches.ehcache.LoggingEhcache" >
  2. <property name="timeToIdleSeconds" value="3600"/><!--1 hour-->
  3. <property name="timeToLiveSeconds" value="3600"/><!--1 hour-->
  4. <property name="maxEntriesLocalHeap" value="1000"/>
  5. <property name="maxEntriesLocalDisk" value="10000000"/>
  6. <property name="memoryStoreEvictionPolicy" value="LRU"/>
  7. </cache>

总结:无论是采用 Mybatis 自身的 cache 还是三方的 cache , 这样的配置,就是对所有的 select 语句都全局缓存,但事实上,并不总是这样,比如,我在这系列教程实现 Mybatis 分页 ,自己写的分页算法,就不能用这种情况。需要禁止掉 cache ,所以需要如下方法:

  1. <select id="selectArticleListPage" resultMap="resultUserArticleList" useCache="false">
  2. .......

注意到 useCache=”false” 了吗? 这可以避免使用缓存。

你的支持将鼓励作者继续创作

评论(0)

(无)