ibatis缓存的简单使用和源码分析

配置:

    <cacheModel type="LRU" id="user-cache">

        <flushInterval hours="24"/>

        <flushOnExecute statement="user.addUser"/>

        <flushOnExecute statement="user.updateUser"/>

        <flushOnExecute statement="user.deleteUser"/>

        <property name="cache-size" value="50000"/>

    </cacheModel>

 

    <select id="getAll" resultClass="user" parameterClass="java.util.HashMap" cacheModel="user-cache">

        select * from user limit 0,#size#

    </select>

 

测试代码:

        Map<String, Object> map = new HashMap<String, Object>();

        map.put("size", 8);

        // first time no cache

        Long startTime = System.currentTimeMillis();

        List<User> list = (List<User>)sqlMap.queryForList("user.getAll", map);

        System.out.println("No cache pass time:" + (System.currentTimeMillis() - startTime));

        // second time has cache

        map.put("size", 8);

        startTime = System.currentTimeMillis();

        list = (List<User>)sqlMap.queryForList("user.getAll", map);

        System.out.println("Has cache pass time:" + (System.currentTimeMillis() - startTime));

 

结果:

No cache pass time:485

Has cache pass time:0

打开ibatis的日志,会发现第二次执行没有sql语句输出。

 

注意:

CacheModel缓存的是statement,即key是跟sql语句相关,如果sql语句不一样,将产生两个cache,如第二条将使用不到缓存,但第三条可以使用缓存:

select * from user limit 0,4    新建缓存

select * from user limit 0,8    新建缓存

select * from user limit 0,8    使用缓存

 

简单源码分析:

queryForList为例:

 

SqlMapExecutorDelegate具体实现:

list = ms.executeQueryForList(statementScope, trans, paramObject, skip, max);

这里msMappedStatement,其中CachingStatement是它的子类。

 

CachingStatement具体实现:

  public List executeQueryForList(StatementScope statementScope, Transaction trans, Object parameterObject, int skipResults, int maxResults)

      throws SQLException {

    CacheKey cacheKey = getCacheKey(statementScope, parameterObject);

    cacheKey.update("executeQueryForList");

    cacheKey.update(skipResults);

    cacheKey.update(maxResults);

    Object listAsObject = cacheModel.getObject(cacheKey);

    List list;

    if(listAsObject == CacheModel.NULL_OBJECT){

      // The cached object was null

      list = null;

    }else if (listAsObject == null) {

      list = statement.executeQueryForList(statementScope, trans, parameterObject, skipResults, maxResults);

      cacheModel.putObject(cacheKey, list);

    }else{

      list = (List) listAsObject;

    }

    return list;

  }

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
File: Account.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd"> <sqlMap namespace="Account"> <typeAlias alias="Account" type="Account"/> <resultMap id="AccountResult" class="Account"> <result property="id" column="ACC_ID"/> <result property="firstName" column="ACC_FIRST_NAME"/> <result property="lastName" column="ACC_LAST_NAME"/> <result property="emailAddress" column="ACC_EMAIL"/> </resultMap> <cacheModel id="categoryCache" type="LRU"> <flushInterval hours="24"/> <property name="size" value="100"/> </cacheModel> <select id="getByLike" resultClass="Account" parameterClass="Account" cacheModel="categoryCache"> select ACC_ID as id, ACC_FIRST_NAME as firstName, ACC_LAST_NAME as lastName, ACC_EMAIL as emailAddress from ACCOUNT where ACC_EMAIL = #emailAddress# and ACC_LAST_NAME = #lastName# </select> <!-- Insert example, using the Account parameter class --> <insert id="insertAccount" parameterClass="Account"> insert into ACCOUNT ( ACC_ID, ACC_FIRST_NAME, ACC_LAST_NAME, ACC_EMAIL )values ( #id#, #firstName#, #lastName#, #emailAddress# ) </insert> </sqlMap> File: Main.java import java.util.List; import com.ibatis.sqlmap.client.SqlMapClient; public class Main { public static void main(String[] a) throws Exception { Util util = new Util(); util .executeSQLCommand("create table ACCOUNT(ACC_ID int, ACC_FIRST_NAME varchar,ACC_LAST_NAME varchar,ACC_EMAIL varchar);"); util.executeSQLCommand("create table Message(Message_ID int, content varchar);"); SqlMapClient sqlMapper = util.getSqlMapClient(); Account account = new Account(); account.setId(1); account.setEmailAddress("e"); account.setFirstName("first"); account.setLastName("last"); sqlMapper.insert("insertAccount", account); util.checkData("select * from account"); List list = sqlMapper.queryForList("getByLike", account); System.out.println(((Account)list.get(0)).getLastName()); } } File: SqlMapConfig.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd"> <sqlMapConfig> <!-- Configure a built-in transaction manager. If you're using an app server, you probably want to use its transaction manager and a managed datasource --> <transactionManager type="JDBC" commitRequired="false"> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="org.hsqldb.jdbcDriver"/> <property name="JDBC.ConnectionURL" value="jdbc:hsqldb:data/tutorial"/> <property name="JDBC.Username" value="sa"/> <property name="JDBC.Password" value=""/> </dataSource> </transactionManager> <!-- List the SQL Map XML files. They can be loaded from the classpath, as they are here (com.domain.data...) --> <sqlMap resource="Account.xml"/> <!-- List more here... <sqlMap resource="com/mydomain/data/Order.xml"/> <sqlMap resource="com/mydomain/data/Documents.xml"/> --> </sqlMapConfig> File: Util.java import java.io.Reader; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.Statement; import com.ibatis.common.resources.Resources; import com.ibatis.sqlmap.client.SqlMapClient; import com.ibatis.sqlmap.client.SqlMapClientBuilder; public class Util { Statement st; public Util() throws Exception{ // Load the JDBC driver. Class.forName("org.hsqldb.jdbcDriver"); System.out.println("Driver Loaded."); // Establish the connection to the database. String url = "jdbc:hsqldb:data/tutorial"; Connection conn = DriverManager.getConnection(url, "sa", ""); System.out.println("Got Connection."); st = conn.createStatement(); } public SqlMapClient getSqlMapClient() throws Exception{ Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml"); SqlMapClient sqlMapper = SqlMapClientBuilder.buildSqlMapClient(reader); reader.close(); return sqlMapper; } public void executeSQLCommand(String sql) throws Exception { st.executeUpdate(sql); } public void checkData(String sql) throws Exception { ResultSet rs = st.executeQuery(sql); ResultSetMetaData metadata = rs.getMetaData(); for (int i = 0; i < metadata.getColumnCount(); i++) { System.out.print("\t"+ metadata.getColumnLabel(i + 1)); } System.out.println("\n----------------------------------"); while (rs.next()) { for (int i = 0; i < metadata.getColumnCount(); i++) { Object value = rs.getObject(i + 1); if (value == null) { System.out.print("\t "); } else { System.out.print("\t"+value.toString().trim()); } } System.out.println(""); } } } File: Account.java public class Account { private int id; private String firstName; private String lastName; private String emailAddress; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getFirstName() { return firstName; } public void setFirstName(String firstName) { this.firstName = firstName; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public String getEmailAddress() { return emailAddress; } public void setEmailAddress(String emailAddress) { this.emailAddress = emailAddress; } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值