现在的位置: 首页 > 综合 > 正文

IBatisNet之运行时多数据库切换方案

2012年10月19日 ⁄ 综合 ⁄ 共 2566字 ⁄ 字号 评论关闭
 

先介绍一下我们项目的数据库连结方案,由于某些需要,我们需要根据用户登录界面选择的信息连结到不同的数据库,也就是系统需要在运行时来选择数据库,在不同的数据库间进行切换。

 

这一段一直在关注Nhiernate的东东,觉得一个项目组如果大部分成员对数据库不太熟悉或者项目已经确定需要在多种数据库之间移植或者项目需要一个不错的ORM框架,那么Nhibernate是个不错的选择,可是心里老是犯嘀咕,不敢贸然使用,毕竟才是1.0了,等着第一个吃螃蟹的:)。随后发现了Cuyahoga,下载下来研究了研究,心里有些底气了,希望能在下个项目中用起来,可是老是觉得对于在系统运行时数据库要不停切换的项目真正实施起来的话,不一定很理想,并且不能直接使用存储过程,这些有些不太习惯。管它呢,先熟悉了再说,于是下了一些hibernate的资料来看,hibernate里面的东西真不少,都快有些晕了。一个偶然的机会,在网上发现了一篇文章何为hibernate”,里面提到了ibatis是也是一个数据层框架,不过直接进行sql mappling对数据库特性支持得很好,并且简单好学。

 

于是从网上下载后开始研究,很快便喜欢上了这个框架(可能是我比较懒,这个比较容易学吧)。开始考虑在我们项目中使用它,可是由于我们需要在运行的时候随意切换到不同的数据库,这个需要在切换数据库后,根据配置文件重新生成SqlMapper对象。可是由于缓存的作用单纯地改变数据库的连结字符串内容是起不到效果的。因为为了节省资源,SqlMapper中实现的是单态实例,是一个静态变量。当一个实例创建后,只要不被销毁,它将一直存在,那么修改完配置文件后就不会根据配置文件重新生成实例。

 

从网上查了查IBatisNet关于并发的文章,发现并发中创建实例是通过DomSqlMapBuilder对象来创建的,例子如下:

DomSqlMapBuilder builder = new DomSqlMapBuilder();
SqlMap map = builder.Configure();

文章来源:http://matrix.foresee.cn/blogs/simon/archives/001674.html

 

这样我们来考虑创建一个静态的全局的SqlMapper对象,每当系统登录时将该对象赋为空值,然后再使用对象是采用DomSqlMapBuilder对象创建一个单态实例,下面是我例子的部分代码说明,例子与IbtaisNet的手册例子是类似的。

 

修改了helper.cs,来提供一个静态的SqlMapper对象,写了一个简单的单态函数GetMapper来获得SqlMapper的实例,用来代替原来的Mapper方法,同时修改相应的XXXHelper文件中的方法,将Mapper方法替换为新增的GetMapper方法。

修改如下:

/***********helper.cs*******/
/// <summary>
    
/// 获得dataMapper的实例
    
/// </summary>

    public abstract class Helper {
        
public static SqlMapper myMapper = null;
        
/********
        public SqlMapper Mapper( ) {
            return IBatisNet.DataMapper.Mapper.Instance();
        }
        ***
*/

        
public static SqlMapper GetMapper()
        
{
            
if( myMapper == null )
            
{
                
//myMapper = IBatisNet.DataMapper.Mapper.Instance();
                DomSqlMapBuilder builder = new DomSqlMapBuilder();
                myMapper 
= builder.Configure();
                
//myMapper = IBatisNet.DataMapper.Mapper.Get();
            }

            
return myMapper;
        }

    }

/***********over*******/
修改相应的XXXHelper的方法
/***********UserHelper.cs*******/
        
        …. 

        
public IList SelectAll( ) {
        
//return Mapper().QueryForList("Select",null); //修改前
        
//修改后
                return Helper.GetMapper().QueryForList("Select",null);
        }

        …
/***********over*******/

 

接下来要做的就是在用户登录后根据用户的选项修改providers.config文件中的数据库连结字符串,并且将项目的公共静态变量赋值为空,好让系统根据最新设置的数据库连结字符串生成新的SqlMapper实例。

 

/*******登录处理函数*******/

//根据输入参数设置providers.config的配置属性

//撤销公共变量SqlMapper,以变根据配置文件重新生成SqlMapper

modle.Helper.myMapper = null;

/**********结束***********/

 

这样在每次用户登录后就能根据用户的配置文件来重新获得SqlMapper实例,也就能在系统运行过程中随意切换数据库了。上面只是做了一个简单的实现例子,项目真正用起来的话,应该再做一些完善处理,这里就先不提了。

抱歉!评论已关闭.