spring-boot动态数据源 2019-11-24 程序之旅 2 条评论 2904 次阅读 ## spring-boot动态数据源 ### 配置步骤 1. 创建读和写的数据源 2. 将读和写的数据源注册到RoutingDataSource 3. 使用AOP技术拦截业务逻辑层方法,判断方法的前缀是否需要做读或者写 ### 功能实现 首先创建一个spring boot项目 项目导包 ```xml 4.0.0 groupId spring-boot-mycat 1.0-SNAPSHOT org.springframework.boot spring-boot-starter-parent 2.0.4.RELEASE org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 1.3.2 mysql mysql-connector-java runtime org.springframework.boot spring-boot-starter-test test com.alibaba druid 1.0.23 org.projectlombok lombok 1.18.10 org.springframework.boot spring-boot-maven-plugin ``` 由于之前已经搭建好读写分离的mycat,所以这里在项目中配置: ```yml spring: datasource: ## 可读数据源 select: jdbc-url: jdbc:mysql://localhost:8066/mycat_testdb driver-class-name: com.mysql.jdbc.Driver username: user password: ******* ## 可写数据源 update: jdbc-url: jdbc:mysql://localhost:8066/mycat_testdb driver-class-name: com.mysql.jdbc.Driver username: root password: ****** type: com.alibaba.druid.pool.DruidDataSource ``` 之后在项目中创建需要的实体类、dao层和service层方法 ```java /** * UserEntity * * @author liurui * @Description: * @date 2019/11/24 */ @Data public class UserEntity { private String userName; } import com.felton.db.UserEntity; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; public interface UserMapper { @Select("SELECT * FROM user_info ") public List findUser(); @Select("insert into user_info values (#{userName}); ") public List insertUser(@Param("userName") String userName); } @Service public class UserService { @Autowired private UserMapper userMapper; public List findUser() { return userMapper.findUser(); } public List insertUser(String userName) { return userMapper.insertUser(userName); } } ``` 配置多数据源 ```java /** * DataSourceConfig * * @author liurui * @Description: * @date 2019/11/24 */ @Configuration public class DataSourceConfig { @Bean(name = "selectDataSource") @ConfigurationProperties(prefix = "spring.datasource.select") public DataSource dataSource1(){ return DataSourceBuilder.create().build(); } @Bean(name = "updateDataSource") @ConfigurationProperties(prefix = "spring.datasource.update") public DataSource dataSource2(){ return DataSourceBuilder.create().build(); } } ``` 创建一个改变数据源的类,采用ThreadLocal 保存本地多数据源 ```java @Component @Lazy(false) public class DataSourceContextHolder { // 采用ThreadLocal 保存本地多数据源 private static final ThreadLocal contextHolder = new ThreadLocal<>(); // 设置数据源类型 public static void setDbType(String dbType) { contextHolder.set(dbType); } public static String getDbType() { return contextHolder.get(); } public static void clearDbType() { contextHolder.remove(); } } ``` 创建动态数据源类,继承`AbstractRoutingDataSource`,重写改变数据源的方法`determineCurrentLookupKey()` ```java @Component @Primary public class DynamicDataSource extends AbstractRoutingDataSource { @Autowired @Qualifier("selectDataSource") private DataSource selectDataSource; @Autowired @Qualifier("updateDataSource") private DataSource updateDataSource; /** * 这个是主要的方法,返回的是生效的数据源名称 */ @Override protected Object determineCurrentLookupKey() { System.out.println("DataSourceContextHolder:::" + DataSourceContextHolder.getDbType()); return DataSourceContextHolder.getDbType(); } /** * 配置数据源信息 */ @Override public void afterPropertiesSet() { Map map = new HashMap<>(); map.put("selectDataSource", selectDataSource); map.put("updateDataSource", updateDataSource); setTargetDataSources(map); setDefaultTargetDataSource(updateDataSource); super.afterPropertiesSet(); } } ``` 最后的是使用AOP来区分判断读写 ```java @Aspect @Component @Lazy(false) @Order(0) // Order设定AOP执行顺序 使之在数据库事务上先执行 public class SwitchDataSourceAOP { // 这里切到你的方法目录 @Before("execution(* com.mayikt.service.*.*(..))") public void process(JoinPoint joinPoint) { String methodName = joinPoint.getSignature().getName(); if (methodName.startsWith("get") || methodName.startsWith("count") || methodName.startsWith("find") || methodName.startsWith("list") || methodName.startsWith("select") || methodName.startsWith("check")) { DataSourceContextHolder.setDbType("selectDataSource"); } else { // 切换dataSource DataSourceContextHolder.setDbType("updateDataSource"); } } } ``` 打赏: 微信, 支付宝 标签: java, mysql, mycat, 数据源 本作品采用 知识共享署名-相同方式共享 4.0 国际许可协议 进行许可。
突然发现刘老板换了新图标
必须的