`
longgangbai
  • 浏览: 7332006 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

IBatis框架的一些问题的扩展(二)

阅读更多

            项目中由于Ibatis自身的缓存的鸡肋性(Ibatis自身的缓存是查询字符串和相应的结果的缓存,效率非常有效并且很容易占用内存,采用大量的缓存时,Ibatis严重的影响效率),进行相应的扩展的采用OSCache进行对象缓存。

 iBatis整理——EhCache支持扩展

项目完结,整理一些技术方面的相关收获。 
已经记不得EhCacheController这个实现类最早来自于那里了,总之稍加修改后非常有效果,大家就这么用了,感谢最初开源的那位兄弟。这里,主要是做个记录,为以后类似扩展(譬如Memcached)做个准备。 

iBatis提供CacheController接口,用于实现第三方缓存架构的扩展。 
这里以iBatis 2.3.0,EhCache 1.2.3版本为基础,构建iBatis+EhCache实现。 

EhCacheController类: 

Java代码   收藏代码
  1. package com.ibatis.sqlmap.engine.cache.ehcache;  
  2.   
  3. import java.net.URL;  
  4. import java.util.Properties;  
  5.   
  6. import net.sf.ehcache.Cache;  
  7. import net.sf.ehcache.CacheManager;  
  8. import net.sf.ehcache.Element;  
  9.   
  10. import com.ibatis.sqlmap.engine.cache.CacheController;  
  11. import com.ibatis.sqlmap.engine.cache.CacheModel;  
  12.   
  13. /** 
  14.  * EhCache Implementation of the 
  15.  * {@link com.ibatis.sqlmap.engine.cache.CacheController} interface to be able 
  16.  * to use EhCache as a cache implementation in iBatis. You can configure your 
  17.  * cache model as follows, by example, in your sqlMapping files: 
  18.  *  
  19.  * <pre> 
  20.  * <code> 
  21.  * <cacheModel id="myCache" readOnly="true" serialize="false" 
  22.  *  type="com.ibatis.sqlmap.engine.cache.EhCacheController" >  
  23.  *  <property name="configLocation" 
  24.  *      value="/path-to-ehcache.xml"/>  
  25.  * </cacheModel> </code> 
  26.  * </pre> 
  27.  *  
  28.  * Alternatively, you can use a type alias in your type attribute and defining 
  29.  * the class with a <code><typeAlias></code> declaration: 
  30.  *  
  31.  * <pre> 
  32.  * <code> 
  33.  * <sqlMapConfig> 
  34.  *  <typeAlias alias="EHCACHE"  
  35.  *      type="com.ibatis.sqlmap.engine.cache.ehcache.EhCacheController" /> 
  36.  * </sqlMapConfig> 
  37.  * </code> 
  38.  * </pre> 
  39.  *  
  40.  */  
  41. public class EhCacheController implements CacheController {  
  42.   
  43.     /** 
  44.      * The EhCache CacheManager. 
  45.      */  
  46.     private CacheManager cacheManager;  
  47.   
  48.     public static final String CONFIG_LOCATION = "configLocation";  
  49.   
  50.     /** 
  51.      * Default Configure Location 
  52.      */  
  53.     public static final String DEFAULT_CONFIG_LOCATION = "/ehcache.xml";  
  54.   
  55.     /** 
  56.      * Flush a cache model. 
  57.      *  
  58.      * @param cacheModel 
  59.      *            - the model to flush. 
  60.      */  
  61.     public void flush(CacheModel cacheModel) {  
  62.         getCache(cacheModel).removeAll();  
  63.     }  
  64.   
  65.     /** 
  66.      * Get an object from a cache model. 
  67.      *  
  68.      * @param cacheModel 
  69.      *            - the model. 
  70.      * @param key 
  71.      *            - the key to the object. 
  72.      * @return the object if in the cache, or null(?). 
  73.      */  
  74.     public Object getObject(CacheModel cacheModel, Object key) {  
  75.         Object result = null;  
  76.         Element element = getCache(cacheModel).get(key);  
  77.         if (element != null) {  
  78.             result = element.getObjectValue();  
  79.         }  
  80.         return result;  
  81.   
  82.     }  
  83.   
  84.     /** 
  85.      * Put an object into a cache model. 
  86.      *  
  87.      * @param cacheModel 
  88.      *            - the model to add the object to. 
  89.      * @param key 
  90.      *            - the key to the object. 
  91.      * @param object 
  92.      *            - the object to add. 
  93.      */  
  94.     public void putObject(CacheModel cacheModel, Object key, Object object) {  
  95.         getCache(cacheModel).put(new Element(key, object));  
  96.     }  
  97.   
  98.     /** 
  99.      * Remove an object from a cache model. 
  100.      *  
  101.      * @param cacheModel 
  102.      *            - the model to remove the object from. 
  103.      * @param key 
  104.      *            - the key to the object. 
  105.      * @return the removed object(?). 
  106.      */  
  107.     public Object removeObject(CacheModel cacheModel, Object key) {  
  108.         Object result = this.getObject(cacheModel, key);  
  109.         getCache(cacheModel).remove(key);  
  110.         return result;  
  111.     }  
  112.   
  113.     /** 
  114.      * Gets an EH Cache based on an iBatis cache Model. 
  115.      *  
  116.      * @param cacheModel 
  117.      *            - the cache model. 
  118.      * @return the EH Cache. 
  119.      */  
  120.     private Cache getCache(CacheModel cacheModel) {  
  121.         String cacheName = cacheModel.getId();  
  122.         Cache cache = cacheManager.getCache(cacheName);  
  123.         return cache;  
  124.     }  
  125.   
  126.     /** 
  127.      * Shut down the EH Cache CacheManager. 
  128.      */  
  129.     public void finalize() {  
  130.         if (cacheManager != null) {  
  131.             cacheManager.shutdown();  
  132.         }  
  133.     }  
  134.   
  135.     /** 
  136.      * Configure a cache controller. Initialize the EH Cache Manager as a 
  137.      * singleton. 
  138.      *  
  139.      * @param props 
  140.      *            - the properties object continaing configuration information. 
  141.      */  
  142.     @Override  
  143.     public void configure(Properties props) {  
  144.         String configLocation = props.getProperty(CONFIG_LOCATION);  
  145.         // if can not found ehcache.xml from configLocaion,  
  146.         // use default configure file.  
  147.         if (configLocation == null) {  
  148.             configLocation = DEFAULT_CONFIG_LOCATION;  
  149.         }  
  150.         URL url = getClass().getResource(configLocation);  
  151.         cacheManager = CacheManager.create(url);  
  152.     }  
  153. }  



这里默认在根目录下获取ehcache.xml文件,可以通过cacheModel配置进行修改。 

在SqlMapConfig.xml文件中配置一个别名,作为全局变量,供其余SqlMap使用。 

Xml代码   收藏代码
  1. <typeAlias  
  2.         alias="EHCACHE"  
  3.         type="com.ibatis.sqlmap.engine.cache.ehcache.EhCacheController" />  


顺便提一句,要使用缓存注意SqlMapConfig.xml文件中settings节点配置cacheModelsEnabledtrue 

Xml代码   收藏代码
  1. <settings  
  2.     cacheModelsEnabled="true"  
  3.     useStatementNamespaces="true"   
  4.     ...   
  5. />  


接下来,在SqlMap.xml文件中的cacheModel 

Xml代码   收藏代码
  1. <cacheModel  
  2.     id="cache"  
  3.     type="EHCACHE">  
  4. ...  
  5. </cacheModel>  


如果要变更ehcache.xml文件路径为/config/ehcache.xml,可以在上述节点中下入如下代码: 

Xml代码   收藏代码
  1. <property name="configLocation" value="/config/ehcache.xml" />   



然后,就可以通过ehcache.xml控制ehcache缓存了! 

举例说明iBatis SqlMap & ehcahce.xml,以免有些兄弟混淆! 

以Account类为示例,在SqlMap中的配置为: 

Xml代码   收藏代码
  1. <?xml version="1.0" encoding="UTF-8" ?>  
  2. <!DOCTYPE sqlMap  
  3.     PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"  
  4.     "http://ibatis.apache.org/dtd/sql-map-2.dtd">  
  5. <sqlMap  
  6.     namespace="Account">  
  7.     <cacheModel  
  8.         id="cache"  
  9.         type="EHCACHE">  
  10.         <flushInterval  
  11.             hours="1" />  
  12.         <!-- flush操作,需要指明 Namespace -->  
  13.         <flushOnExecute  
  14.             statement="Account.create" />  
  15.     </cacheModel>  
  16.     <typeAlias  
  17.         alias="account"  
  18.         type="org.zlex.acl.Account" />  
  19.     <resultMap  
  20.         id="accountMap"  
  21.         class="account">  
  22.         <result  
  23.             property="accountId"  
  24.             column="accountId" />  
  25.         <result  
  26.             property="accountName"  
  27.             column="accountName" />  
  28.         <result  
  29.             property="mail"  
  30.             column="mail" />  
  31.         <result  
  32.             property="realName"  
  33.             column="realName" />  
  34.         <result  
  35.             property="status"  
  36.             column="status" />  
  37.         <result  
  38.             property="lastLoginTime"  
  39.             column="lastLoginTime" />  
  40.     </resultMap>  
  41.     <select  
  42.         id="readByAccountName"  
  43.         parameterClass="string"  
  44.         resultMap="accountMap"  
  45.         cacheModel="cache">  
  46.         <![CDATA[ 
  47.             SELECT  
  48.                 accountId, 
  49.                 accountName, 
  50.                 mail, 
  51.                 realName, 
  52.                 status, 
  53.                 lastLoginTime 
  54.             FROM  
  55.                 acl_account 
  56.             WHERE  
  57.                 accountName = #accountName#  
  58.         ]]>  
  59.     </select>  
  60.     <insert  
  61.         id="create"  
  62.         parameterClass="account">  
  63.         <![CDATA[ 
  64.             INSERT INTO  
  65.                 acl_account( 
  66.                 accountName, 
  67.                 mail, 
  68.                 realName, 
  69.                 status, 
  70.                 lastLoginTime 
  71.                 )  
  72.             VALUES ( 
  73.                     #accountName#, 
  74.                     #mail#, 
  75.                     #realName#, 
  76.                     #status#, 
  77.                     #lastLoginTime# 
  78.                 ) 
  79.         ]]>  
  80.         <selectKey  
  81.             resultClass="long"  
  82.             keyProperty="accountId">  
  83.             <![CDATA[select LAST_INSERT_ID() as id ]]>  
  84.         </selectKey>  
  85.     </insert>  
  86. </sqlMap>  


注意: 

引用


<select 
id="readByAccountName" 
parameterClass="string" 
resultMap="accountMap" 
cacheModel="cache"> 


这里的cacheModel="cache",对应的在ehcache.xml中就应该是: 

Xml代码   收藏代码
  1. <cache   
  2.     name="Account.cache"   
  3.     maxElementsInMemory="10000"   
  4.     eternal="false"  
  5.     maxElementsOnDisk="1000"   
  6.     overflowToDisk="true"   
  7.     timeToIdleSeconds="300"  
  8.     />  


因为,我使用了useStatementNamespaces="true"

package easyway.tbs.framework.cache;

import java.io.Serializable;

import java.util.Set;

/**

 * cache 通用接口

 *

 * @author longgangbai

 */

publicinterface Cache extends Serializable {

    public Object get(Object key);

    publicvoid put(Object key, Object value);

    publicvoid remove(Object key);

    publicvoid clear();

    publicint size();

    @SuppressWarnings("unchecked")

    public Set keys();

    @SuppressWarnings("unchecked")

    public Set values();

}

package easyway.tbs.framework.cache;

import easyway.tbs.framework.app.exceptions.SystemException;

/**

 * CacheManager提供和维护Cache生命周期实例

 *

 * @authorlonggangbai

 */

 

publicinterface CacheManager {

    /**

     * 根据指定的名称获取Cache实现,

     * 如果指定的名称的cache还不存,

     * 则以名称建立一个cache

     * 并返回cache对象

     *  

     * @param name 要获得的cache名称.

     * @return Cache 返回指定名称的cache实例   

     */

    public Cache getCache(String name)  throws SystemException;

    publicvoid destroy(String name) throws SystemException;

    }

package easyway.tbs.framework.cache;

import java.util.HashMap;

import java.util.Map;

import easyway.tbs.framework.app.exceptions.SystemException;

/**

 * 默认的内存缓存管理器

 *

 * @authorlonggangbai

 */

 

publicclass DefaultCacheManager implements CacheManager  {

 

    /**

     * DefaultCacheManager维护内存缓存对象

     */

    privatestaticfinal Map<String, Cache> caches = new HashMap<String, Cache>();

    /*

     * 获得指定的名称cache对象

     *

     * @see

     * easyway.tbs.framework.app.cache.CacheManager#getCache(java.lang.String)

     */

    public Cache getCache(String name) {

        if (name == null) {

            thrownew SystemException("cache-001", "缓存名称不能为空");

        }

        Cache cache;

        synchronized (caches) {

            cache = caches.get(name);

            if (cache == null) {

                cache = new SoftHashMapCache(name);

                caches.put(name, cache);

            }

        }

        return cache;

    }

 

    publicvoid destroy(String name) throws SystemException {

       

        synchronized (caches) {    

                caches.remove(name);

            }

        }

    }

     项目建议:实现Ibatis的缓存的扩展建议采用mechcache或者xmechcache的分布式缓存功能,mechcache为分布式的缓存,性能各方面的比较优越。使用OSCache可以参考Spring或者JforumCache的设计思路。

 

 

分享到:
评论

相关推荐

    ibatis框架简单应用

    Ibatis 主要解决的问题是简化 JDBC 的繁琐工作,通过 XML 或注解方式配置 SQL 语句,使得业务逻辑和数据访问层之间有更好的解耦。 **核心概念** 1. **SqlMapConfig.xml**: 这是 Ibatis 的全局配置文件,包含了数据...

    ssh2+ibatis框架

    SSH2+IBATIS框架是Java开发中常用的一套企业级应用开发框架组合,它将Spring、Hibernate、Struts2和iBatis等组件融合在一起,以提高开发效率和实现松耦合。以下是对这些框架及其整合方式的详细说明: **Spring框架*...

    SpringMvc+ibatis框架

    SpringMvc和iBatis是Java开发中常用的两个框架,它们在Web应用开发中扮演着重要的角色。SpringMvc作为Spring框架的一部分,主要用于处理HTTP请求和视图的渲染,而iBatis则是一个轻量级的数据访问层框架,它将SQL与...

    ibatis 框架原理实现

    在这个自己编写的Ibatis框架实现中,我们可以看到类似的思路和核心功能。 1. **XML配置文件**: XML文件是Ibatis框架的核心,它存储了SQL语句、参数映射以及结果集映射等信息。在`sqlmap`目录下,可能包含了多个...

    SpringMvc+Ibatis框架

    iBatis框架则提供了一种将SQL语句与Java代码分离的方式,通过XML配置文件或注解来定义SQL语句,使得数据库操作更易于维护和扩展。它的核心概念有SqlSessionFactory、SqlSession和Mapper。SqlSessionFactory创建...

    springmvc+ibatis 框架

    Spring MVC 和 iBatis 是两个在 Java Web 开发中广泛使用的框架,它们组合起来可以构建高效、灵活且可维护的Web应用程序。Spring MVC 作为Spring框架的一部分,是用于构建前端控制器(DispatcherServlet)的MVC设计...

    struts2+spring+Ibatis框架包

    这个“struts2+spring+iBatis框架包”集成了这三个框架,使得开发者能够快速构建基于MVC(Model-View-Controller)模式的Web应用。 Struts2作为MVC框架,负责处理应用程序的控制逻辑。它通过Action类和配置文件定义...

    struts+spring+ibatis框架集合教程

    3. iBatis框架:iBatis是一个SQL映射框架,它将SQL语句与Java代码分离,提供了一种灵活的方式来执行数据库操作。通过XML或注解方式定义SQL语句,iBatis可以动态地生成和执行SQL,避免了传统的JDBC代码繁琐的模板式...

    struts+spring+ibatis框架

    Struts、Spring和iBatis是Java开发中常用的三大开源框架,它们各自负责应用程序的不同层面,共同构建了一个灵活且强大的企业级应用开发解决方案。这里,我们深入探讨这三个框架以及它们如何协同工作。 **Struts框架...

    spring struts ibatis 开发框架

    总的来说,Spring Struts iBatis框架组合提供了一个强大而灵活的开发环境,适合开发大型、复杂的企业级应用。通过熟练掌握这三个框架,开发者可以构建出符合现代开发标准的、易于维护的系统。在学习和使用过程中,...

    iBATIS框架源码剖析-任钢

    《iBATIS框架源码剖析》这本书,作者任钢深入探讨了iBATIS的核心机制和实现原理,以下是对该框架的一些关键知识点的详细阐述。 1. **动态SQL**:iBATIS的一大亮点是它的动态SQL功能。通过在XML映射文件中使用条件...

    ibatis框架源代码

    通过对这些组件的源码阅读,我们可以学习到如何设计一个高效、可扩展的持久层框架,同时也可以借鉴Ibatis的优秀实践,比如它的动态SQL支持、缓存机制以及事务管理等。此外,源码中的异常处理、日志记录、单元测试等...

    struts,ibatis框架

    iBatis框架: 1. **SQL映射**:iBatis的核心是XML或注解方式定义的SQL语句,将SQL与Java代码分离,增强了可读性和维护性。 2. **动态SQL**:iBatis支持动态SQL,允许在SQL语句中根据条件动态生成不同的查询,提高...

    ibatis框架实现的增删改查

    本篇文章将深入探讨如何使用Ibatis框架实现对`student`表的增删改查操作,包括模糊查询以及利用序列自动生成主键。 首先,我们来理解Ibatis的基本概念。Ibatis是由Apache基金会维护的一个开源项目,它是一个SQL映射...

    传智播客ibatis教程_ibatis优点总结

    6. **良好的扩展性**:iBATIS允许开发者通过插件进行扩展,例如,可以通过拦截器实现日志记录、性能监控等功能。 7. **与各种数据库兼容**:iBATIS不绑定特定的数据库,可以方便地切换不同的数据库系统,适应不同的...

    Ibatis框架三层架构项目源码.rar

    Ibatis框架是一个轻量级的Java持久层框架,它提供了SQL映射功能,将复杂的SQL语句与Java代码分离,使开发更为灵活高效。在这个"Ibatis框架三层架构项目"中,我们可以看到它按照标准的软件工程设计模式进行了分层,...

    struts2+spring+ibatis框架实例

    "struts2+spring+ibatis框架实例"是基于这三个框架的一个集成示例,它利用MySQL作为后端数据库。下面我们将详细探讨这三个框架及其在实际项目中的应用。 **Struts2框架** Struts2是MVC(模型-视图-控制器)架构模式...

Global site tag (gtag.js) - Google Analytics