`
cppmule
  • 浏览: 447328 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

在Hibernate里面动态切换SChema实现访问不同的数据库的几种方法

    博客分类:
  • J2ee
 
阅读更多

在Hibernate里面动态切换SChema实现访问不同的数据库的几种方法



需求很简单,相同的操作,比如表结构完全相同,程序也完全相同,但需要根据某些条件,分别向不同的schema做操作。
比如,如果当前处理的是A公司,那么向SchemaA 里面保存数据,
如果当前处理的是B公司的,则向SchemaB里面保存数据。

其实就是一套程序,实现后台的动态切换。

我这里提供几种方法,大家自己根据情况考虑,都能实现,注意是实现,不一定适合于正式应用。
方法一: 
在Hibernate里面,有一个配置参数,比如下面这个带Schema配置的映射

[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  4. <!-- 
  5.     Mapping file autogenerated by MyEclipse Persistence Tools 
  6. -->  
  7. <hibernate-mapping>  
  8.     <class name="com.csc.poimanager.dao.Poi" table="POI" schema="P_BEIJING">  
  9.         <id name="poiId" type="java.lang.Long">  
  10.             <column name="POI_ID" precision="10" scale="0" />  
  11.             <generator class="increment" />  
  12.         </id>  
  13.         <property name="cnName" type="java.lang.String">  
  14.             <column name="CN_NAME" length="1000" />  
  15.         </property>  
  16.     </class>  
  17. </hibernate-mapping>  


其中的schema="P_BEIJING"将 Schema写死了。
我们可以不写这部分,而是使用系统的配置参数
<property name="hibernate.default_schema">POI_BEIJING</property>

这样的话,我们的映射文件就变成了
[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  4. <!-- 
  5.     Mapping file autogenerated by MyEclipse Persistence Tools 
  6. -->  
  7. <hibernate-mapping>  
  8.     <class name="com.csc.poimanager.dao.Poi" table="POI"">  
  9.         <id name="poiId" type="java.lang.Long">  
  10.             <column name="POI_ID" precision="10" scale="0" />  
  11.             <generator class="increment" />  
  12.         </id>  
  13.         <property name="cnName" type="java.lang.String">  
  14.             <column name="CN_NAME" length="1000" />  
  15.         </property>  
  16.     </class>  
  17. </hibernate-mapping>  


在调用的时候,动态的指定Schema的参数就行了,比如
[java] view plaincopy
  1. public static SessionFactory rebuildSessionFactoryForChangeSchema(String newSchema){  
  2.        try {  
  3.            Properties p = configuration.getProperties();  
  4.            System.out.println("---" + p);  
  5.            p.put("hibernate.default_schema", newSchema);  
  6.            sessionFactory = configuration.buildSessionFactory();  
  7.            System.out.println(" change schema successfully ......... ");  
  8.            return sessionFactory;  
  9.        } catch (Exception e) {  
  10.            System.err  
  11.                    .println("%%%% rebuild session factory failed for changing schema %%%%");  
  12.            e.printStackTrace();  
  13.            return null;  
  14.        }  
  15.    }  


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


方法二: 
使用多重配置,比如针对天津和北京,我们分别编写对应的映射文件
[xhtml] view plaincopy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  
  4. <!-- 
  5.     Mapping file autogenerated by MyEclipse Persistence Tools 
  6. -->  
  7. <hibernate-mapping>  
  8.     <class name="com.csc.poimanager.dao.Poi" table="POI" id="P_BEIJING" schema="P_BEIJING">  
  9.         <id name="poiId" type="java.lang.Long">  
  10.             <column name="POI_ID" precision="10" scale="0" />  
  11.             <generator class="increment" />  
  12.         </id>  
  13.         <property name="cnName" type="java.lang.String">  
  14.             <column name="CN_NAME" length="1000" />  
  15.         </property>  
  16.     </class>  
  17.     <class name="com.csc.poimanager.dao.Poi" id="P_TIANJIN" table="POI" schema="P_TIANJIN">  
  18.         <id name="poiId" type="java.lang.Long">  
  19.             <column name="POI_ID" precision="10" scale="0" />  
  20.             <generator class="increment" />  
  21.         </id>  
  22.         <property name="cnName" type="java.lang.String">  
  23.             <column name="CN_NAME" length="1000" />  
  24.         </property>  
  25.     </class>  
  26. </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>这样的结构,来做内部的转发。

 


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

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

分享到:
评论

相关推荐

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

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

    JEECG切换数据库方法

    JEECG(Java EE Code Generation platform)作为一个领先的代码生成平台,提供了方便快捷的数据库切换方法。在进行JEECG切换数据库时,支持多种主流数据库系统,例如ORACLE、MySQL和Microsoft SQL Server等。下面将...

    hibernate映射文件生成数据库

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

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

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

    数据库的catalog与schema

    Schema提供了一种方式来组织和隔离数据库中的数据,使得多个用户或应用程序可以在同一个数据库系统中工作,而不会相互干扰。用户可以拥有自己的Schema,每个Schema都有独特的名称,以区分不同的数据集。 在SQL中,...

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

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

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

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

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

    Oracle Streams提供了一种自动化的方法来解决这个问题,尽管它主要设计用于相同schema下的DML(Data Manipulation Language)和DDL同步,但在特定情况下,也可以扩展应用于不同schema间的DDL同步。 首先,我们需要...

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

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

    数据库 schema含义 .doc

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

    使用information_schema.tables查询数据库和数据表信息1

    `information_schema`是一个特殊的系统数据库,它提供了一种方便的方式来获取关于所有数据库、表、列、存储引擎和其他元数据的信息。在这个主题中,我们将深入探讨如何利用`information_schema.tables`来查询数据库...

    oracle中schema指的是什么意思

    在Oracle数据库中,Schema是一个非常重要的概念,它代表了数据库对象的集合,这些对象包括但不限于表格、视图、序列、存储过程、同义词、索引、簇和数据库链接等。Schema是逻辑结构,直接与数据库的数据相关,帮助...

    sample_schema_scripts Oracle 数据库 示例方案脚本(含结构+数据脚本)

    在Oracle数据库中,"方案"(Schema)是一个非常关键的概念,它相当于数据库中的一个用户空间,包含了该用户的所有对象,如表、视图、索引、存储过程等。在本压缩包"sample_schema_scripts"中,包含了一系列用于创建...

    Hibernate动态建表

    "Hibernate动态建表"指的是在应用运行时根据实体类自动生成对应的数据库表结构,这种特性在开发过程中特别有用,尤其是当数据模型频繁变化或者需要快速原型设计时。 **动态表映射原理** Hibernate的动态建表功能...

    hibernate4多租户项目

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

    Hibernate注释深入解析

    总的来说,Hibernate的注释提供了更灵活和便捷的方式来处理对象和数据库之间的映射,而对多个数据库的访问配置则让开发者能够根据需求轻松地切换或管理多个数据库环境。理解和熟练运用这些注解及配置方法,将极大地...

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

    ### 在IDEA中通过MyBatis框架访问达梦数据库 #### 实验背景与目标 随着企业级应用的不断发展,数据库的高效访问与管理成为软件开发过程中不可或缺的一部分。**MyBatis**作为一款优秀的持久层框架,它支持定制化SQL...

    hibernate反向生成数据库表.doc

    为了实现反向工程,即由Java类生成数据库表,我们需要使用Hibernate的工具类`HibernateTool`。这通常涉及到执行以下步骤: 1. 创建一个`hibernate.reveng.xml`文件,指定哪些类应该映射到数据库表,以及任何自定义...

    Springboot整合Quartz实现定时任务数据库动态配置

    本篇文章将详细探讨如何在Spring Boot项目中整合Quartz,并通过MySQL数据库实现定时任务的动态配置。 首先,我们需要在项目中添加依赖。在Spring Boot的`pom.xml`文件中,引入Spring Boot的`spring-boot-starter-...

    Java实现数据库迁移同步

    本文将详细讲解如何使用Java高效地实现数据库迁移同步。 首先,我们需要理解数据库迁移的基本概念。数据库迁移是指将数据从一个数据库系统迁移到另一个数据库系统的过程,或者在同一系统中不同版本之间进行数据转移...

Global site tag (gtag.js) - Google Analytics