DataBaseConfig.java
package com.banksteel.finance.inventorybook.db;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
/**
*
* @description: 数据库配置
* @projectName:banksteel-finance-voucher-service
* @author:
* @createTime:2017年12月12日 下午2:16:50
*/
@Component
public class DataBaseConfig implements EnvironmentAware
{
private Environment environment;
@Override
public void setEnvironment(Environment environment)
{
this.environment = environment;
}
private DataSource readDataSource()
{
DriverManagerDataSource datasource = new DriverManagerDataSource();
datasource.setDriverClassName(environment.getRequiredProperty("dataSource.driverClassName"));
datasource.setUrl(environment.getRequiredProperty("read.dataSource.url") );
datasource.setUsername(environment.getRequiredProperty("read.dataSource.username"));
datasource.setPassword(environment.getRequiredProperty("read.dataSource.password"));
return datasource;
}
// private DataSource masterDataSource()
// {
// DriverManagerDataSource datasource = new DriverManagerDataSource();
// datasource.setDriverClassName(environment.getRequiredProperty("dataSource.driverClassName"));
// datasource.setUrl(environment.getRequiredProperty("dataSource.url") );
// datasource.setUsername(environment.getRequiredProperty("dataSource.username"));
// datasource.setPassword(environment.getRequiredProperty("dataSource.password"));
// return datasource;
// }
@Bean(name = "dataSource")
public DynamicDataSource dataSource()
{
// DataSource master = masterDataSource();
DataSource read = readDataSource();
Map<Object, Object> targetDataSources = new HashMap<>();
targetDataSources.put(DataSourceTarget.READ, read);
// targetDataSources.put(DataSourceTarget.WRITE,master );
DynamicDataSource dataSource = new DynamicDataSource();
dataSource.setTargetDataSources(targetDataSources);
dataSource.setDefaultTargetDataSource(read);
// dataSource.setDefaultTargetDataSource(master);
return dataSource;
}
@Bean(name = "sessionFactory")
public SqlSessionFactory sqlSessionFactory(AbstractRoutingDataSource dynamicDataSource) throws Exception
{
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
Properties configurationProperties = new Properties();
configurationProperties.put("cacheEnabled", true);
configurationProperties.put("lazyLoadingEnabled", true);
configurationProperties.put("aggressiveLazyLoading", false);
configurationProperties.put("multipleResultSetsEnabled", true);
configurationProperties.put("useColumnLabel", true);
configurationProperties.put("useGeneratedKeys", true);
configurationProperties.put("autoMappingBehavior", "FULL");
configurationProperties.put("defaultExecutorType", "BATCH");
configurationProperties.put("defaultStatementTimeout", 25000);
sqlSessionFactoryBean.setConfigurationProperties(configurationProperties);
// 设置动态数据源
sqlSessionFactoryBean.setDataSource(dynamicDataSource);
// 设置mybatis的配置文件路径
sqlSessionFactoryBean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
// 设置mapper文件路径
PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
sqlSessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver
.getResources("classpath*:mybatis/mapper/*_mapper.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer(){
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.banksteel.finance.**.dao");
mapperScannerConfigurer.setAnnotationClass(Repository.class);
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sessionFactory");
return mapperScannerConfigurer;
}
@Bean
public DataSourceTransactionManager dataSourceTransactionManager(AbstractRoutingDataSource dynamicDataSource)
{
DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dynamicDataSource);
return dataSourceTransactionManager;
}
}
DataSourceAspect.java,这里是切入点,主要从这里开始的
package com.banksteel.finance.inventorybook.db;
import java.lang.reflect.Method;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//@Aspect
//@Component
public class DataSourceAspect
{
private static final Logger logger = LoggerFactory.getLogger(DataSourceAspect.class);
@Pointcut("execution(* com.banksteel.finance.inventorybook.dao.*.*(..))")
private void aspectPoint(){}//定义一个切入点
/**
*
*
* @param joinPoint
* 切点
*/
@After("aspectPoint()")
public void doBefore(JoinPoint point)
{
Object target = point.getTarget();
String method = point.getSignature().getName();
Class<?>[] classz = target.getClass().getInterfaces();
Class<?>[] parameterTypes = ((MethodSignature) point.getSignature()).getMethod().getParameterTypes();
Method m = null;
try
{
m = classz[0].getMethod(method, parameterTypes);
} catch (Exception e)
{
logger.error(e.getMessage());
return;
}
if (m != null && m.isAnnotationPresent(DataSourceTarget.class))
{
DataSourceTarget data = m.getAnnotation(DataSourceTarget.class);// 获取访问mapper中的注释
DynamicDataSourceHolder.putDataSource(data.value());// 获取注释中的value值,确定访问的数据源
logger.error("DataSourceAspect:=======================" + data.value());
}else {
DynamicDataSourceHolder.putDataSource(DataSourceTarget.master);
logger.error("DataSourceAspect:======================= master");
}
}
}
DataSourceTarget.java
package com.banksteel.finance.inventorybook.db;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType;
/***
* 数据库annotation定义
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DataSourceTarget {
String value() default DataSourceTarget.master;
public static String master = "writeDataSource";
public static String READ = "readDataSource";
public static String WRITE = "writeDataSource";
}
DynamicDataSource.java
package com.banksteel.finance.inventorybook.db;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
*
* @description: 动态数据源,动态获取数据源的实现
* @projectName:banksteel-finance-voucher-service
* @author:
* @createTime:2017年12月12日 上午10:49:17
*/
public class DynamicDataSource extends AbstractRoutingDataSource
{
/**
* 用户返回当且切换到的数据库
*/
@Override
protected Object determineCurrentLookupKey()
{
//DynamicDataSourceHolder有获取和设置当前数据库的方法get & put
return DynamicDataSourceHolder.getDataSource();
}
}
DynamicDataSourceHolder.java
package com.banksteel.finance.inventorybook.db;
/**
*
* @description: 动态数据源holder
* @projectName:banksteel-finance-voucher-service
* @author:
* @createTime:2017年12月12日 上午10:47:38
*/
public class DynamicDataSourceHolder
{
public static final ThreadLocal<String> holder = new ThreadLocal<String>();
public static void putDataSource(String name)
{
holder.set(name);
}
public static String getDataSource()
{
return holder.get();
}
}