zoukankan      html  css  js  c++  java
  • Hibernate 连接访问多个数据库(含访问不同数据库的相同表)(转)

    利用hibernate访问不同数据库中的不同表或不同数据库中的相同表。

    本人在开发过程中的解决方案,希望大家交流。
    一般用myEclipse工具会自动生成Hibernate的相关文件,大致有下面几类:

    (1)数据库配置文件:.cfg.xml
    (2)映射文件.hbm.xml
    (3)映射类:pojo
    (4)会话工厂类:SessionFactory
    (5)基础DAO接口:IBaseHibernateDAO
    (6)DAO接口的实现基础类:BaseHibernateDAO
    (7)数据访问对象:DAO。所有DAO默认继承BaseHibernateDAO

    当然,不同的工具生成的文件也略有差异,但不影响实现思路。


    一般工具生成的配置只针对一个数据库,所以都生成了一个数据库配置文件。
    下面我以访问不同数据库中相同的表做例子,访问不同数据库的不同表原理类同。
    假设有两个数据库db1和db2,两个库中都有user表,要实现对两个数据库中的表访问,操作如下:

    (1)配置两个数据库配置文件:db1.cfg.xml和db2.cfg.xml,分别连接两个数据库。
    (2)配置两个SessionFactory:SessionFactory_db1绑定db1.cfg.xml,SessionFactory_db2,绑定db2.cfg.xml。
    (3)基础DAO接口:IBaseHibernateDAO保持不变,代码默认如下
    public interface IBaseHibernateDAO {
    public Session getSession( );

    }

    (4)DAO接口的实现基础类:BaseHibernateDAO改造后如下:


    public class BaseHibernateDAO implementsIBaseHibernateDAO {

    private String dbName;//要连接的数据库

    // 为了保证每个DAO能够正确指定所操作的数据库,将无参构造设为私有 
    private BaseHibernateDAO() { }

    // 指定目标数据库的DAO构造方法 
    public BaseHibernateDAO(StringdbName) {
       this.dbName = dbName;
    }

    //重写getSession()方法,使之能够访问不同的数据库
    public Session getSession() {
       if (dbName == null) {
        return null;
       }else if (dbName.equals("db01")){   
       returnSessionFactory_db01.getSession();//连接db01库
       } else if (dbName.equals("db02")) {   
       returnSessionFactory_db02.getSession();//连接db02库
       } else {
        return null;
       }
    }
    }

    (5)改造自动生成用户表对应的DAO——UserDAO类:即继承父类BaseHibernateDAO的有参构造。

    public class UserDAOextends BaseHibernateDAO {

       //因为父类将无参构造设置为了private,所以该类只能存在有参构造了。
        public UserInfoTbDAO(StringdbName) {
           super(dbName);  
        }

        //以下是自动生成的代码:
        public void save(UserTb transientInstance){        
            try {
               getSession().save(transientInstance);
               log.debug("save successful");
            } catch (RuntimeException re) {
               log.error("save failed", re);
                throw re;
            }
        }
    }

    (6)应用层的测试

    public voidtestSaveUser(UserTb user){

    UserDAO userDao_1 = newUserDAO("db01");//得到db01库的DAO
    UserDAO userDao_2 = new UserDAO("db02");//得到db02库的DAO

    //假设两个库中的数据要同步更新(实际操作中应该加入事务控制)
    userDao_1.save();//更新01库
    userDao_2.save();//更新02库

    }

    (7)总结:
    优点:
    1.代码改动比较小,能充分利用工具生成的代码。
    2.结构简单,访问灵活。
    3.访问不同库的同一个表,只需一个DAO,一个pojo,无需写额外代码。

    缺点:
    1.每次连接数据库时都要指定访问的数据库。
    2.为了有效指定数据库逻辑名,和利于维护,就得“db01”这样的字符串设置为全局的final变量,或者弄

    一个DAO工厂来产生不同的DAO实例。

    另一种方法:
    上面的方法是改造了DAO的构造方法。也可以改造getSession()方法,这样透明度更高,但略欠灵活。

    本人刚刚接触Hibernate,不知以上设计是否妥当,望高手指点一二。

  • 相关阅读:
    linux软件相关基操--基于Debian
    Spring AOP实现接口调用异常时重试
    Kafka
    zookeeper集群
    zookeeper客户端之curator
    zk权限模块
    zookeeper简介及基操
    CustomTool
    SpringBoot+Mybatis配置多数据源,分包方式
    mysql操作相关错误解决办法
  • 原文地址:https://www.cnblogs.com/sandea/p/8657808.html
Copyright © 2011-2022 走看看