hibernateschema:在Hibernate里面动态切换SChema实现访问区别的数据库的几种思路方法

  需求很简单相同操作比如表结构完全相同也完全相同但需要根据某些条件分别向区别schema做操作

  比如如果当前处理是A公司那么向SchemaA 里面保存数据

  如果当前处理是B公司则向SchemaB里面保存数据

  其实就是实现后台动态切换

  我这里提供几种思路方法大家自己根据情况考虑都能实现注意是实现定适合于正式应用

  思路方法:

  在Hibernate里面个配置参数比如下面这个带Schema配置映射

<?xml version="1.0" encoding="utf-8"?>  
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  

<!--  
    Mapping file autogenerated by MyEclipse Persistence Tools  
-->  
<hibernate-mapping>  
    < name="com.csc.poimanager.dao.Poi" table="POI" schema="P_BEIJING">  
        <id name="poiId" type="java.lang.Long">  
            <column name="POI_ID" precision="10" scale="0" />  
            <generator ="increment" />  
        </id>  
        <property name="cnName" type="java.lang.String">  
            <column name="CN_NAME" length="1000" />  
        </property>  
    </>  
</hibernate-mapping>  


  其中schema="P_BEIJING"将 Schema写死了

  我们可以不写这部分而是使用系统配置参数

  <property name="hibernate.default_schema">POI_BEIJING</property>

  这样我们映射文件就变成了

<?xml version="1.0" encoding="utf-8"?>  
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<!--  
    Mapping file autogenerated by MyEclipse Persistence Tools  
-->  
<hibernate-mapping>  
    < name="com.csc.poimanager.dao.Poi" table="POI"">  
        <id name="poiId" type="java.lang.Long">  
            <column name="POI_ID" precision="10" scale="0" />  
            <generator ="increment" />  
        </id>  
        <property name="cnName" type="java.lang.String">  
            <column name="CN_NAME" length="1000" />  
        </property>  
    </>  
</hibernate-mapping>  


  在时候动态指定Schema参数就行了比如

public  SessionFactory rebuildSessionFactoryForChangeSchema(String Schema){   
       try {   
           Properties p = configuration.getProperties;   
           .out.prln("---" + p);   
           p.put("hibernate.default_schema", Schema);   
           sessionFactory = configuration.buildSessionFactory;   
           .out.prln(" change schema successfully ......... ");   
            sessionFactory;   
       } catch (Exception e) {   
           .err   
                   .prln("%%%% rebuild session factory failed for changing schema %%%%");   
           e.prStackTrace;   
            null;   
       }   
   }  


  这个思路方法能实现切换但是我们必须每次都返回个SessionFactory, 否则在并发时候就会出问题hibernate.default_schema系统只有

  思路方法 2:

  使用多重配置比如针对天津和北京我们分别编写对应映射文件

<?xml version="1.0" encoding="utf-8"?>  
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"   
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
<!--  
    Mapping file autogenerated by MyEclipse Persistence Tools  
-->  
<hibernate-mapping>  
    < name="com.csc.poimanager.dao.Poi" table="POI" id="P_BEIJING" schema="P_BEIJING">  
        <id name="poiId" type="java.lang.Long">  
            <column name="POI_ID" precision="10" scale="0" />  
            <generator ="increment" />  
        </id>  
        <property name="cnName" type="java.lang.String">  
            <column name="CN_NAME" length="1000" />  
        </property>  
    </>  
    < name="com.csc.poimanager.dao.Poi" id="P_TIANJIN" table="POI" schema="P_TIANJIN">  
        <id name="poiId" type="java.lang.Long">  
            <column name="POI_ID" precision="10" scale="0" />  
            <generator ="increment" />  
        </id>  
        <property name="cnName" type="java.lang.String">  
            <column name="CN_NAME" length="1000" />  
        </property>  
    </>  
</hibernate-mapping>  




  配置文件除了SCHEMA和ID区别外其它完全相同那么如何使用呢?

  sessionFactory.getBean("P"+placeName);

  这样就可以实现动态

  至于placeName可以通过前台传递过来也可以放到ThreadLocal里面后者更具有通用性而且对以前修改量最少只需要写个getPlaceName得思路方法就行了

  思路方法3:

  修改数据库连接属性将以前指向SchemaA改成指向SchemaB,这需要些高权限账号做这些事情

  其实还有个更简单思路方法那就是自己继承个DataSource,然后在思路方法里面根据ThreadLocal参数返回区别数据连接比如如果是BEIGJING,则返回 BeiJingDatasource连接如果是TIANJIN则返回TianJinDatasource连接

  系统在使用时肯定会从DataSource里面获取连接我们在内部做了分配自然前台运行结果也就分配开了

  提示:在你DataSource里面可以包含Map<String,DataSource>这样结构来做内部转发

  个人整理总结:

  第种思路方法只适合于单机单线程使用

  第 2个思路方法相对技术难度低单配置起来要写多份维护比较麻烦

  第 3个思路方法技术难度高单维护起来简单

  我个人当然是用第 3个思路方法了很有趣



Tags:  oracle切换数据库 切换数据库 数据库schema hibernateschema

延伸阅读

最新评论

发表评论