`
longgangbai
  • 浏览: 7308671 次
  • 性别: 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(模型-视图-控制器)架构模式...

    Ibatis .net框架多数据源配置

    Ibatis .net框架多数据源配置是针对在同一个应用程序中需要连接并操作多个数据库场景的一种解决方案。Ibatis是一个流行的持久层框架,它允许开发者将SQL语句与Java或.NET代码解耦,提供了一种灵活的方式来处理数据库...

Global site tag (gtag.js) - Google Analytics