• 使用hibernate配置多数据源链接MySQL和Oracle数据库


    最近做项目要将读取到的数据同时插入到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业务层的编写就和其他的项目的编写一样了。

    可能考虑的有不全面的地方,希望各位高手多多指点

  • 相关阅读:
    java IO选择流的原则及其与IO流相关类的关系
    图形用户界面(graphical user interface)
    泛型
    流、文件及基于文本的应用
    java线程
    多态与方法调用
    在eclipse中使用javap工具反汇编
    java类的访问控制符与其他几个特殊修饰符的总结
    java中几个特殊的类
    @property在内存管理中的参数问题
  • 原文地址:https://www.cnblogs.com/tangkai/p/3488004.html
Copyright © 2020-2023  润新知