1. Import the corresponding jar package dependencies
<!-- Integrate mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- Distributed Transaction Management--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>
2. Configure multiple data sources
2.1 Configure the connection of multiple data sources in application.xml
spring: datasource: test1: url: jdbc:mysql://localhost:3306/test username: root password: root driver-class-name: com.mysql.jdbc.Driver testQuery: select 1 test2: url: jdbc:mysql://localhost:3306/test1 username: root password: root driver-class-name: com.mysql.jdbc.Driver testQuery: select 1 mybatis: mapper-locations: classpath:mapping/*.xml
2.2 Create a connection information configuration class for multiple databases
@ConfigurationProperties(prefix="spring.datasource.test1") @Primary public class DB1Config { private String url; private String username; private String password; private String testQuery; public String getUrl() { return url; }
...add get and set methods, if multiple data sources are to be configured with multiple
}
2.3 Create a configuration class for multiple data sources, and hand over different data sources to atomikos of jta for unified management (multiple data sources are configured with multiple such files)
@Configuration // Register in the spring boot container @MapperScan(basePackages="com.beifeng.hadoop.spring.boot.dao.jta.test1",sqlSessionFactoryRef="jtaTest1SqlSessionFactory" ) public class JtaDataSource1Config { @Bean(name="jtaTest1DataSource") @Primary//Only one data source is designated as the main data source in a project public DataSource testDataSource(DB1Config db1Config){ MysqlXADataSource dataSource=new MysqlXADataSource(); dataSource.setUrl(db1Config.getUrl()); dataSource.setUser(db1Config.getUsername()); dataSource.setPassword(db1Config.getPassword()); dataSource.setPinGlobalTxToPhysicalConnection(true); //Call the data source an atomikos for unified management AtomikosDataSourceBean atomikosDataSource = new AtomikosDataSourceBean (); atomikosDataSource.setXaDataSource (dataSource); atomikosDataSource.setUniqueResourceName("jtaTest1DataSource"); atomikosDataSource.setTestQuery (db1Config.getTestQuery ()); return atomikosDataSource; } @Bean(name="jtaTest1SqlSessionFactory") @Primary public SqlSessionFactory testSqlSessionFactory(@Qualifier("jtaTest1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean=new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean(name="jtaTest1SqlSessionTemplate") @Primary public SqlSessionTemplate testSqlSessionTemplate(@Qualifier("jtaTest1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }
2.4 Declarative transaction configuration in service
@Service public class Test1JtaUserService { @Autowired//Introduce different data sources private JtaUser1Dao jtaUser1Dao; @Autowired private JtaUser2Dao jtaUser2Dao; @Transactional//Declarative transaction public void insertJtaUser(String name,Integer age) { jtaUser1Dao.insertUser(name, age); jtaUser2Dao.insertUser(name, age); int a=1/0 ;//If an exception occurs, the distributed transaction will be rolled back at the same time } }
2.5 Declare the configuration of multiple data sources in the startup class
@SpringBootApplication @MapperScan( "com.beifeng.hadoop.spring.boot.dao" )//Specify the dao scan package path of mybatis @EnableConfigurationProperties(value ={DB1Config.class , DB2Config.class } )//Specify the configuration of multiple data sources public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
3 aop aspect programming
@Aspect @Component public class WebLogAspect { private Logger logger=LoggerFactory.getLogger(WebLogAspect.class); private Long startTime; @Pointcut("execution(public * com.beifeng.hadoop.spring.boot.controller..*.*(..))") public void webLog() { } @Before("webLog()") public void doBefore(JoinPoint joinPoint) { logger.info( "==============Start request=============" ); startTime = System.currentTimeMillis(); // Receive the request, record the request content ServletRequestAttributes requestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest httpServletRequest=requestAttributes.getRequest(); logger.info("url: "+httpServletRequest.getRequestURL()); logger.info("http_method: "+httpServletRequest.getMethod()); logger.info("ip "+httpServletRequest.getRemoteAddr()); Enumeration<String> parameterNames = httpServletRequest.getParameterNames(); while (parameterNames.hasMoreElements()) { String parameterName = (String) parameterNames.nextElement(); logger.info("parameter:{}->{}",parameterName,httpServletRequest.getParameter(parameterName)); } } @AfterReturning(returning ="ret",pointcut="webLog()" ) public void doAfterReturning(Object ret) { // After processing the request, return the content logger.info("response result: "+ ret); logger.info( "==============Start and end, time-consuming"+(System.currentTimeMillis()-startTime)+"milliseconds============ =" ); } }