企业宣传网站源码,电子商务网站建设的基本流程,wordpress 外部视频,可以给别人做ps设计的网站转载自 Spring Boot 集成 Mybatis 实现双数据源这里用到了Spring Boot Mybatis DynamicDataSource配置动态双数据源#xff0c;可以动态切换数据源实现数据库的读写分离。
添加依赖
加入Mybatis启动器#xff0c;这里添加了Druid连接池、Oracle数据库驱动为例。
depe…转载自 Spring Boot 集成 Mybatis 实现双数据源这里用到了Spring Boot Mybatis DynamicDataSource配置动态双数据源可以动态切换数据源实现数据库的读写分离。
添加依赖
加入Mybatis启动器这里添加了Druid连接池、Oracle数据库驱动为例。
dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactId
/dependencydependencygroupIdcom.alibaba/groupIdartifactIddruid/artifactId
/dependencydependencygroupIdcom.oracle/groupIdartifactIdojdbc6/artifactId
/dependency
添加启动类
EnableMybatis
EnableTransactionManagement
SpringBootApplication(exclude { DataSourceAutoConfiguration.class })
public class Application {public static void main(String[] args) {SpringApplication.run(ServiceApplication.class, args);}}
SpringBootApplication(exclude { DataSourceAutoConfiguration.class })这里用到了双数据源需要排除数据源的自动配置如果只有一个数据源用Spring Boot的自动配置就行。EnableTransactionManagement开启事务支持。
EnableMybatis开启Mybatis功能
Target(ElementType.TYPE)
Retention(RetentionPolicy.RUNTIME)
Documented
Import(MybatisConfig.class)
public interface EnableMybatis {}
Mybatis配置类
Configuration
MapperScan(basePackages DSConfig.BASE_PACKAGES)
public class MybatisConfig implements DSConfig {PrimaryBeanpublic DynamicDataSource dynamicDataSource(Qualifier(DB_MASTER) DataSource master,Qualifier(DB_SLAVE) DataSource slave) {MapObject, Object dsMap new HashMap();dsMap.put(DB_MASTER, master);dsMap.put(DB_MASTER, slave);DynamicDataSource dynamicDataSource new DynamicDataSource();dynamicDataSource.setDefaultTargetDataSource(master);dynamicDataSource.setTargetDataSources(dsMap);return dynamicDataSource;}Beanpublic PlatformTransactionManager transactionManager(DynamicDataSource dynamicDataSource) {return new DataSourceTransactionManager(dynamicDataSource);}Beanpublic SqlSessionFactory sqlSessionFactory(DynamicDataSource dynamicDataSource)throws Exception {SqlSessionFactoryBean sessionFactory new SqlSessionFactoryBean();sessionFactory.setDataSource(dynamicDataSource);sessionFactory.setMapperLocations(((ResourcePatternResolver) new PathMatchingResourcePatternResolver()).getResources(DSConfig.MAPPER_LOCATIONS));return sessionFactory.getObject();}}
DSConfig常量类
public interface DSConfig {String DS_PREFIX spring.datasource;String DS_ACTIVE active;String DB_MASTER db-master;String DB_SLAVE db-slave;String DRUID druid;String DRUID_MONITOR_USERNAME spring.druid.username;String DRUID_MONITOR_PASSWORD spring.druid.password;String DRUID_MONITOR_URL /druid/*;String DRUID_FILTER_EXCLUSIONS *.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*;String DRUID_FILTER_URL /*;String BASE_PACKAGES com.example.**.mapper;String MAPPER_LOCATIONS mapper/**/*.xml;}
连接池配置类
Druid连接池的自动配置类
Configuration
Import({ PropertiesConfig.class })
ConditionalOnClass(DruidDataSource.class)
ConditionalOnProperty(prefix DSConfig.DS_PREFIX, value DSConfig.DS_ACTIVE, havingValue DSConfig.DRUID)
public class DruidAutoConfig implements DSConfig {private Logger logger LoggerUtils.getLogger(this);Bean(name DB_MASTER, initMethod init, destroyMethod close)public DataSource dataSourceMaster(DruidMasterProperties masterProperties) throws SQLException {logger.debug(master properties: {}, masterProperties.toString());DruidDataSource dds new DruidDataSource();dds.setDriverClassName(masterProperties.getDriverClassName());dds.setUrl(masterProperties.getUrl());dds.setUsername(masterProperties.getUsername());dds.setPassword(masterProperties.getPassword());dds.setInitialSize(masterProperties.getInitialSize());dds.setMinIdle(masterProperties.getMinIdle());dds.setMaxActive(masterProperties.getMaxActive());dds.setMaxWait(masterProperties.getMaxWait());dds.setTimeBetweenEvictionRunsMillis(masterProperties.getTimeBetweenEvictionRunsMillis());dds.setMinEvictableIdleTimeMillis(masterProperties.getMinEvictableIdleTimeMillis());dds.setValidationQuery(masterProperties.getValidationQuery());dds.setTestOnBorrow(masterProperties.isTestOnBorrow());dds.setTestWhileIdle(masterProperties.isTestWhileIdle());dds.setTestOnReturn(masterProperties.isTestOnReturn());dds.setPoolPreparedStatements(masterProperties.isPoolPreparedStatements());dds.setMaxPoolPreparedStatementPerConnectionSize(masterProperties.getMaxPoolPreparedStatementPerConnectionSize());dds.setFilters(masterProperties.getFilters());return dds;}Bean(name DB_SLAVE, initMethod init, destroyMethod close)public DataSource dataSourceSlave(DruidSlaveProperties slaveProperties) throws SQLException {logger.debug(slave properties: {}, slaveProperties.toString());DruidDataSource dds new DruidDataSource();dds.setDriverClassName(slaveProperties.getDriverClassName());dds.setUrl(slaveProperties.getUrl());dds.setUsername(slaveProperties.getUsername());dds.setPassword(slaveProperties.getPassword());dds.setInitialSize(slaveProperties.getInitialSize());dds.setMinIdle(slaveProperties.getMinIdle());dds.setMaxActive(slaveProperties.getMaxActive());dds.setMaxWait(slaveProperties.getMaxWait());dds.setTimeBetweenEvictionRunsMillis(slaveProperties.getTimeBetweenEvictionRunsMillis());dds.setMinEvictableIdleTimeMillis(slaveProperties.getMinEvictableIdleTimeMillis());dds.setValidationQuery(slaveProperties.getValidationQuery());dds.setTestOnBorrow(slaveProperties.isTestOnBorrow());dds.setTestWhileIdle(slaveProperties.isTestWhileIdle());dds.setTestOnReturn(slaveProperties.isTestOnReturn());dds.setPoolPreparedStatements(slaveProperties.isPoolPreparedStatements());dds.setMaxPoolPreparedStatementPerConnectionSize(slaveProperties.getMaxPoolPreparedStatementPerConnectionSize());dds.setFilters(slaveProperties.getFilters());return dds;}Beanpublic ServletRegistrationBean druidServletRegistrationBean(EnvConfig env) {String username env.getStringValue(DSConfig.DRUID_MONITOR_USERNAME);String password env.getStringValue(DSConfig.DRUID_MONITOR_PASSWORD);return new ServletRegistrationBean(new DruidStatViewServlet(username, password),DSConfig.DRUID_MONITOR_URL);}Beanpublic FilterRegistrationBean druidFilterRegistrationBean() {WebStatFilter wsf new WebStatFilter();FilterRegistrationBean filterRegistrationBean new FilterRegistrationBean();filterRegistrationBean.setFilter(wsf);filterRegistrationBean.setUrlPatterns(Arrays.asList(DSConfig.DRUID_FILTER_URL));filterRegistrationBean.setInitParameters(Collections.singletonMap(exclusions, DSConfig.DRUID_FILTER_EXCLUSIONS));return filterRegistrationBean;}}
根据类路径下有DruidDataSource这个类即有Druid这个jar包和配置文件中spring.datasource.activedruid才开启对Druid连接池的自动配置。
导入的配置文件
Configuration
ComponentScan(basePackages com.example.common.config.properties)
public class PropertiesConfig {}
DruidMasterProperties、DruidSlaveProperties属性文件读取的配置省略。
连接池监控配置类
public class DruidStatViewServlet extends StatViewServlet {private static final long serialVersionUID 1L;private String username;private String password;Overridepublic String getInitParameter(String name) {if (loginUsername.equals(name)) {return username;}if (loginPassword.equals(name)) {return password;}return super.getInitParameter(name);}public DruidStatViewServlet(String username, String password) {super();this.username username;this.password password;}public String getUsername() {return username;}public String getPassword() {return password;}}
在META-INF/spring.factories中加入Druid自动配置映射
org.springframework.boot.autoconfigure.EnableAutoConfiguration\
com.example.common.config.ds.DruidAutoConfig切换数据源
切换数据源注解
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
Documented
public interface DS {String value() default DSConfig.DB_MASTER;
}
动态数据源类
public class DynamicDataSource extends AbstractRoutingDataSource {private final Logger logger LoggerUtils.getLogger(this);Overrideprotected Object determineCurrentLookupKey() {logger.debug(当前数据源为{}, DataSourceContextHolder.getDS());return DataSourceContextHolder.getDS();}}
动态数据源AOP实现类
Aspect
Component
public class DynamicDataSourceAspect {Before(annotation(DS))public void beforeSwitchDS(JoinPoint point) {Class? className point.getTarget().getClass();String methodName point.getSignature().getName();Class?[] argClass ((MethodSignature) point.getSignature()).getParameterTypes();String dataSource DataSourceContextHolder.DEFAULT_DS;try {Method method className.getMethod(methodName, argClass);if (method.isAnnotationPresent(DS.class)) {DS annotation method.getAnnotation(DS.class);dataSource annotation.value();}} catch (Exception e) {e.printStackTrace();}DataSourceContextHolder.setDS(dataSource);}After(annotation(DS))public void afterSwitchDS(JoinPoint point) {DataSourceContextHolder.clearDS();}}
绑定当前线程数据源类
public class DataSourceContextHolder {public static final String DEFAULT_DS DSConfig.DB_MASTER;private static final ThreadLocalString DS_HOLDER new ThreadLocal();public static void setDS(String dbType) {DS_HOLDER.set(dbType);}public static String getDS() {return (DS_HOLDER.get());}public static void clearDS() {DS_HOLDER.remove();}
}