`
lqixv
  • 浏览: 218366 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Hibernate编程实现动态切换SChema访问不同的数据库

    博客分类:
  • java
阅读更多

在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>
    <class 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 class="increment" />
        </id>
        <property name="cnName" type="java.lang.String">
            <column name="CN_NAME" length="1000" />
        </property>
    </class>
</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>
    <class name="com.csc.poimanager.dao.Poi" table="POI"">
        <id name="poiId" type="java.lang.Long">
            <column name="POI_ID" precision="10" scale="0" />
            <generator class="increment" />
        </id>
        <property name="cnName" type="java.lang.String">
            <column name="CN_NAME" length="1000" />
        </property>
    </class>
</hibernate-mapping>
 

在调用的时候,动态的指定Schema的参数就行了,比如

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

 这个方法能实现切换,但是我们必须每次都返回一个SessionFactory, 否则在并发的时候就会出问题。因为hibernate.default_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>
    <class 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 class="increment" />
        </id>
        <property name="cnName" type="java.lang.String">
            <column name="CN_NAME" length="1000" />
        </property>
    </class>
    <class 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 class="increment" />
        </id>
        <property name="cnName" type="java.lang.String">
            <column name="CN_NAME" length="1000" />
        </property>
    </class>
</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>这样的结构,来做内部的转发。


个人总结:
第一种方法只适合于单机,单线程使用。
第二个方法,相对技术难度低一点,单配置起来要写多份,维护比较麻烦
第三个方法,技术难度高,单维护起来简单

我个人当然是用第三个方法了,很有趣。

 

本文来自: IT知道网(http://www.itwis.com) 详细出处参考:http://www.itwis.com/html/java/hibernate/20090824/5678.html

分享到:
评论

相关推荐

    SpringBoot+Mybatis实现数据源动态切换

    springboot实现数据源动态切换 注意事项: 1. 该demo采用yml配置数据库信息,注意url标签为jdbc-url 2.项目中加了日志输出,可看到完整执行过程 3.在Service中应用事务时,自定义的注解将失效,解决办法:可将注解...

    JEECG切换数据库方法

    在企业级应用开发和部署过程...最后,操作完成后,重新启动JEECG应用,检查系统日志及应用运行状态,验证数据库切换是否成功,以及应用是否能正常访问新的数据库环境。在确认无误后,JEECG的数据库切换工作便宣告完成。

    数据库的catalog与schema

    在数据库管理中,Catalog(目录)和Schema(模式)是两个非常重要的概念,它们构成了数据库组织和管理的基础。本文将深入探讨这两个概念,以及它们在实际应用中的作用。 首先,让我们来理解什么是Catalog。在数据库...

    hibernate映射文件生成数据库

    在Java开发领域,Hibernate是一个非常流行的对象关系映射(ORM)框架,它允许开发者使用面向对象的方式处理数据库操作。...在实际项目中,开发者可以根据需求灵活调整映射文件,实现数据库的动态管理和更新。

    datanamic DB_Schema_Difftective 数据库结构升级脚本制作工具

    datanamic DB_Schema_Difftective 数据库结构升级脚本制作工具 自动比较 数据库结构差异, 生成DDL脚本 支持多种数据库,数据库结构升级脚本制作的理想工具。 支持oracle, sql server, db2, informix, my sql 。。。...

    hibernate同时配置多个数据库连接

    - **实体类和数据库关联**:为每个数据库的实体类指定相应的`sessionFactory`,可以在实体类的注解`@Entity`中通过`@Table`的`schema`属性来区分数据库,或者在映射文件`hbm.xml`中设置`table`元素的`schema`属性。...

    用streams实现不同数据库下不同schema间DDL同步 上个礼拜有同事问我 ....doc

    本文将探讨如何使用Oracle Streams来实现不同数据库下不同schema之间的DDL(Data Definition Language)同步,这是一个相对复杂但实用的场景。 DDL同步主要涉及到数据库对象如表、视图、索引等的创建、修改和删除...

    自动在数据库中建成表(Hibernate)

    当提到“自动在数据库中建成表”,这是Hibernate的自动反向工程或Schema Generation功能。在实体类中定义的每个类都对应数据库中的一个表,类的属性则对应表的字段。只需在配置文件中指定相应的数据库连接信息,...

    oracle数据库体系结构之一【user和schema】

    首先,从官方文档中可以看到,schema是数据库对象的集合,拥有同一名称的用户拥有该schema,并且该schema中的对象可以分布在不同的表空间中。这样,一个用户可以拥有多个schema,每个schema中都可以包含多个数据库...

    Hibernate注解编程实例

    此外,还指定了数据库方言(dialect),这非常重要,因为不同的数据库系统(如MySQL、Oracle等)有不同的SQL语法,指定正确的方言可以让Hibernate生成适用于当前数据库系统的SQL语句。 ```xml &lt;property name="...

    Hibernate动态建表

    在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者将数据库操作与Java对象模型相结合,简化了数据库编程。"Hibernate动态建表"指的是在应用运行时根据实体类自动生成对应的数据库表...

    Hibernate注释方法描述数据库映射

    ### Hibernate注释方法描述数据库映射 #### 一、概述 Hibernate 是一款强大的对象关系映射(ORM)框架,它简化了 Java 开发者与数据库交互的过程。在 Hibernate 中,可以利用注解来描述实体类与数据库表之间的映射...

    oracle中schema指的是什么意思

    总结来说,Oracle中的Schema是数据库对象的容器,它提供了命名空间,用于区分不同用户或不同业务模块的数据。每个用户都有一个默认的Schema,可以拥有和访问多个Schema中的对象。理解Schema的概念对于管理和维护大型...

    基于struts2和hibernate实现登录和注册功能

    Hibernate则是一款基于Java的持久层框架,主要用于将Java对象映射到关系数据库中。通过结合Struts2和Hibernate,开发者可以快速地开发出功能强大、可维护性强的Web应用程序。 在本文中,我们将详细介绍如何基于...

    数据库 schema含义 .doc

    在一个数据库中可以有多个应用的数据表,这些不同应用的表可以放在不同的 schema 中,同时,每一个 schema 对应一个用户,不同的应用可以以不同的用户连接数据库,这样,一个大数据库就可以根据应用把其表分开来管理...

    Spring/泛型Hibernate的实现

    泛型Hibernate是利用Java泛型特性对Hibernate进行封装的一种方式,目的是为了提供更简洁、灵活且易于维护的数据库访问接口。 ##### 1.1 定义泛型接口IHibernateDao, PK&gt; ```java /** * @author Administrator * ...

    hibernate4多租户项目

    在多租户场景下,Hibernate 4提供了对多租户支持,允许根据不同的租户ID动态切换到对应的数据库Schema,从而实现数据的隔离。 1. **多租户实现方式** Hibernate 4提供了两种主要的多租户实现方式:基于Schema的多...

    hibernate课程笔记.doc

    - **面向对象编程**:Hibernate实现了对象与数据库之间的映射,使得开发者可以使用Java对象进行数据库操作,避免了手动编写SQL语句。 - **简化代码**:相比于JDBC,Hibernate提供了更高的抽象层次,减少了手动管理...

    在IDEA中通过MyBatis框架访问达梦数据库

    通过以上步骤,我们不仅实现了MyBatis框架下对达梦数据库的基本访问,还深入探讨了不同类型关联查询的具体实现方式。这将有助于开发者更好地理解和运用MyBatis框架,提高实际项目中的数据访问效率。

    DB2导出数据库表结构和数据.pdf

    DB2 导出数据库表结构和数据 DB2 是一个关系数据库管理系统,能够高效地存储、管理和检索大量数据。在实际应用中,我们经常需要导出...我们可以使用 db2cmd、db2look 和 db2move 等工具来实现数据库的导出和备份。

Global site tag (gtag.js) - Google Analytics