【原创】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 implements IBaseHibernateDAO {
private String dbName;//要连接的数据库
// 为了保证每个DAO能够正确指定所操作的数据库,将无参构造设为私有
private BaseHibernateDAO() { }
// 指定目标数据库的DAO构造方法
public BaseHibernateDAO(String dbName) {
this.dbName = dbName;
}
//重写getSession() 方法,使之能够访问不同的数据库
public Session getSession() {
if (dbName == null) {
return null;
}else if (dbName.equals("db01")) {
return SessionFactory_db01.getSession();//连接db01库
} else if (dbName.equals("db02")) {
return SessionFactory_db02.getSession();//连接db02库
} else {
return null;
}
}
}
(5)改造自动生成用户表对应的DAO——UserDAO 类:即继承父类BaseHibernateDAO 的有参构造。
public class UserDAO extends BaseHibernateDAO {
//因为父类将无参构造设置为了private,所以该类只能存在有参构造了。
public UserInfoTbDAO(String dbName) {
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 void testSaveUser(UserTb user){
UserDAO userDao_1 = new UserDAO("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实例。