• spring+hibernate配置多数据源


    spring+hibernate配置多数据源及多个事务过程

    • 在datasource.properties文件中增加数据库配置
    sqlServer.jdbc.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=db_ceshi1
    sqlServer.jdbc.user=sa
    sqlServer.jdbc.password=sa
    sqlServer.jdbc.initialPoolSize=5
    sqlServer.jdbc.minPoolSize=5
    sqlServer.jdbc.maxPoolSize=80
    sqlServer.jdbc.checkoutTimeout=20000
    sqlServer.jdbc.idleConnectionTestPeriod=120
    sqlServer.jdbc.maxIdleTime=60
    sqlServer.jdbc.maxStatements=6000
    sqlServer.jdbc.testConnectionOnCheckout=false
    
    sqlServer.jdbc.erms.driverClass=com.microsoft.sqlserver.jdbc.SQLServerDriver
    sqlServer.jdbc.erms.url=jdbc:sqlserver://127.0.0.1:1433;databaseName=db_ceshi2
    sqlServer.jdbc.erms.user=sa
    sqlServer.jdbc.erms.password=sa
    sqlServer.jdbc.erms.initialPoolSize=5
    sqlServer.jdbc.erms.minPoolSize=5
    sqlServer.jdbc.erms.maxPoolSize=80
    sqlServer.jdbc.erms.checkoutTimeout=20000
    sqlServer.jdbc.erms.idleConnectionTestPeriod=120
    sqlServer.jdbc.erms.maxIdleTime=60
    sqlServer.jdbc.erms.maxStatements=6000
    sqlServer.jdbc.erms.testConnectionOnCheckout=false
    • 在spring.xml文件中配置数据源级事务
        <bean id="dataSourceSqlServer" class="com.mchange.v2.c3p0.ComboPooledDataSource"
            destroy-method="close">
            <property name="driverClass" value="${sqlServer.jdbc.driverClass}" />
            <property name="jdbcUrl" value="${sqlServer.jdbc.url}" />
            <property name="user" value="${sqlServer.jdbc.user}" />
            <property name="password" value="${sqlServer.jdbc.password}" />
            <property name="initialPoolSize" value="${sqlServer.jdbc.initialPoolSize}" />
            <property name="minPoolSize" value="${sqlServer.jdbc.minPoolSize}" />
            <property name="maxPoolSize" value="${sqlServer.jdbc.maxPoolSize}" />
            <property name="checkoutTimeout" value="${sqlServer.jdbc.checkoutTimeout}" />
            <property name="idleConnectionTestPeriod" value="${sqlServer.jdbc.idleConnectionTestPeriod}" />
            <property name="maxIdleTime" value="${sqlServer.jdbc.maxIdleTime}" />
            <property name="maxStatements" value="${sqlServer.jdbc.maxStatements}" />
            <property name="testConnectionOnCheckout" value="${sqlServer.jdbc.testConnectionOnCheckout}" />
        </bean>
    
        <bean id="dataSource" class="com.hebky.erms.util.core.DynamicDataSource">
            <property name="targetDataSources">
                <map key-type="java.lang.String">
                    <entry key="dataSourceMySql" value-ref="dataSourceMySql" />
                    <entry key="dataSourceSqlServer" value-ref="dataSourceSqlServer" />
                </map>
            </property>
            <property name="defaultTargetDataSource" ref="dataSourceSqlServer" />
        </bean>
    
        <bean id="sessionFactory"
            class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="configLocation" value="classpath:hibernate.cfg.xml" />
            <!-- 通过扫描包的方式扫描所有实体类 -->
            <property name="packagesToScan">
                <list>
                    <value>com.ceshi.*</value>
                </list>
            </property>
        </bean>
    
        <!-- 配置事务管理器 -->
        <bean id="transactionManager"
            class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory"></property>
            <property name="nestedTransactionAllowed" value="true"></property>
        </bean>
    
        <!-- 拦截器方式配配置事务 -->
        <tx:advice id="txadvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="add*" propagation="REQUIRED" />
                <tx:method name="save*" propagation="REQUIRED" />
                <tx:method name="saveRN*" propagation="REQUIRES_NEW" />
                <tx:method name="import*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" />
                <tx:method name="saveNS*" propagation="NOT_SUPPORTED" />
                <tx:method name="updateNS*" propagation="NOT_SUPPORTED" />
                <tx:method name="executeNS*" propagation="REQUIRED" />
                <tx:method name="updateRN*" propagation="REQUIRES_NEW" />
                <tx:method name="delete*" propagation="REQUIRED" no-rollback-for="NotImplementedException"/>
                <tx:method name="get*" read-only="true" propagation="REQUIRED" />
                <tx:method name="find*" read-only="true" propagation="REQUIRED" />
                <tx:method name="query*" read-only="true" propagation="REQUIRED" />
                <tx:method name="count*" read-only="true" propagation="REQUIRED" />
                <tx:method name="isNS*" read-only="true" propagation="NOT_SUPPORTED" />
                <tx:method name="*" read-only="true" />
            </tx:attributes>
        </tx:advice>
        <aop:config>
            <aop:pointcut id="serviceMethods"
                expression="execution(* com.ceshi..service..*.*(..))" />
            <aop:advisor advice-ref="txadvice" pointcut-ref="serviceMethods" />
        </aop:config>
    
        <!--从数据库配置-->
        <bean id="dataSourcecm" class="com.mchange.v2.c3p0.ComboPooledDataSource" >
            <property name="driverClass" value="${sqlServer.jdbc.erms.driverClass}" />
            <property name="jdbcUrl" value="${sqlServer.jdbc.erms.url}" />
            <property name="user" value="${sqlServer.jdbc.erms.user}" />
            <property name="password" value="${sqlServer.jdbc.erms.password}" />
            <property name="initialPoolSize" value="${sqlServer.jdbc.erms.initialPoolSize}" />
            <property name="minPoolSize" value="${sqlServer.jdbc.erms.minPoolSize}" />
            <property name="maxPoolSize" value="${sqlServer.jdbc.erms.maxPoolSize}" />
            <property name="checkoutTimeout" value="${sqlServer.jdbc.erms.checkoutTimeout}" />
            <property name="idleConnectionTestPeriod" value="${sqlServer.jdbc.erms.idleConnectionTestPeriod}" />
            <property name="maxIdleTime" value="${sqlServer.jdbc.erms.maxIdleTime}" />
            <property name="maxStatements" value="${sqlServer.jdbc.erms.maxStatements}" />
            <property name="testConnectionOnCheckout" value="${sqlServer.jdbc.erms.testConnectionOnCheckout}" />
        </bean>
    
        <!--session工厂-->
        <bean id="sessionFactorycm" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
            <property name="dataSource" ref="dataSourcecm" />
            <!--包扫描,数据库对应的实体类所在的包-->
            <!-- 通过扫描包的方式扫描所有实体类 -->
            <property name="packagesToScan">
                <list>
                    <value>com.ceshi.*</value>
                </list>
            </property>
            <property name="hibernateProperties">
                <value>
                    <!-- hibernate使用的数据库方言(即连接哪种数据库) -->
                    hibernate.dialect = org.hibernate.dialect.SQLServerDialect
                    <!-- 自动更新数据库表结构 -->
                    hibernate.hbm2ddl.auto = update
                    <!-- 后台显示sql语句,开发时使用-->
                    hibernate.show_sql = true
                    <!-- 是否格式化SQL -->
                    hibernate.format_sql = true
                </value>
            </property>
        </bean>
    
        <!--事务管理器-->
        <bean id="transactionManagercm" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactorycm"/>
        </bean>
    
        <!-- 配置事务通知属性 -->
        <tx:advice id="transactionAdvicecm" transaction-manager="transactionManagercm">
            <!-- 定义事务传播属性 -->
            <tx:attributes>
                <tx:method name="add*" propagation="REQUIRED" />
                <tx:method name="save*" propagation="REQUIRED" />
                <tx:method name="saveRN*" propagation="REQUIRES_NEW" />
                <tx:method name="import*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" />
                <tx:method name="saveNS*" propagation="NOT_SUPPORTED" />
                <tx:method name="updateNS*" propagation="NOT_SUPPORTED" />
                <tx:method name="executeNS*" propagation="REQUIRED" />
                <tx:method name="updateRN*" propagation="REQUIRES_NEW" />
                <tx:method name="delete*" propagation="REQUIRED" no-rollback-for="NotImplementedException"/>
                <tx:method name="get*" read-only="true" propagation="REQUIRED" />
                <tx:method name="find*" read-only="true" propagation="REQUIRED" />
                <tx:method name="query*" read-only="true" propagation="REQUIRED" />
                <tx:method name="count*" read-only="true" propagation="REQUIRED" />
                <tx:method name="isNS*" read-only="true" propagation="NOT_SUPPORTED" />
                <tx:method name="*" read-only="true" />
            </tx:attributes>
        </tx:advice>
    
        <!-- 配置事务切面 -->
        <aop:config>
            <aop:advisor pointcut="execution(* com.ceshi..service..*.*(..))" advice-ref="transactionAdvicecm"/>
        </aop:config>
    • 创建DatabaseContextHolder类
    class DatabaseContextHolder {
        public static final String DATA_SOURCE_SQLSERVER = "dataSourceSqlServer";
        public static final String DATA_SOURCE_ERMS = "dataSourcecm";
    
    
        private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(); // 线程本地环境
    
        /**
         * 设置数据源类型
         *
         * @param customerType 数据源类型
         */
        public static void setCustomerType(String customerType) {
            contextHolder.set(customerType);
        }
    
        /**
         * 获取数据源类型
         *
         * @return
         */
        static String getCustomerType() {
            return contextHolder.get();
        }
    
        /**
         * 清除数据源类型
         */
        public static void clearCustomerType() {
            contextHolder.remove();
        }
    }
    • 创建DynamicDataSource继承AbstractRoutingDataSource获取动态数据源
    public class DynamicDataSource extends AbstractRoutingDataSource {
    
        /**
         * 在进行DAO操作前,通过上下文环境变量,获得数据源的类型
         */
        @Override
        protected Object determineCurrentLookupKey() {
            return DatabaseContextHolder.getCustomerType();
        }
    
    }
    • 在BaseDao中注入session即可
    public abstract class BaseDao implements IBaseDao {
    
        @Resource
        private SessionFactory sessionFactory;// 从容器中注入session工厂【无需get,set方法】
    
        @Resource
        private SessionFactory sessionFactorycm;
    
        /**
         * 向子类暴露的接口获用来获取session
         *
         * @return session
         */
        protected Session getSession() {
            // 事务必须是开启的(Required),否则获取不到
                return sessionFactory.getCurrentSession();
        }
    
        //注入第二个session
         protected Session getSessionFactorycm(){
                return sessionFactorycm.getCurrentSession();
            }
    
    
        /**
         * 保存实体
         *
         * @param t 实体参数
         */
        public <T> void save(T t) {
            getSession().save(t);
        }
        
        public <T> void saveTwo(T t){
            getSessionFactorycm().save(T);
        }
    }

    配置多数据源完成

  • 相关阅读:
    string数组批量转换成Int数组
    TCP/IP 、 HTTP 、HTTPS
    静态布局、自适应布局、流式布局、响应式布局、弹性布局等的概念和区别
    Vue源码学习02 初始化模块init.js
    IOS8白屏
    VUE 源码学习01 源码入口
    http状态码
    vue全家桶(Vue+Vue-router+Vuex+axios)(Vue+webpack项目实战系列之二)
    Vue实战Vue-cli项目构建(Vue+webpack系列之一)
    module.exports,exports,export和export default,import与require区别与联系【原创】
  • 原文地址:https://www.cnblogs.com/hww-2429/p/11843726.html
Copyright © 2020-2023  润新知