├── pom.xml └── src └── main ├── java └── com │ └── jorden │ ├── ApplicationStart.java │ ├── aop │ └── DynamicDataSourceAspect.java │ ├── base │ └── BaseDao.java │ ├── config │ └── DataSourceConfig.java │ ├── core │ └── DynamicDataSource.java │ ├── dao │ └── UserDao.java │ ├── entity │ └── User.java │ ├── enums │ └── DynDataSourceEnum.java │ ├── service │ ├── UserService.java │ └── impl │ │ └── UserServiceImpl.java │ └── web │ └── UserContorller.java └── resources ├── application.properties └── logback-spring.xml /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | springboot-read-write 5 | springboot-read-write 6 | 0.0.1-SNAPSHOT 7 | 8 | 9 | 10 | org.springframework.boot 11 | spring-boot-starter-parent 12 | 1.4.7.RELEASE 13 | 14 | 15 | 16 | org.springframework.boot 17 | spring-boot-starter-web 18 | 19 | 20 | org.springframework.boot 21 | spring-boot-starter-test 22 | test 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-jdbc 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-aop 31 | 32 | 33 | mysql 34 | mysql-connector-java 35 | 36 | 37 | com.alibaba 38 | druid 39 | 1.1.5 40 | 41 | 42 | 43 | org.scala-lang 44 | scala-library 45 | 2.11.0 46 | 47 | 48 | org.javassist 49 | javassist 50 | 51 | 52 | org.apache.hadoop 53 | hadoop-core 54 | 1.0.0 55 | 56 | 57 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/ApplicationStart.java: -------------------------------------------------------------------------------- 1 | package com.jorden; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; 6 | /** 7 | * 项目启动主类 8 | * 9 | * @ClassName: ApplicationStart 10 | * @Description:TODO(这里用一句话描述这个类的作用) 11 | * @author: jorden.li 12 | * @date: 2018年4月2日 上午11:23:49 13 | * 14 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 15 | * Success is never final. Failure is never fatal. Courage is what counts. -Sir Winston Churchill 16 | */ 17 | @SpringBootApplication(exclude={DataSourceAutoConfiguration.class}) 18 | public class ApplicationStart { 19 | 20 | public static void main(String[] args) { 21 | SpringApplication.run(ApplicationStart.class, args); 22 | } 23 | 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/aop/DynamicDataSourceAspect.java: -------------------------------------------------------------------------------- 1 | package com.jorden.aop; 2 | 3 | import java.lang.reflect.Method; 4 | 5 | import org.aspectj.lang.JoinPoint; 6 | import org.aspectj.lang.annotation.After; 7 | import org.aspectj.lang.annotation.Aspect; 8 | import org.aspectj.lang.annotation.Before; 9 | import org.aspectj.lang.annotation.Pointcut; 10 | import org.aspectj.lang.reflect.MethodSignature; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.core.annotation.Order; 14 | import org.springframework.stereotype.Component; 15 | 16 | import com.jorden.core.DynamicDataSource; 17 | import com.jorden.enums.DynDataSourceEnum; 18 | 19 | /** 20 | * 21 | * @ClassName: DynamicDataSourceAspect 22 | * @Description:TODO(这里用一句话描述这个类的作用) 23 | * @author: jorden.li 24 | * @date: 2018年4月2日 下午1:21:36 25 | * 26 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. Success is never 27 | * final. Failure is never fatal. Courage is what counts. -Sir 28 | * Winston Churchill 29 | */ 30 | @Order(-1) // 在 @Transactional 执行 31 | @Aspect 32 | @Component 33 | public class DynamicDataSourceAspect { 34 | 35 | public Logger logger=LoggerFactory.getLogger(DynamicDataSourceAspect.class); 36 | 37 | @Before(value = "execution(* com.jorden.service..*.*(..))") 38 | public void changeDataSource(JoinPoint point) throws Throwable { 39 | 40 | /* 获取当前的方法 */ 41 | Class currentClass = point.getTarget().getClass(); 42 | logger.info("访问当前的类: " + currentClass.getName()); 43 | //slaveDataSource masterDataSource 44 | //定义的接口方法 45 | Method abstractMethod = ((MethodSignature) point.getSignature()).getMethod(); 46 | String currentMethodName=abstractMethod.getName().toUpperCase(); 47 | if(currentMethodName.contains(DynDataSourceEnum.SELECT.toString())||currentMethodName.contains(DynDataSourceEnum.FIND.toString())){ 48 | logger.info("切换数据源,现在是读请求"); 49 | DynamicDataSource.setDataSource("master"); 50 | 51 | }else{ 52 | logger.info("切换数据源,现在是写请求"); 53 | DynamicDataSource.setDataSource("slave"); 54 | } 55 | } 56 | 57 | @Pointcut("execution(* com.jorden.service..*.*(..))") 58 | public void pointCut() { 59 | } 60 | 61 | @After("pointCut()") 62 | public void after(JoinPoint point) { 63 | logger.info("after"); 64 | // DynamicDataSource.clearDataSource(); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/base/BaseDao.java: -------------------------------------------------------------------------------- 1 | package com.jorden.base; 2 | 3 | import java.util.List; 4 | /** 5 | * 6 | * @ClassName: BaseDao 7 | * @Description:TODO(这里用一句话描述这个类的作用) 8 | * @author: jorden.li 9 | * @date: 2018年4月2日 上午11:25:41 10 | * 11 | * @param 12 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 13 | * Success is never final. Failure is never fatal. Courage is what counts. -Sir Winston Churchill 14 | */ 15 | public interface BaseDao { 16 | 17 | 18 | /** 19 | * 20 | * @Title: selectAll 21 | * @Description: TODO(这里用一句话描述这个方法的作用) 22 | * @param: @return 23 | * @return: List 24 | * @throws 25 | */ 26 | List selectAll(); 27 | 28 | /** 29 | * 30 | * @Title: selectOne 31 | * @Description: TODO(这里用一句话描述这个方法的作用) 32 | * @param: @param t 33 | * @param: @return 34 | * @return: T 35 | * @throws 36 | */ 37 | T selectByPirmayKey(T t); 38 | /** 39 | * 40 | * @Title: deleteByPrimayKey 41 | * @Description: TODO(这里用一句话描述这个方法的作用) 42 | * @param: @param t 43 | * @return: void 44 | * @throws 45 | */ 46 | void deleteByPrimayKey(T t ); 47 | 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/config/DataSourceConfig.java: -------------------------------------------------------------------------------- 1 | package com.jorden.config; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | import javax.sql.DataSource; 7 | 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder; 10 | import org.springframework.boot.context.properties.ConfigurationProperties; 11 | import org.springframework.context.annotation.Bean; 12 | import org.springframework.context.annotation.Configuration; 13 | import org.springframework.jdbc.core.JdbcTemplate; 14 | 15 | import com.jorden.core.DynamicDataSource; 16 | 17 | /** 18 | * DataSourceConfig 配置 19 | * @ClassName: DataSourceConfig 20 | * @Description:TODO(这里用一句话描述这个类的作用) 21 | * @author: jorden.li 22 | * @date: 2018年4月2日 上午10:56:36 23 | * 24 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 25 | * Success is never final. Failure is never fatal. Courage is what counts. -Sir Winston Churchill 26 | */ 27 | @Configuration 28 | public class DataSourceConfig { 29 | 30 | @Value("${spring.datasource.type}") 31 | private Class < ? extends DataSource> dataSourceType; 32 | /** 33 | * master 配置 34 | * @Title: masterDataSource 35 | * @Description: TODO(这里用一句话描述这个方法的作用) 36 | * @param: @return 37 | * @return: DataSource 38 | * @throws 39 | */ 40 | @Bean(name="masterDataSource",destroyMethod="close",initMethod="init") 41 | @ConfigurationProperties(prefix="spring.datasource.master") 42 | public DataSource masterDataSource(){ 43 | return DataSourceBuilder.create().type(dataSourceType).build(); 44 | } 45 | /** 46 | * slave 配置 47 | * @Title: slaveDataSource 48 | * @Description: TODO(这里用一句话描述这个方法的作用) 49 | * @param: @return 50 | * @return: DataSource 51 | * @throws 52 | */ 53 | @Bean(name="slaveDataSource",destroyMethod="close",initMethod="init") 54 | @ConfigurationProperties(prefix="spring.datasource.slave") 55 | public DataSource slaveDataSource(){ 56 | return DataSourceBuilder.create().type(dataSourceType).build(); 57 | 58 | } 59 | @Bean(name="dataSource") 60 | public DataSource dataSource(){ 61 | DynamicDataSource dataSource=new DynamicDataSource(); 62 | // 配置多数据源 63 | Map targetDataSources = new HashMap<>(); 64 | targetDataSources.put("master", masterDataSource()); 65 | targetDataSources.put("slave", slaveDataSource()); 66 | dataSource.setTargetDataSources(targetDataSources); 67 | dataSource.setDefaultTargetDataSource(masterDataSource()); 68 | return dataSource; 69 | } 70 | 71 | @Bean(name="jdbcTemplate") 72 | public JdbcTemplate getJdbcTemplate(){ 73 | JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource()); 74 | return jdbcTemplate; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/core/DynamicDataSource.java: -------------------------------------------------------------------------------- 1 | package com.jorden.core; 2 | 3 | import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; 4 | /** 5 | * 6 | * @ClassName: DynamicDataSource 7 | * @Description:TODO(这里用一句话描述这个类的作用) 8 | * @author: jorden.li 9 | * @date: 2018年4月2日 上午11:14:52 10 | * 11 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 12 | * Success is never final. Failure is never fatal. Courage is what counts. -Sir Winston Churchill 13 | */ 14 | public class DynamicDataSource extends AbstractRoutingDataSource{ 15 | 16 | private static final ThreadLocal datasourceHolder = new ThreadLocal<>(); 17 | 18 | @Override 19 | public Object determineCurrentLookupKey() { 20 | return datasourceHolder.get(); 21 | } 22 | 23 | public static void setDataSource(String sourceName) { 24 | datasourceHolder.set(sourceName); 25 | } 26 | 27 | public static void clearDataSource() { 28 | datasourceHolder.remove(); 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/dao/UserDao.java: -------------------------------------------------------------------------------- 1 | package com.jorden.dao; 2 | 3 | import com.jorden.base.BaseDao; 4 | import com.jorden.entity.User; 5 | 6 | /** 7 | * 8 | * @ClassName: UserDao 9 | * @Description:TODO(这里用一句话描述这个类的作用) 10 | * @author: jorden.li 11 | * @date: 2018年4月2日 上午10:49:59 12 | * 13 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 14 | * Success is never final. Failure is never fatal. Courage is what counts. -Sir Winston Churchill 15 | */ 16 | public interface UserDao extends BaseDao { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.jorden.entity; 2 | 3 | public class User { 4 | 5 | 6 | private String name; 7 | 8 | private int age ; 9 | 10 | private int id; 11 | 12 | public String getName() { 13 | return name; 14 | } 15 | 16 | public void setName(String name) { 17 | this.name = name; 18 | } 19 | 20 | public int getAge() { 21 | return age; 22 | } 23 | 24 | public void setAge(int age) { 25 | this.age = age; 26 | } 27 | 28 | public int getId() { 29 | return id; 30 | } 31 | 32 | public void setId(int id) { 33 | this.id = id; 34 | } 35 | 36 | public User() { 37 | // TODO Auto-generated constructor stub 38 | } 39 | 40 | 41 | 42 | public User(int id) { 43 | super(); 44 | this.id = id; 45 | } 46 | 47 | public User(String name, int age, int id) { 48 | super(); 49 | this.name = name; 50 | this.age = age; 51 | this.id = id; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/enums/DynDataSourceEnum.java: -------------------------------------------------------------------------------- 1 | package com.jorden.enums; 2 | /** 3 | * 4 | * @ClassName: DynDataSourceEnum 5 | * @Description:TODO(这里用一句话描述这个类的作用) 6 | * @author: jorden.li 7 | * @date: 2018年4月2日 下午2:01:29 8 | * 9 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 10 | * Success is never final. Failure is never fatal. Courage is what counts. -Sir Winston Churchill 11 | */ 12 | public enum DynDataSourceEnum { 13 | SELECT,DELETE,FIND,UPDATE,REMOVE 14 | } 15 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.jorden.service; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import com.jorden.entity.User; 7 | 8 | /** 9 | * 10 | * @ClassName: UserService 11 | * @Description:TODO(这里用一句话描述这个类的作用) 12 | * @author: jorden.li 13 | * @date: 2018年4月2日 上午10:49:43 14 | * 15 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 16 | * Success is never final. Failure is never fatal. Courage is what counts. -Sir Winston Churchill 17 | */ 18 | public interface UserService { 19 | 20 | /** 21 | * 22 | * @Title: selectAll 23 | * @Description: TODO(这里用一句话描述这个方法的作用) 24 | * @param: @return 25 | * @return: List> 26 | * @throws 27 | */ 28 | List> selectAll(); 29 | 30 | /** 31 | * 32 | * @Title: selectOne 33 | * @Description: TODO(这里用一句话描述这个方法的作用) 34 | * @param: @param t 35 | * @param: @return 36 | * @return: T 37 | * @throws 38 | */ 39 | User selectByPirmayKey(User t); 40 | /** 41 | * 42 | * @Title: deleteByPrimayKey 43 | * @Description: TODO(这里用一句话描述这个方法的作用) 44 | * @param: @param t 45 | * @return: void 46 | * @throws 47 | */ 48 | void deleteByPrimayKey(User t ); 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/service/impl/UserServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.jorden.service.impl; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.jdbc.core.JdbcTemplate; 8 | import org.springframework.stereotype.Service; 9 | 10 | import com.jorden.entity.User; 11 | import com.jorden.service.UserService; 12 | /** 13 | * 14 | * @ClassName: UserServiceImpl 15 | * @Description:TODO(这里用一句话描述这个类的作用) 16 | * @author: jorden.li 17 | * @date: 2018年4月2日 上午10:49:39 18 | * 19 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 20 | * Success is never final. Failure is never fatal. Courage is what counts. -Sir Winston Churchill 21 | */ 22 | @Service 23 | public class UserServiceImpl implements UserService{ 24 | 25 | @Autowired 26 | JdbcTemplate jdbcTemplate; 27 | 28 | @Override 29 | public List> selectAll() { 30 | return jdbcTemplate.queryForList("select * from user"); 31 | } 32 | 33 | @Override 34 | public User selectByPirmayKey(User t) { 35 | // TODO Auto-generated method stub 36 | return null; 37 | } 38 | 39 | @Override 40 | public void deleteByPrimayKey(User t) { 41 | jdbcTemplate.update("delete from user where id = "+t.getId()); 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/jorden/web/UserContorller.java: -------------------------------------------------------------------------------- 1 | package com.jorden.web; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | import org.springframework.beans.factory.annotation.Autowired; 7 | import org.springframework.http.ResponseEntity; 8 | import org.springframework.web.bind.annotation.RequestMapping; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import com.jorden.entity.User; 12 | import com.jorden.service.UserService; 13 | /** 14 | * 15 | * @ClassName: UserContorller 16 | * @Description:TODO(这里用一句话描述这个类的作用) 17 | * @author: jorden.li 18 | * @date: 2018年4月2日 下午1:03:57 19 | * 20 | * @Copyright: 2018 www.tydic.com Inc. All rights reserved. 21 | * Success is never final. Failure is never fatal. Courage is what counts. -Sir Winston Churchill 22 | */ 23 | @RestController 24 | @RequestMapping("user") 25 | public class UserContorller { 26 | 27 | @Autowired 28 | UserService userService; 29 | /** 30 | * 31 | * @Title: getList 32 | * @Description: TODO(这里用一句话描述这个方法的作用) 33 | * @param: @return 34 | * @return: ResponseEntity> 35 | * @throws 36 | */ 37 | @RequestMapping("/getList") 38 | public ResponseEntity> > getList(){ 39 | return ResponseEntity.ok(userService.selectAll()); 40 | 41 | } 42 | @RequestMapping("/deleteForPrimayKey") 43 | public ResponseEntity deleteForPrimayKey(){ 44 | userService.deleteByPrimayKey(new User(7)); 45 | return ResponseEntity.ok("success"); 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.datasource.type=com.alibaba.druid.pool.DruidDataSource 2 | spring.datasource.master.driver-class-name=com.mysql.jdbc.Driver 3 | spring.datasource.master.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8 4 | spring.datasource.master.username=root 5 | spring.datasource.master.password=123456 6 | spring.datasource.slave.driver-class-name=com.mysql.jdbc.Driver 7 | spring.datasource.slave.url=jdbc:mysql://localhost:3306/rediscloud?useUnicode=true&characterEncoding=utf8 8 | spring.datasource.slave.username=root 9 | spring.datasource.slave.password=123456 10 | 11 | server.port=8099 12 | 13 | # \u914D\u7F6Elogback 14 | logging.config=classpath:logback-spring.xml -------------------------------------------------------------------------------- /src/main/resources/logback-spring.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | %date [%thread] %-5level %logger{50}:%L - %msg%n 12 | 13 | 14 | 15 | 16 | 17 | 18 | ${logDir}/service.log 19 | 20 | ${logDir}/history/service.%d{yyyy-MM-dd}.log.gz 21 | 30 22 | 23 | 24 | %date [%thread] %-5level %logger{50}:%L - %msg%n 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | --------------------------------------------------------------------------------