zoukankan      html  css  js  c++  java
  • Spring+Hibernate实现动态SessionFactory切换

    场景:

    1)系统有多个数据库

    2)且数据库类型也不尽相同

    3)现在应用根据某些条件路由到具体的数据库

    4)且在spring+hibernate框架下,支持依赖注入

    已有实现,spring动态数据源,但无法实现动态SessionFactory,即不通数据库的方言不一样

    目标:

    在spring动态数据源的基础上,实现动态SessionFactory

    1.配置多个数据源和SessionFactory,并给相应SessionFactory配置事务管理:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="
                http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        <!-- FOR SqlServer-->
        <bean id="SqlServer_DataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">
            <property name="driverClassName" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" />
            <property name="url"
                value="url" />
            <property name="username" value="username" />
            <property name="password" value="password" />
        </bean>
        <bean id="SqlServer_SessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"
            p:mappingLocations="classpath:/com/entity/*.hbm.xml">
            <property name="dataSource" ref="SqlServer_DataSource" />        
            <property name="hibernateProperties">
                <props>                
                    <prop key="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</prop>
                    <prop key="hibernate.dialect">org.hibernate.dialect.SQLServer2008Dialect</prop>                
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                </props>
            </property>
        </bean>
        <bean id="SqlServer_TransactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="SqlServer_SessionFactory"/>
        </bean>
        
        <!-- FOR Oracle -->
        <bean id="Oracle _DataSource"
            class="org.springframework.jdbc.datasource.DriverManagerDataSource">        
            <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
            <property name="url" value="jdbc:oracle:thin:@localhost:1521/orcl" />
            <property name="username" value="username" />
            <property name="password" value="password" />
        </bean>
        <bean id="Oracle_SessionFactory"
            class="org.springframework.orm.hibernate3.LocalSessionFactoryBean" 
            p:mappingLocations="classpath:/com/entity/*.hbm.xml">
            <property name="dataSource" ref="Oracle_DataSource" />        
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.query.factory_class">org.hibernate.hql.ast.ASTQueryTranslatorFactory</prop>
                    <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>                
                    <prop key="hibernate.show_sql">true</prop>
                    <prop key="hibernate.format_sql">true</prop>
                </props>
            </property>
        </bean>
        <bean id="Oracle_TransactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="Oracle_SessionFactory"/>
        </bean>
        
        
    </beans>

    2. 为SessionFactory配置事务切面:

    <tx:advice id="SqlServer_TxAdvice" transaction-manager="SqlServer_TransactionManager">
            <tx:attributes>
                <tx:method name="get*" read-only="true" />
                <tx:method name="find*" read-only="true" />
                <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />
            </tx:attributes>
        </tx:advice>
        <tx:advice id="Oracle_TxAdvice" transaction-manager="Oracle_TransactionManager">
            <tx:attributes>
                <tx:method name="get*" read-only="true" />
                <tx:method name="find*" read-only="true" />
                <tx:method name="*" propagation="REQUIRED" rollback-for="Exception" />
            </tx:attributes>
        </tx:advice>
        
        
        
        <aop:config proxy-target-class="true">  
            <aop:pointcut id="txPointcut" expression="execution(* com.service.*.*(..))"/>        
            <aop:advisor advice-ref="SqlServer_TxAdvice" pointcut-ref="txPointcut" order="1"/> 
            <aop:advisor advice-ref="Oracle_TxAdvice" pointcut-ref="txPointcut" order="2"/> 
        </aop:config>

    3. 配置一个动态的SessionFactory:

    <bean id="sessionFactory" class="com.DynamicSessionFactory"/>

    4. 定义DynamicSessionFactory实现接口SessionFactory:

    public class DynamicSessionFactory implements SessionFactory ,ApplicationContextAware{
        
        private static final long serialVersionUID = 1L;
    
        private ApplicationContext applicationContext;
        
        private SessionFactory getSessionFactory(String name) {
            return (SessionFactory) applicationContext.getBean(name);
        }
            //根据当前线程的SessionFactoryName获取SessionFactory
        private SessionFactory getSessionFactory() {
            return getSessionFactory(ThreadLocalUtil.
                    .getSessionFactoryName());
        }
    
        public Reference getReference() throws NamingException {
            return getSessionFactory().getReference();
        }
    
        
    
        public Session openSession() throws HibernateException {
            return getSessionFactory().openSession();
        }
    
        public Session openSession(Interceptor interceptor)
                throws HibernateException {
            return getSessionFactory().openSession(interceptor);
        }
    
        public Session openSession(Connection connection) {
            return getSessionFactory().openSession(connection);
        }
    
        public Session openSession(Connection connection, Interceptor interceptor) {
            return getSessionFactory().openSession(connection,interceptor);
        }
    
        public Session getCurrentSession() throws HibernateException {
            return getSessionFactory().getCurrentSession();
        }
    
        public StatelessSession openStatelessSession() {
            return getSessionFactory().openStatelessSession();
        }
    
        public StatelessSession openStatelessSession(Connection connection) {
            return getSessionFactory().openStatelessSession(connection);
        }
    
        public ClassMetadata getClassMetadata(Class entityClass) {
            return getSessionFactory().getClassMetadata(entityClass);
        }
    
        public ClassMetadata getClassMetadata(String entityName) {
            return getSessionFactory().getClassMetadata(entityName);
        }
    
        public CollectionMetadata getCollectionMetadata(String roleName) {
            return getSessionFactory().getCollectionMetadata(roleName);
        }
    
        public Map getAllClassMetadata() {
            return getSessionFactory().getAllClassMetadata();
        }
    
        public Map getAllCollectionMetadata() {
            return getSessionFactory().getAllCollectionMetadata();
        }
    
        public Statistics getStatistics() {
            return getSessionFactory().getStatistics();
        }
    
        public void close() throws HibernateException {
            getSessionFactory().close();
        }
    
        public boolean isClosed() {
            return getSessionFactory().isClosed();
        }
    
        public Cache getCache() {
            return getSessionFactory().getCache();
        }
    
        public void evict(Class persistentClass) throws HibernateException {
            getSessionFactory().evict(persistentClass);
        }
    
        public void evict(Class persistentClass, Serializable id)
                throws HibernateException {
            getSessionFactory().evict(persistentClass, id);
        }
    
        public void evictEntity(String entityName) throws HibernateException {
            getSessionFactory().evictEntity(entityName);
        }
    
        public void evictEntity(String entityName, Serializable id)
                throws HibernateException {
            getSessionFactory().evictEntity(entityName, id);
        }
    
        public void evictCollection(String roleName) throws HibernateException {
            getSessionFactory().evictCollection(roleName);
        }
    
        public void evictCollection(String roleName, Serializable id)
                throws HibernateException {
            getSessionFactory().evictCollection(roleName, id);
        }
    
        public void evictQueries(String cacheRegion) throws HibernateException {
            getSessionFactory().evictQueries(cacheRegion);
        }
    
        public void evictQueries() throws HibernateException {
            getSessionFactory().evictQueries();
        }
    
        public Set getDefinedFilterNames() {
            return getSessionFactory().getDefinedFilterNames();
        }
    
        public FilterDefinition getFilterDefinition(String filterName)
                throws HibernateException {
            return getSessionFactory().getFilterDefinition(filterName);
        }
    
        public boolean containsFetchProfileDefinition(String name) {
            return getSessionFactory().containsFetchProfileDefinition(name);
        }
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext)
                throws BeansException {
            this.applicationContext = applicationContext;
        }    
    
    }
  • 相关阅读:
    ruby中的特殊字符
    android and webview
    ActiveRecord::Base.establish_connection
    Ruby 创建目录
    不能手动输入或粘贴
    eclipse找不到 help>software update>find and install
    PL/SQL 创建、查看、操作用户
    XML文件
    javascript 获取页面高度(多种浏览器)(转)
    Eclipse to android
  • 原文地址:https://www.cnblogs.com/tangyanbo/p/4283482.html
Copyright © 2011-2022 走看看