spring整合hibernate多数据源

这篇博客详细介绍了如何在Spring中整合Hibernate以实现多数据源切换。配置包括两个基本的数据源`dataSource1`和`dataSource2`,然后通过`DynamicDataSource`进行动态数据源选择。使用`AbstractRoutingDataSource`的子类`DynamicDataSource`和`DataSourceHolder`来管理当前数据源。此外,还定义了注解`@DataSource`和切面`DataSourceAspect`,用于在AOP中根据注解动态切换数据源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!-- 整合hibernate -->
<context:component-scan base-package="service,dao"/>
<aop:aspectj-autoproxy/> 
<bean id="dataSource1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        ...
</bean>
<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        ...
</bean>
<bean id="dataSource" class="xxx.DynamicDataSource">
        <property name="targetDataSources">
            <map key-type="java.lang.String">
                <entry key="ds1" value-ref="dataSource1"/>
                <entry key="ds2" value-ref="dataSource2"/>
            </map>
        </property>
        <property name="defaultTargetDataSource" ref="dataSource1"/>
</bean>
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" lazy-init="false">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">none</prop>
                <!-- 每次读取的数目 -->
                <prop key="hibernate.jdbc.fetch_size">100</prop>
                <!-- 每次写入的数目 -->
                <prop key="hibernate.jdbc.batch_size">30</prop>
            </props>
        </property>
        <property name="packagesToScan" value="model"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<tx:annotation-driven transaction-manager="transactionManager" order="1"/>

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource{
    @Override
    protected Object determineCurrentLookupKey() {
        return DataSourceHolder.getDataSourceType(); 
    }
}

public class DataSourceHolder {
    private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();  
    public static void setDataSourceType(String dataSourceType) {  
        contextHolder.set(dataSourceType);  
    }
    public static String getDataSourceType() {
        return contextHolder.get();  
    } 
    public static void clearDataSourceType() { 
        contextHolder.remove(); 
    }
}

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSource {
    String value() default "";
}

import java.lang.reflect.Method;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(0)
@Aspect
@Component
public class DataSourceAspect {   
    Logger log = LoggerFactory.getLogger(DataSourceAspect.class);
    @Pointcut("execution(* service..*.*(..))")
    private void myMethod() {}
    
    @Around("myMethod()")
    public Object aroundLog(ProceedingJoinPoint pjb) {
        Object result = null;
        Class<?> clazz = pjb.getTarget().getClass();
        DataSource dataSource = clazz.getAnnotation(DataSource.class);
        if(dataSource!=null){
            String value = dataSource.value();
            DataSourceHolder.setDataSourceType(value);
        }
        MethodSignature methodSignature = (MethodSignature) pjb.getSignature();
        Method method = methodSignature.getMethod();
        if(method.isAnnotationPresent(DataSource.class)){
            dataSource = method.getAnnotation(DataSource.class);
            String value = dataSource.value();
            DataSourceHolder.setDataSourceType(value);
        }
        try {
            result =  pjb.proceed();
            if(dataSource!=null){
                DataSourceHolder.clearDataSourceType();
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
        return result;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值