`
cppmule
  • 浏览: 454650 次
  • 性别: 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>这样的结构,来做内部的转发。

 


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

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

分享到:
评论

相关推荐

    JEECG切换数据库方法

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

    spring整合hibernate

    2. **数据访问抽象层**:Spring 为不同的数据访问技术提供了一个统一的抽象层,使得开发者可以在不改变业务逻辑的情况下切换底层的数据访问技术。这意味着如果需要从 JDBC 切换到 Hibernate 或其他 ORM 工具,只需...

    JAVAJPAJPA学习手册.doc

    事实上,它是用来规范现有的ORM技术,确保应用程序能够在不同的持久化提供商之间无缝切换。这意味着,在使用JPA开发的应用中,仍然会使用到如Hibernate、TopLink等具体的ORM框架,但这样的应用将不再依赖于特定的...

    野生动物目标检测数据集.zip

    数据集介绍:野生动物目标检测数据集 一、基础信息 数据集名称:野生动物目标检测数据集 图片数量: - 训练集:4,181张图片 - 验证集:1,212张图片 - 测试集:610张图片 总计:6,003张航拍及自然场景图片 分类类别: 涵盖23类野生动物,包括: - 濒危物种(北极熊、犀牛、熊猫) - 大型哺乳动物(大象、河马、长颈鹿) - 猛禽类(鹰、鹦鹉、企鹅) - 食肉动物(狮子、猎豹、美洲豹) - 草食动物(斑马、鹿、山羊) 标注格式: YOLO格式标注,包含边界框坐标与类别标签,适配主流目标检测框架。 数据特性: 航拍视角与地面视角相结合,包含动物群体活动和个体行为场景。 二、适用场景 生态保护监测系统: 构建野生动物种群识别系统,支持自然保护区自动监测动物迁徙和栖息地活动。 智能林业管理: 集成至森林巡护无人机系统,实时检测濒危物种并预警盗猎行为。 动物行为研究: 为科研机构提供标注数据支撑,辅助研究动物种群分布与行为特征。 自然纪录片制作: AI预处理工具开发,快速定位视频素材中的特定物种片段。 教育科普应用: 用于野生动物识别教育软件,支持互动式物种学习功能开发。 三、数据集优势 物种覆盖全面: 包含非洲草原系、极地系、森林系等23类特色动物,特别涵盖10种IUCN红色名录物种。 多场景适配: 整合航拍与地面视角数据,支持开发不同观测高度的检测模型。 标注质量可靠: 经动物学专家校验,确保复杂场景(群体/遮挡)下的标注准确性。 模型兼容性强: 原生YOLO格式可直接应用于YOLOv5/v7/v8等系列模型训练。 生态研究价值: 特别包含熊科动物(棕熊/北极熊/熊猫)细分类别,支持濒危物种保护研究。

    云计算的起源与发展.pptx

    云计算的起源与发展.pptx

    软件工程过程资料模板界面设计说明书.doc

    软件工程过程资料模板界面设计说明书.doc

    职称计算机xp题库.doc

    职称计算机xp题库.doc

    网站运营管理手册.docx

    网站运营管理手册.docx

    新版计算机基础题库资料.doc

    新版计算机基础题库资料.doc

    计算机等级考试公共基础知识模拟试题.doc

    计算机等级考试公共基础知识模拟试题.doc

    自动化控制施工组织计划.doc

    自动化控制施工组织计划.doc

    电动汽车锂离子电池组热管理仿真:基于COMSOL的热不平衡与流场冷却技术研究 热管理

    内容概要:本文探讨了电动汽车锂离子电池组热管理仿真的可靠性设计,重点研究了热不平衡和流场冷却技术。文中详细介绍了利用COMSOL 6.1进行流场冷却仿真,通过等效热网络模型预测温升,并针对仿真过程中遇到的问题(如湍流非线性效应、流道截面突变)进行了优化。此外,还讨论了电池排列方式对温度分布的影响以及冷却液流速对温度均衡性的效果。最后指出,实际环境中动态温度的变化对仿真结果有显著影响。 适合人群:从事电动汽车电池系统设计与仿真的研究人员和技术人员。 使用场景及目标:适用于需要深入了解电动汽车电池组热管理仿真的科研人员和工程师,旨在提高电池组的安全性和性能。 其他说明:文章强调了理论与实际应用之间的差距,指出了实验室数据与现实环境的不同挑战。

    网络工程师模拟试题参考资料.doc

    网络工程师模拟试题参考资料.doc

    计算机基础与应用模拟理论考试.doc

    计算机基础与应用模拟理论考试.doc

    计算机考试一级题库.doc

    计算机考试一级题库.doc

    基于RK3588的智慧农场系统开发-RS485总线-华为云IOT-node-red-MQTT

    node-red流

    【目标检测】牛行为检测数据集2961张4类行为YOLO+VOC格式.docx

    【目标检测】牛行为检测数据集2961张4类行为YOLO+VOC格式.docx

    空间目标轨道建模与仿真计算建立二体运动方程

    (1)熟悉并阐述不同空间目标的轨道分类与特点; (2)能够独立完成空间目标轨道建模与计算; (3)能够应用MATLAB和STK仿真软件完成空间目标轨道计算与仿真。

    系统集成部安全质量管理细则.doc

    系统集成部安全质量管理细则.doc

    【目标检测】施工人员安全服装穿戴检测数据集367张YOLO+VOC格式.docx

    【目标检测】施工人员安全服装穿戴检测数据集367张YOLO+VOC格式.docx

Global site tag (gtag.js) - Google Analytics