最近做项目要将读取到的数据同时插入到MySQL数据库和Oracle数据库当中,以前都是使用一个数据库,没有用过多数据源的情况,现在把这个问题搞定了,写下来希望对大家有点帮助,可能我所使用的方法不是最好的,希望多多指教。
首先是applicationContext.xml的配置文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> <context:component-scan base-package="com.ydcn.csv.dao"></context:component-scan> <context:component-scan base-package="com.ydcn.csv.service"></context:component-scan> <context:component-scan base-package="com.ydcn.csv.task"></context:component-scan> <context:annotation-config></context:annotation-config> <!-- 管理MySQL的事务 --> <tx:annotation-driven transaction-manager="mysqlTransactionManager" /> <!-- 管理Oracle的事务 --> <tx:annotation-driven transaction-manager="oracleTransactionManager" /> <!-- MySQL的JNDI数据源 --> <bean id="mysqlDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:MySQLTEST"></property> </bean> <!-- MySQL的sessionFactory --> <bean id="mysqlSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="mysqlDataSource"></property> <!-- 注解的方式定义实体类 --> <property name="annotatedClasses"> <list> <value>com.ydcn.csv.entity.MerchantCateOne</value> <value>com.ydcn.csv.entity.MerchantCateTwo</value> <value>com.ydcn.csv.entity.MerchantCateThree</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop> <prop key="hibernate.hbm2ddl.auto">update</prop> <prop key="hibernate.jdbc.batch_size">50</prop> <!-- <prop key="hibernate.show_sql">true</prop> --> <!-- <prop key="hibernate.format_sql">true</prop> --> </props> </property> </bean> <!-- MySQL数据库事务管理 --> <bean id="mysqlTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="mysqlSessionFactory"></property> </bean> <!-- 为MySQL的实现类注入SessionFactory --> <bean id="mysqlMechantCateOneDao" class="com.ydcn.csv.dao.mysql.impl.MysqlMechantCateOneDaoImpl"> <property name="sessionFactory" ref="mysqlSessionFactory"></property> </bean> <!-- 为操作MySQL数据库的实现类注入SessionFactory --> <bean id="mysqlMerchantCateTwoDao" class="com.ydcn.csv.dao.mysql.impl.MysqlMerchantCateTwoDaoImpl"> <property name="sessionFactory" ref="mysqlSessionFactory"></property> </bean> <!-- 为操作MySQL数据库的实现类注入SessionFactory --> <bean id="mysqlMerchantCateThreeDao" class="com.ydcn.csv.dao.mysql.impl.MysqlMerchantCateThreeDaoImpl"> <property name="sessionFactory" ref="mysqlSessionFactory"></property> </bean> <!-- ####################### 配置Oracle数据信息 ################### --> <!-- Oracle 的JNDI数据源 --> <bean id="oracleDataSource" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:ORACLETEST"></property> </bean> <!-- Oracle 的SessionFactory --> <bean id="oracleSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> <property name="dataSource" ref="oracleDataSource"></property> <!-- 使用注解的方式定义实体类 --> <property name="annotatedClasses"> <list> <value>com.ydcn.csv.entity.TransCategoryData</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.OracleDialect</prop> <!-- <prop key="hibernate.hbm2ddl.auto">update</prop> --> <prop key="hibernate.jdbc.batch_size">50</prop> <!-- <prop key="hibernate.show_sql">true</prop> --> <!-- <prop key="hibernate.format_sql">true</prop> --> </props> </property> </bean> <!-- Oracle事务管理配置 --> <bean id="oracleTransactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="oracleSessionFactory"></property> </bean> <!-- 为操作Oracle数据库的实现类注入SessionFactory --> <bean id="oracleTransCategoryDataDao" class="com.ydcn.csv.dao.oracle.impl.OracleTransCategoryDataDaoImpl"> <property name="sessionFactory" ref="oracleSessionFactory"></property> </bean> <!-- #################################### 配置定时任务信息 ############################### --> <!-- 读取 Transaction 和 Category CSV文件 --> <bean id="readCSVTask" class="com.ydcn.csv.task.ReadCSVTask"></bean> <!-- 下载 CSV 文档 --> <bean id="executeDownLoadCSVFileJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="readCSVTask"></property> <property name="targetMethod" value="downLoadCSV"></property> </bean> <!-- 读取 CSV 文件 --> <bean id="executeReadCSVFileJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"> <property name="targetObject" ref="readCSVTask"></property> <property name="targetMethod" value="readCSVFile"></property> </bean> <!-- 定义下载CSV文档的时间 --> <bean id="executeDownLoadCSVFileCron" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="executeDownLoadCSVFileJob"></property> <property name="cronExpression" value="0 58 7 * * ?"></property> </bean> <!-- 定义读取CSV文件的时间 --> <bean id="executeReadCSVFileCron" class="org.springframework.scheduling.quartz.CronTriggerBean"> <property name="jobDetail" ref="executeReadCSVFileJob"></property> <property name="cronExpression" value="0 0 8 * * ?"></property> </bean> <!-- 总的管理类 将lazy-init="false" 那么容器启动的时候就会执行任务调度 --> <bean id="startQuertz" lazy-init="false" autowire="no" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> <property name="triggers"> <list> <ref bean="executeDownLoadCSVFileCron"/> <ref bean="executeReadCSVFileCron"/> </list> </property> </bean> </beans>
我所使用的是泛型的方式去写:首先来看一下我的BaseDao吧!
package com.ydcn.csv.dao.base; import java.util.List; /** * 基础的接口信息 * @author allen.tang * * @param <T> */ public interface BaseDao<T> { /** * 保存实体的信息 * @param user */ public void save(T entity); /** * 删除实体信息 * @param id */ public void delete(T entity); /** * 更新实体信息 * @param user */ public void update(T entity); /** * 根据id查询 * @param id * @return */ public T queryById(int id); /** * 查询出所有的信息 * @return */ public List<T> queryAll(); /** * 根据特约商的代码查询出大类码的相关信息 * @param merchantGroupID * @return */ public List<T> queryByMerchantGroupID(String merchantGroupID); }
这样所有的接口就可以继承这个BaseDao不用再一个一个的添加相同的方法,只要是相同的方法都可以写到BaseDao中,然后我们再来看看BaseDaoImpl
package com.ydcn.csv.dao.base; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.util.List; import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; /** * 基础的接口实现 * @author allen.tang * * @param <T> */ public class BaseDaoImpl<T> extends HibernateDaoSupport { private Class<T> entityClass; /** * 通过反射获取子类的确定的泛型类 */ public BaseDaoImpl() { // Type genType = this.getClass().getGenericSuperclass(); // Type[] params = // ((ParameterizedType)getClass()).getActualTypeArguments(); // entityClass = (Class<T>) params[0]; this.entityClass = (Class<T>) ((ParameterizedType) getClass() .getGenericSuperclass()).getActualTypeArguments()[0]; } public BaseDaoImpl(Class clazz) { this.entityClass = clazz; } // @Autowired // @Qualifier("mysqlDataSource") // public void anyMethodName(SessionFactory sessionFactory) { // setSessionFactory(sessionFactory); // } public Session getCurrentSession() { return this.getHibernateTemplate().getSessionFactory() .getCurrentSession(); } /** * 根据ID加载PO实例 * * @param id * @return 返回相应的PO实例 */ public T get(Serializable id) { return this.getHibernateTemplate().get(entityClass, id); } /** * 保存PO * * @param entity */ public void save(T entity) { this.getHibernateTemplate().save(entity); } /** * 删除PO * * @param entity */ public void delete(T entity) { this.getHibernateTemplate().delete(entity); } /** * 修改PO * * @param entity */ public void update(T entity) { this.getHibernateTemplate().update(entity); } /** * 执行hql查询 * * @param hql * hql查询语句 * @return 返回查询结果 */ public List<T> find(String hql) { return this.getHibernateTemplate().find(hql); } /** * 执行带参的hql查询 * * @param hql * hql查询语句 * @param params * 参数 * @return 返回查询的集合 */ public List<T> find(String hql, Object... params) { return this.getHibernateTemplate().find(hql, params); } /** * 返回Query对象 * * @param hql * hql查询语句 * @param params * 查询参数 * @return 返回的Query对象 */ public Query createQuery(String hql, Object... params) { Query query = this.getSession().createQuery(hql); if (params != null && params.length > 0) { for (int i = 0; i < params.length; i++) { query.setParameter(i, params[i]); } } return query; } /** * 获取该类数据的总条数 * * @return */ public int getCount() { String hql = "select count(e) from " + entityClass.getSimpleName() + " e "; Query query = this.createQuery(hql, null); Long count = (Long) query.uniqueResult(); return count.intValue(); } /** * 根据传入对象的编号获取对象的详细信息 * * @param id * 传入对象的id * @return 返回正个对象 */ public T queryById(int id) { return this.get(id); } /** * 不进行分页的查询查询出所有的对象信息 */ public List<T> queryAll() { String hql = "from " + entityClass.getSimpleName(); List<T> list = find(hql); return list; } /** * 根据特约商的代码查询出大类码的信息 */ public List<T> queryByMerchantGroupID(String merchantGroupID) { String hql = "from " + entityClass.getSimpleName() + " where merchantGroupID = ?"; List<T> list = find(hql, merchantGroupID); return list; } }
注释已经很详细了,这里我就不细说了,下面来看一下我的接口和实现类是怎么写的吧!
首先接口,只需要继承BaseDao,接口里就有了BaseDao的所有的方法,并加入了传入的类型
public interface TransCategoryDataDao extends BaseDao<TransCategoryData> { }
然后实现类,这里使用注解的方式定义Dao层,之所以不仅继承了BaseDaoImpl类也实现了TransCateGoryDataDao接口是因为,有些方法可能是这个类独有的方法,需要这个类去单独实现,而不是放在公共的BaseDaoImp里面。
@Repository("oracleTransCategoryDataDao") public class OracleTransCategoryDataDaoImpl extends BaseDaoImpl<TransCategoryData> implements TransCategoryDataDao{ }
然后其他的Service业务层的编写就和其他的项目的编写一样了。
可能考虑的有不全面的地方,希望各位高手多多指点