1.借鉴:
hibernate配置多个数据源及事物(以两个数据源为例)
Hibernate学习记录3 Hibernate 配置多数据源
百度和谷歌了很多,最终参看以上两个链接,再次感谢。
2.开始:
2.1 首先需要搞一个spring4+hibernate4的环境,同时配置Mysql和Oracle的驱动,连接池等信息,使用maven快速构建,这里就粘贴一下pom下的关键配置
2.2 接下来是applicationContext.xml文件的内容.
2.3 jdbc.properties中的配置
2.4接下来是applicationContext-hibernate.xml文件的内容
两个数据库,两套数据库方言,所以需要两套DataSource, SessionFactory,事物管理
2.4.1首先是mysql
mysql的DataSource
mysql的SessionFactory
mysql-事务管理器和编制aop
接下来是mysql的切面【这里同时配置了Oracle的切面】
2.4.2接下来是Oracle
Oracle的DataSource
Oracle的SessionFactory
Oracle是事务管理器和编制aop
Oracle的切面【没错,就是上面那张图,ctrl+c,v来的】
至此,配置部分已经完成了。
2.5 好的,接下来编写我们自己的伪SessionFactory,姑且就叫HibernateSessionFactory吧
代码很少也很简单,名称注入配置的两个SessionFactory,并声明组件,唯一需要注意的是得让spring扫描的到。
@Component
public class HibernateSessionFactory
{
@Resource(name = "sessionFactory_mysql")
SessionFactory sessionFactoryMysql;
@Resource(name = "sessionFactory_oracle")
SessionFactory sessionFactoryOracle;
public HibernateSessionFactory()
{
}
public SessionFactory getSessionFactoryMysql()
{
return sessionFactoryMysql;
}
public SessionFactory getSessionFactoryOracle()
{
return sessionFactoryOracle;
}
}
2.6接下来是BaseDao
public interface BaseDao
{
/***
* 保存对象
* @param entity
*/
int insert(T entity);
/**
* 更新对象
* @param entity
*/
int update(T entity);
/***
* 根据主键删除
* @param id
* @return
*/
int deleteById(Serializable id);
/***
* 删除
* @param entity
* @return
*/
int delete(T entity);
/***
* 通过id删除
* @param id
* @return
*/
T selectById(Serializable id);
/***
* 查询全部
* @return
*/
Collection selectAll();
/***
* 通过hql查询
* @param hql
* @param params
* @return
*/
Collection selectByHql(String hql, Object[] params);
/***
* 原生sql查询
* @param sql
* @param params
* @return
*/
Collection selectByNativeSql(String sql, Object[] params);
/***
* 原生sql查询
* @param sql
* @param params
* @return
*/
Collection selectByNativeSql(String sql, LinkedList params);
/***
* 原生sql查询
* @param sql
* @param params
* @return
*/
List selectByNativeSql(String sql, LinkedList params, Class clazz);
/**
* 分页查询
* @param hql
* @param pageNo
* @param pageSize
* @return
*/
Collection selectByPage(String hql, int pageNo, int pageSize);
/***
* 分页查询
* @param params
* @param pageNo
* @param pageSize
* @return
*/
PageInfo> selectByPage(String hql, LinkedList params, int pageNo, int pageSize);
/***
* 通过sql分页查询
* @param sql
* @param params
* @param clazz
* @param pageNo
* @param pageSize
* @return
*/
PageInfo selectByNativeSqlAndPage(String sql, LinkedList params, Class clazz, int pageNo, int pageSize);
}
可以看到的PageInfo自定义如下,并不是mybatis-pagerhelper插件里面的。get和set方法就不写了。
public class PageInfo implements Serializable
{
private int pageNumber;
private int pageSize;
private int total;
private T datas;
public PageInfo()
{
}
public PageInfo(int pageNumber,
int pageSize,
int total,
T datas)
{
this.pageNumber = pageNumber;
this.pageSize = pageSize;
this.total = total;
this.datas = datas;
}
}
2.7 接下来是BaseDaoImpl,重点看下代码最后面的getSessionFactory方法,这里直接返回null,为啥不写在BaseDao中呢,其实都可以。
/***
* CREATED BY: kaiser
* DATE: 2018/5/27
* INFO: 子类必须重写getSessionFactory方法
*/
public class BaseDaoImpl implements BaseDao
{
private Class clazz;
@Autowired
HibernateSessionFactory sessionFactory;
@SuppressWarnings("unchecked")
public BaseDaoImpl()
{
ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
Type[] actualTypeArguments = type.getActualTypeArguments();
clazz = (Class) type.getActualTypeArguments()[0];
}
@Override
public int insert(T entity)
{
getSessionFactory().getCurrentSession().save(entity);
return 0;
}
@Override
public int update(T entity)
{
getSessionFactory().getCurrentSession().update(entity);
return 0;
}
@Override
public int deleteById(Serializable id)
{
T entity = selectById(id);
getSessionFactory().getCurrentSession().delete(entity);
return 0;
}
@Override
public int delete(T entity)
{
getSessionFactory().getCurrentSession().delete(entity);
return 0;
}
@SuppressWarnings("unchecked")
@Override
public T selectById(Serializable id)
{
return (T) getSessionFactory().getCurrentSession().get(clazz, id);
}
@Override
public Collection selectAll()
{
// return sessionFactory.getCurrentSession().createQuery("from ")
this.getClazzName();
return null;
}
@SuppressWarnings("unchecked")
@Override
public Collection selectByHql(String hql,
Object[] params)
{
Query query = getSessionFactory().getCurrentSession()
.createQuery(hql);
if (params != null)
{
for(int i = 0; i < params.length; i++)
{
query.setParameter(i, params[i]);
}
}
return query.list();
}
@SuppressWarnings("unchecked")
@Override
public List selectByNativeSql(String sql,
Object[] params)
{
Query query = getSessionFactory().getCurrentSession()
.createSQLQuery(sql);
if (params != null)
{
for(int i = 0; i < params.length; i++)
{
query.setParameter(i, params[i]);
}
}
return query.list();
}
@SuppressWarnings("unchecked")
@Override
public Collection selectByNativeSql(String sql,
LinkedList params)
{
Query query = getSessionFactory().getCurrentSession().createSQLQuery(sql);
if (params != null)
{
for(int i = 0; i < params.size(); i++)
{
query.setParameter(i, params.get(i));
}
}
return query.list();
}
@Override
public List selectByNativeSql(String sql,
LinkedList params,
Class clazz)
{
SQLQuery query = getSessionFactory().getCurrentSession().createSQLQuery(sql);
if (params != null)
{
for(int i = 0; i < params.size(); i++)
{
query.setParameter(i, params.get(i));
}
}
query.addEntity(clazz);
return query.list();
}
@SuppressWarnings("unchecked")
@Override
public Collection selectByPage(String hql,
int pageNo,
int pageSize)
{
return getSessionFactory().getCurrentSession().createQuery(hql)
.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize)
.list();
}
@SuppressWarnings("unchecked")
@Override
public PageInfo> selectByPage(String hql,
LinkedList params,
int pageNo,
int pageSize)
{
Query query = getSessionFactory().getCurrentSession()
.createQuery(hql);
if (params != null)
{
for(int i = 0; i < params.size(); i++)
{
query.setParameter(i, params.get(i));
}
}
ScrollableResults scroll = query.scroll();
scroll.last();
query.setFirstResult(pageNo);
query.setMaxResults(pageSize);
PageInfo> pageInfo = new PageInfo>(pageNo, pageSize, scroll.getRowNumber() + 1, query.list());
return pageInfo;
}
@SuppressWarnings("unchecked")
@Override
public PageInfo selectByNativeSqlAndPage(String sql,
LinkedList params,
Class clazz,
int pageNo,
int pageSize)
{
Query query = getSessionFactory().getCurrentSession()
.createSQLQuery(sql)
.addEntity(clazz);
if (params != null)
{
for(int i = 0; i < params.size(); i++)
{
query.setParameter(i, params.get(i));
}
}
ScrollableResults scroll = query.scroll();
scroll.last();
query.setFirstResult(pageNo);
query.setMaxResults(pageSize);
PageInfo pageInfo = new PageInfo(pageNo, pageSize, scroll.getRowNumber() + 1, query.list());
return pageInfo;
}
private String getClazzName()
{
System.out.println(this.clazz.getName());
return this.clazz.getName();
}
public void clearDataSourceType()
{
DataSourceContextHolder.clearDataSourceType();
}
protected SessionFactory getSessionFactory()
{
return null;
}
}
2.8 接下来是实体类了
Result对应的是mysql库里面的表t_result。
注:Entity只是实现了Serializable接口,这里就不贴了
@Entity
@Table(name = "T_RESULT", schema = "ZSXY")
public class Result extends com.kaiser.domain.Entity
{
/** 属性映射字段 */
@Id
@GeneratedValue(generator = "id")
@GenericGenerator(name = "id", strategy = "identity")
@Column(name = "id")
private int id;
@Column(name = "session_id", nullable = false)
private String sessionId;
@Column(name = "query_info", nullable = true)
private String queryInfo;
@Column(name = "result_info", nullable = true)
private String resultInfo;
@Column(name = "order_id", columnDefinition = "varchar(32)")
private String orderId;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "create_time")
private Date createTime;
@Column(name = "status")
private String status;
@Column(name = "task_id")
private String taskId;
}
UserInfo对应的是oracle库里面的表t_user_info。
注:1.Entity只是实现了Serializable接口,这里不贴了
2.因为t_user_info表没有主键,所以得使用复合主键,否则会报错
@Entity
@Table(name = "T_USER_INFO",
schema = "sms")
public class UserInfo extends com.kaiser.domain.Entity
{
@EmbeddedId
@AttributeOverrides({
@AttributeOverride(name = "uid", column = @Column(name = "uiid")),
@AttributeOverride(name = "code", column = @Column(name = "ucode")),
@AttributeOverride(name = "account", column = @Column(name = "uaccount")),
@AttributeOverride(name = "password", column = @Column(name = "upassword"))
})
private UserInfoId userInfoId;
@Column(name = "reg_type")
private int registerType;
@Column(name = "isactive")
private String isActive;
@Temporal(TemporalType.TIMESTAMP)
@Column(name = "reg_date")
private Date createTime;
@Column(name = "aid")
private int RoleId;
@Column(name = "balance")
private double balance;
}
这个是复合主键的实体类,必须重写equals和hascode方法,同时必须注解@Embeddable以及一个无参的构造方法。同时需要注意的是复合主键的实体类中定义的属性列不能在原实体类【UserInfo】中重复定义,比如说UserInfoId中有uid属性,在UserInfo中不需要定义。,之所以是【uid,code,account,password】四个属性,完全是为了生成一个id,也可以
@Embeddable
public class UserInfoId implements Serializable
{
@Column(name = "uid")
private int id;
@Column(name = "code")
private String code;
@Column(name = "account")
private String account;
@Column(name = "password")
private String password;
public UserInfoId() { }
public UserInfoId(int id,
String code,
String account,
String password)
{
this.id = id;
this.code = code;
this.account = account;
this.password = password;
}
@Override
public boolean equals(Object o)
{
if (this == o) { return true; }
if (o == null || getClass() != o.getClass()) { return false; }
UserInfoId that = (UserInfoId) o;
return getId() == that.getId() && Objects.equals(getCode(),
that.getCode()) && Objects.equals(getAccount(),
that.getAccount()) &&
Objects.equals(getPassword(),
that.getPassword());
}
@Override
public int hashCode()
{
return Objects.hash(getId(),
getCode(),
getAccount(),
getPassword());
}
}
2.9 接下来是Dao
public interface ResultDao
extends BaseDao {}
public interface UserInfoDao
extends BaseDao {}
2.10 接着是DaoImpl
@Repository("resultDao")
public class ResultDaoImpl
extends BaseDaoImpl implements ResultDao {
@Override
protected SessionFactory getSessionFactory()
{
return sessionFactory.getSessionFactoryMysql();
}
}
@Repository("userInfoDao")
public class UserInfoDaoImpl
extends BaseDaoImpl implements UserInfoDao {
@Override
protected SessionFactory getSessionFactory()
{
return sessionFactory.getSessionFactoryOracle();
}
}
2.11 BaseService
public interface BaseService
, dao extends BaseDao > {
/***
* 保存
* @param entity
* @return
*/
int save(T entity);
/**
* 更新
* @param entity
* @return
*/
int renew(T entity);
/***
* 通过id删除
* @param id
* @return
*/
int dropById(Serializable id);
/***
* 删除
* @param entity
* @return
*/
int drop(T entity);
/***
* 通过id查找
* @param id
* @return
*/
T findById(Serializable id);
/***
* 查询全部
* @return
*/
Collection findAll();
}
2.12 BaseServiceImpl
public class BaseServiceImpl
, Dao extends BaseDao > implements BaseService {
@Autowired
protected Dao dao;
@Override
public int save(T entity)
{
return dao.insert(entity);
}
@Override
public int renew(T entity)
{
return dao.update(entity);
}
@Override
public int dropById(Serializable id)
{
return dao.deleteById(id);
}
@Override
public int drop(T entity)
{
return dao.delete(entity);
}
@Override
public T findById(Serializable id)
{
return dao.selectById(id);
}
@Override
public Collection findAll()
{
return dao.selectAll();
}
}
2.13 继承自BaseService的类,这里以ResultService和ResultServiceImpl为例
public interface ResultService extends BaseService
>{}
@Service("resultService")
public class ResultServiceImpl extends BaseServiceImpl
> implements ResultService{}
2.14 接下来可以在Controller层使用注解注入使用了
3.大功告成
虽然写完了,但是不确定的是这是不是最优解,还希望能对碰上此问题的各位有所帮助,如果更好的方案,希望能不吝指教。