`
C_J
  • 浏览: 128731 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

无奈修改ibatis源码以支持外部DataSource数据源解决方案(已有其他更好的方案)

阅读更多

不知道楼下的同学自己亲手验证过没有,帖子也竟然被投为"新手帖"

按照楼下同学说的,原来可以通过外围构造一个TransactionManager通过setTxManger()方法赋值过去....从而根本不需要更改ibatis的源码了...这个方法确实比原来的好..

String resource = "sql-map-config.xml";               
        Reader reader = Resources.getResourceAsReader (resource);                
        SqlMapClientImpl sqlMap = (SqlMapClientImpl) SqlMapClientBuilder.buildSqlMapClient(reader);               
        TransactionConfig transactionConfig = new ExternalTransactionConfig();        Properties properties = new Properties();               
        properties.setProperty("SetAutoCommitAllowed", "false");               
        transactionConfig.setDataSource(getDataSource());               
        transactionConfig.setProperties(properties);               
        TransactionManager txManager = new TransactionManager(transactionConfig);               
                       
        sqlMap.getDelegate().setTxManager(txManager);    



今天验证这个方案发现: 
  transactionConfig.setProperties(properties);     
错误:The method setProperties(Properties) is undefined for the type TransactionConfig


以上方案修改如下:

 把transactionConfig.setProperties(properties); 更改为transactionConfig.initialize(properties);



题记:

    有时候在做项目的时候,Ds需要被其他应用监控,需要用到外部的DataSource,而不能用框架本身的DS..而修改IBATIS的XML配置文件也做不到,无奈今天只能更改源码了...

下面大概简单介绍下各种配置文件和源码.

ibatis的xml配置文件 
    类似很多dao框架一样, 这个配置有oscache配置,datasource数据库连接池配置,sqlMap映射文件配置,详细配置请看博客或者google吧,这里就不详述了..但重点说下datasource配置:ibatis2.3.0提供3类DS,分别为SIMPLE,DBCP,JNDI..配置方法大同小异.. 配置好后,这样在ibatis初始化的时候就会建立相应的ds和连接池了.

问题所在
 
   1,ibatis可以读取任意一个xml文件,但xml的格式是规定死的..如配置文件必须以 打头等等.

   2,xml配置可兼容jndi规范,但是有时候项目中并没有写成jndi,而是以另一种xml配置文件存在.

   3,项目中需要用到其他ds,不允许新创建.

解决方案 
   基于以上的状况,我没有找到更好的解决方案,所以只能更改源码,思路是ibatis不构建自己的ds对象,而是公用其他模块的ds对象,思路很明确,所以代码也好改,原ibatis配置文件不配置ds,外部ds对象作为参数传入ibatis..

具体方法 
  总共修改2个类,主要是改下参数和赋值了ds对象而已,也没有仔细研究过源码,有不对的地方还请海涵``

//修改SqlMapClientBuilder.java               
              
/** 新增方法,把外部的ds传进去**/              
              
 /**          
   * add ds parameter by cj.yangjun@gmail.com          
   * @param reader          
   * @param ds          
   * @param forceCommit          
   * @return          
   */              
  public static SqlMapClient buildSqlMapClient(Reader reader,DataSource ds,boolean forceCommit) {               
//    return new XmlSqlMapClientBuilder().buildSqlMap(reader);               
    return new SqlMapConfigParser().parse(reader,ds,forceCommit);               
  }               
              
              
//修改SqlMapConfigParser.java               
              
              
/**parser是一个NodeletParser 类,The NodeletParser is a callback based parser similar to SAX.           
         
vars是作者构建的Variables,这里有个疑问**/              
 public SqlMapClient parse(Reader reader) {               
    try {               
      if (vars.sqlMapConfigConv != null) {               
         System.out.println("null");               
        reader = vars.sqlMapConfigConv.convertXml(reader);               
      }               
              
      usingStreams = false;               
                     
      parser.parse(reader);               
                     
      return vars.client;               
    } catch (Exception e) {               
      throw new RuntimeException("Error occurred.  Cause: " + e, e);               
    }               
  }               
              
              
/**新增方法,把外围ds传进入,并且赋值**/              
              
 public SqlMapClient parse(Reader reader,DataSource ds,boolean forceCommit){               
    vars.dataSource=ds;               
      vars.errorCtx.setActivity("configuring the transaction manager");               
      String type = "jdbc";               
      type = vars.typeHandlerFactory.resolveAlias(type);               
              
      TransactionManager txManager = null;//ibatis的思路是要构造一个TransactionManager 对象               
      try {               
          vars.errorCtx.setMoreInfo("Check the transaction manager type or class.");               
      TransactionConfig config = (TransactionConfig) Resources.instantiate(type);//需要构造一个JDBC类型TransactionConfig我们的ds等部分信息去填充这个TransactionConfig,JDBC的其他属性由这个config初始化               
         config.setDataSource(vars.dataSource);               
          config.setMaximumConcurrentTransactions(vars.client.getDelegate().getMaxTransactions());               
          vars.errorCtx.setMoreInfo("Check the transactio nmanager properties or configuration.");               
              config.initialize(vars.txProps);               
          vars.errorCtx.setMoreInfo(null);               
          txManager = new TransactionManager(config);               
              txManager.setForceCommit(forceCommit);               
      } catch (Exception e) {               
        if (e instanceof SqlMapException) {               
          throw (SqlMapException) e;               
        } else {               
          throw new SqlMapException("Error initializing TransactionManager.  Could not instantiate TransactionConfig.  Cause: " + e, e);               
        }               
      }               
              
      vars.client.getDelegate().setTxManager(txManager);// 根据这个manager初始化一些事务控制的对象               
                   
    return parse(reader);//parser是一个NodeletParser ,The NodeletParser is a callback based parser similar to SAX. 读取其他内容并初始化...               
  }       


修改过,简单测试下,应该是可以用的..

疑问
在看的过程对有个地方有个疑问:
有如下结构关系:
public class SqlMapConfigParser extends BaseParser{

...

}

public abstract class BaseParser { 
  protected final Variables vars; 

   protected static class Variables {

          public ExtendedSqlMapClient client;
          public SqlMapExecutorDelegate delegate;
          public TypeHandlerFactory typeHandlerFactory;
          public DataSource dataSource;

         ......

   }

}

其中Variables 的注释如下:

/**
   * Variables the parser uses.  This "struct" like class is necessary because
   * anonymous inner classes do not have access to non-final member fields of the parent class.
   * This way, we can make the Variables instance final, and use all of its public fields as
   * variables for parsing state.
   */
我不明白作者精心设计这个"struct"的目的是什么呢?没看明白这里的
because
   * anonymous inner classes do not have access to non-final member fields of the parent class.

 

分享到:
评论
7 楼 mmwy 2010-06-15  
超级潜水员 写道
现在啥年代了,连spring都没有看过!!! 自己去看看吧!!!

现在啥年代了,没有spring的项目多得是,自己去看看吧!
6 楼 C_J 2009-11-21  
楼上的真会说笑话```
5 楼 超级潜水员 2009-11-15  
现在啥年代了,连spring都没有看过!!! 自己去看看吧!!!
4 楼 C_J 2009-11-15  
为什么我提的疑问没人回答呢?


楼上的说"新手帖",想必你应该都明白吧?  那能否能帮我解答呢?
3 楼 超级潜水员 2009-11-12  
新手帖!!!
2 楼 C_J 2009-11-12  
storm0912 写道
不知道LZ的外部数据源是指什么样的DS?


其他模块构造的任意一个Ds对象...
1 楼 bill.end 2009-11-12  
作用域的问题吧

相关推荐

    ibatis源码,ibatis源码 ibatis源码 ibatis源码

    《深入解析iBatis源码》 iBatis,一个优秀的Java持久层框架,以其轻量级、灵活的特性在众多ORM(Object-Relational Mapping)框架中独树一帜。iBatis的核心在于它的SQL映射机制,它将数据库操作与业务逻辑解耦,...

    装饰模式 切换 ibatis 多数据源

    总结来说,装饰模式在切换iBatis多数据源的应用中,起到了扩展和动态切换的作用,它允许我们在不修改原有数据源实现的基础上,通过组合的方式增加新的功能,实现了在运行时选择不同数据源的目标,同时保持了代码的...

    Ibatis和Mybatis实例源码

    Ibatis的核心概念是SqlMapConfig.xml配置文件,它包含了数据源、事务管理器等关键设置。在源码中,可以看到Ibatis如何通过SqlSessionFactory构建会话工厂,以及SqlSession接口如何处理数据库交互。SqlMapper接口提供...

    ibatis_spring源代码

    综上所述,`iBatis_Spring`源代码的学习涵盖了数据库连接、SQL映射、事务处理、依赖注入等多个核心概念,通过深入理解这些知识点,开发者可以更好地掌握企业级Java应用的开发技巧。在实际项目中,这样的整合可以带来...

    SpringIbatis源码

    本项目结合Spring 3.1.4和iBatis-2.3.3.720版本,深入探讨了这两者的集成与应用,旨在提供一个高效、灵活的数据访问解决方案。 首先,我们来看环境配置。本项目选择了eclipse 3作为开发工具,这是一款广泛使用的...

    iBATIS-SqlMaps2入门代码文档

    - `<dataSource>`元素定义了数据源类型为“POOLED”,即使用Jakarta DBCP进行连接池管理。 - 使用`<property>`元素配置数据库驱动、URL、用户名和密码。 - `<sqlMap>`元素指定外部映射文件的位置,用于定义具体的SQL...

    ibatis实战之基础环境搭建(源码).zip

    iBatis的核心是SqlMapConfig.xml配置文件,它包含了数据源、事务管理器、SqlMapClient以及其他的全局设置。在搭建环境中,我们需要创建这个配置文件,并正确配置数据库连接信息。 1. **环境准备**: - 安装Java ...

    Ibatis+MySql(含对应数据库sql) 源码

    【Ibatis+MySql源码解析】 在Java开发中,Ibatis作为一个轻量级的持久层框架,被广泛用于数据库操作。它与MySql数据库的结合,为开发者提供了灵活的数据访问方式,使得数据库操作更加简单易用。Ibatis 2.3版本与...

    spring-ibatis简单集成

    在IT行业中,Spring框架与iBatis的集成是常见的数据访问解决方案,特别是在Java Web开发中。这个集成将Spring的依赖注入特性和iBatis的SQL映射功能相结合,提供了高效且灵活的数据操作方式。让我们深入探讨一下这个...

    ibatis-2.3

    Ibatis支持多种数据库,如MySQL、Oracle、SQL Server等,通过配置数据源,可以灵活切换不同的数据库环境。例如,通过`DataSource`配置,我们可以指定数据库驱动、连接URL、用户名和密码,实现与数据库的连接。 ...

    ibatis 连接字符串 SqlMapConfig.xml

    这个文件是iBATIS的核心配置文件,它包含了数据源、事务管理器、SQL映射文件等信息,确保了应用程序能够正确地连接到数据库并执行SQL语句。 在SqlMapConfig.xml中,最重要的部分是数据库连接的配置,通常包括以下几...

    ibatis2小例子(转)

    描述虽然为空,但根据标题和标签,我们可以推测博主可能在博文中分享了他们对iBatis2的理解和应用经验,可能包括了一些实用技巧或常见问题的解决方案。 标签 "源码" 和 "工具" 提示我们,内容可能包含了源代码示例...

    iBatis入门(三)

    对于进阶用户,了解iBatis的源码有助于更好地理解和优化应用程序。源码中包含了很多关键组件,如`Executor`执行器、`StatementHandler`语句处理器、`ParameterHandler`参数处理器等。通过对这些组件的工作原理的理解...

    ibatis配置详解

    2. **数据源(DataSource)**:Ibatis支持多种数据源,包括JDBC、C3P0、DBCP等。数据源负责管理数据库连接,确保在多线程环境下高效、安全地操作数据库。 3. **事务管理器(Transaction Manager)**:事务管理器...

    ibatis 配置 连上 h2 数据库

    2. 配置数据源:在项目的配置文件(如application.properties或mybatis-config.xml)中指定H2数据库的连接信息。例如: ```properties # application.properties spring.datasource.url=jdbc:h2:mem:testdb;DB_...

    ibatis--dao的应用

    首先,Ibatis的配置文件(通常为`SqlMapConfig.xml`)是整个框架的入口,它包含了数据源配置、事务管理器和其他全局设置。在这个文件中,你可以定义多个数据源,每个数据源对应一个`<transactionManager>`和`...

    ibatis与spring整合实例(附源码)

    2. **配置iBatis**:创建`sqlMapConfig.xml`文件,定义数据源、事务管理器以及映射文件的位置。这里会涉及到DataSource的配置,例如使用Apache的DBCP或C3P0连接池。 3. **配置Spring**:在Spring的配置文件(如`...

    Spring集成iBatis

    **Spring集成iBatis详解** 在Java开发中,Spring框架以其强大的依赖注入和面向切面编程能力被广泛应用,而iBatis作为一个轻量...同时,通过源码阅读和工具辅助,我们可以更好地理解和优化这种集成方式,提升系统性能。

    struts spring ibatis mysql 整合 实例 数据库 源码

    2. 设计和创建Spring的配置文件(如applicationContext.xml),声明Bean,包括Service层、DAO层以及相应的数据源和事务管理器。 3. 集成iBatis,配置SqlMapConfig.xml,编写Mapper接口和XML映射文件,定义SQL语句。 ...

Global site tag (gtag.js) - Google Analytics