系列导航

springBoot项目打jar包

1、springboot工程新建(单模块)

2、springboot创建多模块工程

3、springboot连接数据库

4、SpringBoot连接数据库引入druid

5、SpringBoot连接数据库引入mybatis

6、SpringBoot-mybatis分页实现pagehelper

7、SpringBoot-mybatis-plus引入

8、SpringBoot 事务

9、SpringBoot-mybatis-druid多源数据多源数据

10、SpringBoot-mybatis-plus-druid多源数据

11、SpringBoot-mybatis-plus-druid多源数据事务

12、SpringBoot-mybatis-plus-ehcache

未完待续

上一篇博客中因为多源项目的事务没有解决,本篇博客介绍一种可以在多源项目中让事务生效的方法,mybatis-plus配置多源数据还要使的事务生效,需要引入新的依赖atomikos

1数据库中创建表

zy数据库:

  1. CREATE TABLE TEST_BLOCK_T
  2. (
  3. BLOCK_ID VARCHAR2(10 BYTE) PRIMARY KEY, --编码
  4. BLOCK_NAME VARCHAR2(200 BYTE) --资源名称
  5. );
  6. Insert into TEST_BLOCK_T (BLOCK_ID, BLOCK_NAME) Values ('1', 'java');
  7. COMMIT;

yc数据库:

  1. CREATE TABLE TEST_USER_T
  2. (
  3. USER_ID VARCHAR2(10 BYTE) PRIMARY KEY,
  4. NAME VARCHAR2(200 BYTE)
  5. );
  6. Insert into TEST_USER_T (USER_ID, NAME) Values ('1', '张三');
  7. COMMIT;

2、pom.xml

  1. <properties>
  2. <java.version>1.8</java.version>
  3. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  4. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  5. <spring-boot.version>2.1.17.RELEASE</spring-boot.version>
  6. </properties>
  7.  
  8. <dependencies>
  9. <dependency>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-web</artifactId>
  12. </dependency>
  13.  
  14. <dependency>
  15. <groupId>org.springframework.boot</groupId>
  16. <artifactId>spring-boot-starter-test</artifactId>
  17. <scope>test</scope>
  18. </dependency>
  19.  
  20. <!--阿里数据库连接池 -->
  21. <dependency>
  22. <groupId>com.alibaba</groupId>
  23. <artifactId>druid-spring-boot-starter</artifactId>
  24. <version>1.1.20</version>
  25. </dependency>
  26.  
  27. <!--mybatis-plus-->
  28. <dependency>
  29. <groupId>com.baomidou</groupId>
  30. <artifactId>mybatis-plus-boot-starter</artifactId>
  31. <version>3.3.1</version>
  32. </dependency>
  33.  
  34. <!--分布式事务-->
  35. <dependency>
  36. <groupId>org.springframework.boot</groupId>
  37. <artifactId>spring-boot-starter-jta-atomikos</artifactId>
  38. </dependency>
  39.  
  40. <!-- oracle驱动 -->
  41. <dependency>
  42. <groupId>com.oracle</groupId>
  43. <artifactId>ojdbc6</artifactId>
  44. <version>11.2.0.3</version>
  45. </dependency>
  46.  
  47. <!-- 省略get/set等方法 日志打印 -->
  48. <dependency>
  49. <groupId>org.projectlombok</groupId>
  50. <artifactId>lombok</artifactId>
  51. <optional>true</optional>
  52. </dependency>
  53.  
  54. </dependencies>

3、      application.properties配置

  1. # 应用名称
  2. spring.application.name=demo
  3. # 应用服务 WEB 访问端口
  4. server.port=8080
  5.  
  6. spring.datasource.type=com.alibaba.druid.pool.xa.DruidXADataSource
  7.  
  8. spring.datasource.druid.one.name=oneDataSource
  9. spring.datasource.druid.one.url=jdbc:oracle:thin:@192.168.0.100:1521:orcl
  10. spring.datasource.druid.one.driver-class-name=oracle.jdbc.OracleDriver
  11. spring.datasource.druid.one.username=zy
  12. spring.datasource.druid.one.password=1
  13. spring.datasource.druid.one.initialSize=5
  14. spring.datasource.druid.one.minIdle=5
  15. spring.datasource.druid.one.maxActive=20
  16. spring.datasource.druid.one.maxWait=60000
  17. spring.datasource.druid.one.timeBetweenEvictionRunsMillis=60000
  18. spring.datasource.druid.one.minEvictableIdleTimeMillis=300000
  19. spring.datasource.druid.one.validationQuery= SELECT 1 from dual
  20. spring.datasource.druid.one.validationQueryTimeout=10000
  21. spring.datasource.druid.one.testWhileIdle=true
  22. spring.datasource.druid.one.testOnBorrow=false
  23. spring.datasource.druid.one.testOnReturn=false
  24. spring.datasource.druid.one.poolPreparedStatements=true
  25. spring.datasource.druid.one.maxPoolPreparedStatementPerConnectionSize=20
  26. spring.datasource.druid.one.filters=stat,wall
  27. spring.datasource.druid.one.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
  28. spring.datasource.druid.one.useGlobalDataSourceStat=true
  29.  
  30. spring.datasource.druid.two.name=twoDataSource
  31. spring.datasource.druid.two.url=jdbc:oracle:thin:@192.168.0.100:1521:orcl
  32. spring.datasource.druid.two.driver-class-name=oracle.jdbc.OracleDriver
  33. spring.datasource.druid.two.username=yc
  34. spring.datasource.druid.two.password=1
  35. spring.datasource.druid.two.initialSize=5
  36. spring.datasource.druid.two.minIdle=5
  37. spring.datasource.druid.two.maxActive=20
  38. spring.datasource.druid.two.maxWait=60000
  39. spring.datasource.druid.two.timeBetweenEvictionRunsMillis=60000
  40. spring.datasource.druid.two.minEvictableIdleTimeMillis=300000
  41. spring.datasource.druid.two.validationQuery=SELECT 1 from dual
  42. spring.datasource.druid.two.validationQueryTimeout=10000
  43. spring.datasource.druid.two.testWhileIdle=true
  44. spring.datasource.druid.two.testOnBorrow=false
  45. spring.datasource.druid.two.testOnReturn=false
  46. spring.datasource.druid.two.poolPreparedStatements=true
  47. spring.datasource.druid.two.maxPoolPreparedStatementPerConnectionSize=20
  48. spring.datasource.druid.two.filters=stat,wall
  49. spring.datasource.druid.two.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
  50. spring.datasource.druid.two.useGlobalDataSourceStat=true
  51.  
  52. spring.jta.atomikos.properties.log-base-dir=tx-logs
  53. spring.jta.transaction-manager-id=txManager

4、文件目录

5、源码

  1. package com.example.demo;
  2.  
  3. import org.springframework.boot.SpringApplication;
  4. import org.springframework.boot.autoconfigure.SpringBootApplication;
  5.  
  6. @SpringBootApplication
  7. public class DemoApplication {
  8.  
  9. private org.springframework.dao.support.DaoSupport dao ;
  10.  
  11. public static void main(String[] args) {
  12. SpringApplication.run(DemoApplication.class, args);
  13. }
  14.  
  15. }
  1. package com.example.demo.config;
  2.  
  3. import com.alibaba.druid.filter.stat.StatFilter;
  4. import com.alibaba.druid.support.http.StatViewServlet;
  5. import com.alibaba.druid.support.http.WebStatFilter;
  6. import com.alibaba.druid.wall.WallConfig;
  7. import com.alibaba.druid.wall.WallFilter;
  8. import org.springframework.beans.factory.annotation.Autowired;
  9. import org.springframework.boot.jta.atomikos.AtomikosDataSourceBean;
  10. import org.springframework.boot.web.servlet.FilterRegistrationBean;
  11. import org.springframework.boot.web.servlet.ServletRegistrationBean;
  12. import org.springframework.context.annotation.Bean;
  13. import org.springframework.context.annotation.Configuration;
  14. import org.springframework.context.annotation.Primary;
  15. import org.springframework.core.env.Environment;
  16.  
  17. import java.util.Properties;
  18.  
  19. /**
  20. * 多数据源和Druid配置
  21. *
  22. * @author leilei
  23. */
  24. @Configuration
  25. public class DruidConfig {
  26.  
  27. /**
  28. * 数据源1配置 使用AtomikosDataSourceBean 支持多数据源事务
  29. *
  30. * @param env
  31. * @return Primary 指定主库 (必须指定一个主库 否则会报错)
  32. */
  33. @Bean(name = "MybatisPlusOneDataSource")
  34. @Primary
  35. @Autowired
  36. public AtomikosDataSourceBean oneDataSource(Environment env) {
  37. AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
  38. Properties prop = build(env, "spring.datasource.druid.one.");
  39. ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
  40. ds.setUniqueResourceName("oneDataSource");
  41. ds.setPoolSize(5);
  42. ds.setXaProperties(prop);
  43. return ds;
  44. }
  45.  
  46. /**
  47. * 数据源2配置 使用AtomikosDataSourceBean 支持多数据源事务
  48. *
  49. * @param env
  50. * @return
  51. */
  52. @Autowired
  53. @Bean(name = "MybatisPlusTwoDataSource")
  54. public AtomikosDataSourceBean twoDataSource(Environment env) {
  55. AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
  56. Properties prop = build(env, "spring.datasource.druid.two.");
  57. ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
  58. ds.setUniqueResourceName("twoDataSource");
  59. ds.setPoolSize(5);
  60. ds.setXaProperties(prop);
  61. return ds;
  62. }
  63.  
  64. // @Autowired
  65. // @Bean(name = "MybatisPlusThreeDataSource")
  66. // public AtomikosDataSourceBean threeDataSource(Environment env) {
  67. // AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
  68. // Properties prop = build(env, "spring.datasource.druid.three.");
  69. // ds.setXaDataSourceClassName("com.alibaba.druid.pool.xa.DruidXADataSource");
  70. // ds.setUniqueResourceName("threeDataSource");
  71. // ds.setPoolSize(5);
  72. // ds.setXaProperties(prop);
  73. // return ds;
  74. // }
  75.  
  76. // /**
  77. // * 注入事物管理器
  78. // * @return
  79. // */
  80. // @Bean(name = "leijta")
  81. // public JtaTransactionManager regTransactionManager () {
  82. // UserTransactionManager userTransactionManager = new UserTransactionManager();
  83. // UserTransaction userTransaction = new UserTransactionImp();
  84. // return new JtaTransactionManager(userTransaction, userTransactionManager);
  85. // }
  86.  
  87. /**
  88. * 从配置文件中加载数据源信息
  89. *
  90. * @param env
  91. * @param prefix
  92. * @return
  93. */
  94. private Properties build(Environment env, String prefix) {
  95. Properties prop = new Properties();
  96. prop.put("url", env.getProperty(prefix + "url"));
  97. prop.put("username", env.getProperty(prefix + "username"));
  98. prop.put("password", env.getProperty(prefix + "password"));
  99. prop.put("driverClassName", env.getProperty(prefix + "driverClassName", ""));
  100. prop.put("initialSize", env.getProperty(prefix + "initialSize", Integer.class));
  101. prop.put("maxActive", env.getProperty(prefix + "maxActive", Integer.class));
  102. prop.put("minIdle", env.getProperty(prefix + "minIdle", Integer.class));
  103. prop.put("maxWait", env.getProperty(prefix + "maxWait", Integer.class));
  104. prop.put("poolPreparedStatements", env.getProperty(prefix + "poolPreparedStatements", Boolean.class));
  105. prop.put("maxPoolPreparedStatementPerConnectionSize",
  106. env.getProperty(prefix + "maxPoolPreparedStatementPerConnectionSize", Integer.class));
  107. prop.put("maxPoolPreparedStatementPerConnectionSize",
  108. env.getProperty(prefix + "maxPoolPreparedStatementPerConnectionSize", Integer.class));
  109. prop.put("validationQuery", env.getProperty(prefix + "validationQuery"));
  110. prop.put("validationQueryTimeout", env.getProperty(prefix + "validationQueryTimeout", Integer.class));
  111. prop.put("testOnBorrow", env.getProperty(prefix + "testOnBorrow", Boolean.class));
  112. prop.put("testOnReturn", env.getProperty(prefix + "testOnReturn", Boolean.class));
  113. prop.put("testWhileIdle", env.getProperty(prefix + "testWhileIdle", Boolean.class));
  114. prop.put("timeBetweenEvictionRunsMillis",
  115. env.getProperty(prefix + "timeBetweenEvictionRunsMillis", Integer.class));
  116. prop.put("minEvictableIdleTimeMillis", env.getProperty(prefix + "minEvictableIdleTimeMillis", Integer.class));
  117. prop.put("filters", env.getProperty(prefix + "filters"));
  118. return prop;
  119. }
  120.  
  121. /**
  122. * druid访问配置
  123. *
  124. * @return
  125. */
  126. @Bean
  127. public ServletRegistrationBean druidServlet() {
  128. ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
  129. //控制台管理用户,加入下面2行 进入druid后台就需要登录
  130. servletRegistrationBean.addInitParameter("loginUsername", "leilei");
  131. servletRegistrationBean.addInitParameter("loginPassword", "123456");
  132. return servletRegistrationBean;
  133. }
  134.  
  135. @Bean
  136. public FilterRegistrationBean filterRegistrationBean() {
  137. FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
  138. filterRegistrationBean.setFilter(new WebStatFilter());
  139. filterRegistrationBean.addUrlPatterns("/*");
  140. filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
  141. filterRegistrationBean.addInitParameter("profileEnable", "true");
  142. return filterRegistrationBean;
  143. }
  144.  
  145. @Bean
  146. public StatFilter statFilter() {
  147. StatFilter statFilter = new StatFilter();
  148. //slowSqlMillis用来配置SQL慢的标准,执行时间超过slowSqlMillis的就是慢。
  149. statFilter.setLogSlowSql(true);
  150. //SQL合并配置
  151. statFilter.setMergeSql(true);
  152. //slowSqlMillis的缺省值为3000,也就是3秒。
  153. statFilter.setSlowSqlMillis(1000);
  154. return statFilter;
  155. }
  156.  
  157. @Bean
  158. public WallFilter wallFilter() {
  159. WallFilter wallFilter = new WallFilter();
  160. //允许执行多条SQL
  161. WallConfig config = new WallConfig();
  162. config.setMultiStatementAllow(true);
  163. wallFilter.setConfig(config);
  164. return wallFilter;
  165. }
  166. }
  1. package com.example.demo.config;
  2.  
  3. import org.springframework.web.bind.annotation.ExceptionHandler;
  4. import org.springframework.web.bind.annotation.RestControllerAdvice;
  5.  
  6. import javax.servlet.http.HttpServletRequest;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9.  
  10. /**
  11. * @author : leilei
  12. * @date : 14:20 2020/3/5
  13. * @desc : 自定义异常响应
  14. */
  15. @RestControllerAdvice
  16. public class ExceptionHadler {
  17.  
  18. @ExceptionHandler(value = Exception.class)
  19. public Map<String, Object> exceptionHandler(HttpServletRequest req, Exception e) {
  20. HashMap<String, Object> map = new HashMap<>(4);
  21. map.put("请求状态", "False");
  22. map.put("请求路径", req.getRequestURI());
  23. map.put("请求方式", req.getMethod());
  24. map.put("错误信息", e.getMessage());
  25. return map;
  26. }
  27. }

配置数据源1

  1. package com.example.demo.config;
  2.  
  3. import com.baomidou.mybatisplus.core.MybatisConfiguration;
  4. import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
  5. import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
  6. import org.apache.ibatis.logging.stdout.StdOutImpl;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.mybatis.spring.SqlSessionTemplate;
  9. import org.mybatis.spring.annotation.MapperScan;
  10. import org.springframework.beans.factory.annotation.Qualifier;
  11. import org.springframework.context.annotation.Bean;
  12. import org.springframework.context.annotation.Configuration;
  13. import org.springframework.context.annotation.Primary;
  14. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  15.  
  16. import javax.sql.DataSource;
  17.  
  18. /**
  19. * @author leilei
  20. */
  21. @Configuration
  22. @MapperScan(basePackages = "com.example.demo.mapper.one", sqlSessionFactoryRef = "oneSqlSessionFactory")
  23. public class OneDataSourceConfig {
  24.  
  25. @Primary
  26. @Bean(name = "oneSqlSessionFactory")
  27. public SqlSessionFactory sqlSessionFactory(@Qualifier("MybatisPlusOneDataSource") DataSource dataSource) throws Exception {
  28. //配置myabtisSqlSession
  29. MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
  30. // 指明mapper.xml位置(配置文件中指明的xml位置会失效用此方式代替,具体原因未知)
  31. //sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/leilei/mapper/one/*/*Mapper.xml"));
  32. // 指明实体扫描(多个package用逗号或者分号分隔)
  33. sessionFactoryBean.setTypeAliasesPackage("com.example.demo.entity.one");
  34.  
  35. MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
  36. // mybatisConfiguration.setJdbcTypeForNull(JdbcType.NULL);
  37. //驼峰
  38. mybatisConfiguration.setMapUnderscoreToCamelCase(true);
  39. //是否开启缓存
  40. mybatisConfiguration.setCacheEnabled(false);
  41. //多数据源下分页模式
  42. mybatisConfiguration.addInterceptor(new PaginationInterceptor());
  43. // 配置打印sql语句
  44. mybatisConfiguration.setLogImpl(StdOutImpl.class);
  45. sessionFactoryBean.setConfiguration(mybatisConfiguration);
  46. //数据源注入
  47. sessionFactoryBean.setDataSource(dataSource);
  48. return sessionFactoryBean.getObject();
  49. }
  50.  
  51. @Primary
  52. @Bean(name = "oneSqlSessionTemplate")
  53. public SqlSessionTemplate sqlSessionTemplate(@Qualifier("oneSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
  54. return new SqlSessionTemplate(sqlSessionFactory);
  55. }
  56. }

配置数据源2  需要几个就配置几个

  1. package com.example.demo.config;
  2.  
  3. import com.baomidou.mybatisplus.core.MybatisConfiguration;
  4. import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
  5. import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
  6. import org.apache.ibatis.logging.stdout.StdOutImpl;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.mybatis.spring.SqlSessionTemplate;
  9. import org.mybatis.spring.annotation.MapperScan;
  10. import org.springframework.beans.factory.annotation.Qualifier;
  11. import org.springframework.context.annotation.Bean;
  12. import org.springframework.context.annotation.Configuration;
  13. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  14.  
  15. import javax.sql.DataSource;
  16.  
  17. /**
  18. * @author leilei
  19. */
  20. @Configuration
  21. @MapperScan(basePackages = "com.example.demo.mapper.two", sqlSessionFactoryRef = "twoSqlSessionFactory")
  22. public class TwoDataSourceConfig {
  23.  
  24. @Bean(name = "twoSqlSessionFactory")
  25. public SqlSessionFactory sqlSessionFactory(@Qualifier("MybatisPlusTwoDataSource") DataSource dataSource) throws Exception {
  26. //配置myabtisSqlSession
  27. MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
  28. // 指明mapper.xml位置(配置文件中指明的xml位置会失效用此方式代替,具体原因未知)
  29. //sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:com/leilei/mapper/two/*/*Mapper.xml"));
  30. // 指明实体扫描(多个package用逗号或者分号分隔)
  31. sessionFactoryBean.setTypeAliasesPackage("com.example.demo.entity.two");
  32.  
  33. MybatisConfiguration mybatisConfiguration = new MybatisConfiguration();
  34. //mybatisConfiguration.setJdbcTypeForNull(JdbcType.NULL);
  35. //驼峰
  36. mybatisConfiguration.setMapUnderscoreToCamelCase(true);
  37. //是否开启缓存
  38. mybatisConfiguration.setCacheEnabled(false);
  39. //多数据源下分页模式
  40. mybatisConfiguration.addInterceptor(new PaginationInterceptor());
  41. // 配置打印sql语句
  42. mybatisConfiguration.setLogImpl(StdOutImpl.class);
  43. sessionFactoryBean.setConfiguration(mybatisConfiguration);
  44. //数据源注入
  45. sessionFactoryBean.setDataSource(dataSource);
  46. return sessionFactoryBean.getObject();
  47. }
  48.  
  49. @Bean(name = "twoSqlSessionTemplate")
  50. public SqlSessionTemplate sqlSessionTemplate(@Qualifier("twoSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
  51. return new SqlSessionTemplate(sqlSessionFactory);
  52. }
  53. }
  1. package com.example.demo.controller;
  2.  
  3. import com.example.demo.service.ManySourceService;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.web.bind.annotation.*;
  6.  
  7. @RestController
  8. @RequestMapping("/hello")
  9. public class ManySourceController {
  10.  
  11. @Autowired
  12. ManySourceService manySourceService;
  13.  
  14. @GetMapping("/getZyBlock")
  15. @ResponseBody
  16. public String test1() {
  17. return manySourceService.getZyBlock();
  18.  
  19. }
  20.  
  21. @GetMapping("/getYcUser")
  22. @ResponseBody
  23. public String test2() {
  24. return manySourceService.getYcUser();
  25.  
  26. }
  27.  
  28. @PostMapping("/insertZyBlock")
  29. @ResponseBody
  30. public String test3() {
  31. return manySourceService.insertZyBlock();
  32.  
  33. }
  34.  
  35. @PostMapping("/insertYcUser")
  36. @ResponseBody
  37. public String test4() {
  38. return manySourceService.insertYcUser();
  39.  
  40. }
  41.  
  42. @PostMapping("/insertMany")
  43. @ResponseBody
  44. public String test5() {
  45. return manySourceService.insertMany();
  46.  
  47. }
  48.  
  49. }
  1. package com.example.demo.service;
  2.  
  3. import com.example.demo.entity.one.Block;
  4. import com.example.demo.entity.two.User;
  5. import com.example.demo.mapper.one.BlockMapper;
  6. import com.example.demo.mapper.two.UserMapper;
  7. import org.springframework.beans.factory.annotation.Autowired;
  8. import org.springframework.stereotype.Service;
  9. import org.springframework.transaction.annotation.Transactional;
  10.  
  11. @Service
  12. public class ManySourceService {
  13.  
  14. //SpringBoot在使用事物Transactional的时候,要在main方法上加上 @EnableTransactionManagement
  15. // 注解开发事物声明,在使用的service层的公共方法加上 @Transactional (spring)注解。
  16.  
  17. @Autowired
  18. BlockMapper blockMapper;
  19.  
  20. @Autowired
  21. UserMapper userMapper;
  22.  
  23. //获取zy库中的block中的数据
  24. public String getZyBlock() {
  25. return blockMapper.selectById("1").toString();
  26.  
  27. }
  28.  
  29. //获取yc库中的user中的数据
  30. public String getYcUser() {
  31. return userMapper.selectById("2").toString() ;
  32. }
  33.  
  34. public String insertZyBlock() {
  35. Block block = new Block();
  36. block.setBlockId("99999");
  37. block.setBlockName("PHP");
  38. return blockMapper.insert(block)+"";
  39. }
  40.  
  41. public String insertYcUser() {
  42. User user = new User();
  43. user.setUserId("2");
  44. user.setName("李四");
  45. return userMapper.insert(user)+"";
  46. }
  47.  
  48. @Transactional
  49. public String insertMany() {
  50. Block block = new Block();
  51. block.setBlockId("99999");
  52. block.setBlockName("PHP");
  53. blockMapper.insert(block) ;
  54. int a = 100/0;
  55.  
  56. User user = new User();
  57. user.setUserId("2");
  58. user.setName("李四");
  59. userMapper.insert(user) ;
  60. return "1";
  61. }
  62.  
  63. }
  1. package com.example.demo.entity.one;
  2.  
  3. import com.baomidou.mybatisplus.annotation.TableId;
  4. import com.baomidou.mybatisplus.annotation.TableName;
  5.  
  6. /**
  7. * <p>
  8. * 。
  9. * </p>
  10. *
  11. * @author yc
  12. * @since 2021-09-18
  13. */
  14. @TableName(value = "TEST_BLOCK_T")
  15. public class Block {
  16. private static final long serialVersionUID = 1L;
  17.  
  18. @TableId
  19. private String blockId;
  20. /**
  21. * $field.comment。
  22. */
  23. private String blockName;
  24.  
  25. public String getBlockId() {
  26. return blockId;
  27. }
  28.  
  29. public void setBlockId(String blockId) {
  30. this.blockId = blockId;
  31. }
  32.  
  33. public String getBlockName() {
  34. return blockName;
  35. }
  36.  
  37. public void setBlockName(String blockName) {
  38. this.blockName = blockName;
  39. }
  40.  
  41. @Override
  42. public String toString() {
  43. return "XyDicBlockT{" +
  44. "blockId='" + blockId + '\'' +
  45. ", blockName='" + blockName + '\'' +
  46. '}';
  47. }
  48. }
  1. package com.example.demo.entity.two;
  2.  
  3. import com.baomidou.mybatisplus.annotation.TableId;
  4. import com.baomidou.mybatisplus.annotation.TableName;
  5.  
  6. /**
  7. * <p>
  8. * 。
  9. * </p>
  10. *
  11. * @author yc
  12. * @since 2021-09-18
  13. */
  14.  
  15. @TableName(value = "TEST_USER_T")
  16. public class User {
  17. private static final long serialVersionUID = 1L;
  18.  
  19. @TableId
  20. private String userId;
  21. /**
  22. * $field.comment。
  23. */
  24. private String name;
  25.  
  26. public String getUserId() {
  27. return userId;
  28. }
  29.  
  30. public void setUserId(String userId) {
  31. this.userId = userId;
  32. }
  33.  
  34. public String getName() {
  35. return name;
  36. }
  37.  
  38. public void setName(String name) {
  39. this.name = name;
  40. }
  41.  
  42. @Override
  43. public String toString() {
  44. return "User{" +
  45. "userId='" + userId + '\'' +
  46. ", name='" + name + '\'' +
  47. '}';
  48. }
  49. }
  1. package com.example.demo.entity.two;
  2.  
  3. import com.baomidou.mybatisplus.annotation.TableId;
  4. import com.baomidou.mybatisplus.annotation.TableName;
  5.  
  6. /**
  7. * <p>
  8. * 。
  9. * </p>
  10. *
  11. * @author yc
  12. * @since 2021-09-18
  13. */
  14.  
  15. @TableName(value = "TEST_USER_T")
  16. public class User {
  17. private static final long serialVersionUID = 1L;
  18.  
  19. @TableId
  20. private String userId;
  21. /**
  22. * $field.comment。
  23. */
  24. private String name;
  25.  
  26. public String getUserId() {
  27. return userId;
  28. }
  29.  
  30. public void setUserId(String userId) {
  31. this.userId = userId;
  32. }
  33.  
  34. public String getName() {
  35. return name;
  36. }
  37.  
  38. public void setName(String name) {
  39. this.name = name;
  40. }
  41.  
  42. @Override
  43. public String toString() {
  44. return "User{" +
  45. "userId='" + userId + '\'' +
  46. ", name='" + name + '\'' +
  47. '}';
  48. }
  49. }
  1. package com.example.demo.mapper.two;
  2.  
  3. import com.baomidou.mybatisplus.core.mapper.BaseMapper;
  4. import com.example.demo.entity.two.User;
  5.  
  6. public interface UserMapper extends BaseMapper<User> {
  7.  
  8. }

6、启动项目访问项目

清空yc库里的表TEST_USER_T 和 zy库里的表TEST_BLOCK_T

(1)访问http://localhost:8080/hello/insertZyBlock 成功插入数据到TEST_BLOCK_T

(2)访问http://localhost:8080/hello/insertYcUser成功插入数据到TEST_USER_T

说明分别向不同数据源的数据库的插入没有问题。

(3)访问http://localhost:8080/hello/getZyBlock

(4)访问http://localhost:8080/hello/getYcUser

说明分别从不同数据源的数据库的查询没有问题。

再次清空yc库里的表TEST_USER_T 和 zy库里的表TEST_BLOCK_T

重头戏来了

(5)访问http://localhost:8080/hello/insertMany

这里添加了事务,并且在插入TEST_BLOCK_T后制造了一个除数为0的错误,如果事务生效,前面插入的数据就应该回滚。

下面可以看到前台返回的消息报错了说了除数为0的错误。

后台开始也插入了数据,但是会发现数据库里并没有插入数据,说清事务生效了。

11、SpringBoot-mybatis-plus-druid多源数据事务的更多相关文章

  1. spring boot 学习(五)SpringBoot+MyBatis(XML)+Druid

    SpringBoot+MyBatis(xml)+Druid 前言 springboot集成了springJDBC与JPA,但是没有集成mybatis,所以想要使用mybatis就要自己去集成. 主要是 ...

  2. 12.SpringBoot+MyBatis(XML)+Druid

    转自:https://www.cnblogs.com/MaxElephant/p/8108342.html 主要是在Spring Boot中集成MyBatis,可以选用基于注解的方式,也可以选择xml ...

  3. 搭建Springboot+mybatis+redis+druid

    2019独角兽企业重金招聘Python工程师标准>>> 准备工作 JDK:1.8 使用技术:SpringBoot.Dubbo.Mybatis.Druid 开发工具:Intelj ID ...

  4. shardingsphere多数据源(springboot + mybatis+shardingsphere+druid)

    org.springframeword.boot:spring-boot-starer-web: 2.0.4release io.shardingsphere:sharding-jdbc-spring ...

  5. 3分钟搞定SpringBoot+Mybatis+druid多数据源和分布式事务

    文章来自: https://blog.csdn.net/qq_29242877/article/details/79033287 在一些复杂的应用开发中,一个应用可能会涉及到连接多个数据源,所谓多数据 ...

  6. SpringBoot+Mybatis+ Druid+PageHelper 实现多数据源并分页

    前言 本篇文章主要讲述的是SpringBoot整合Mybatis.Druid和PageHelper 并实现多数据源和分页.其中SpringBoot整合Mybatis这块,在之前的的一篇文章中已经讲述了 ...

  7. springboot+mybatis+druid+atomikos框架搭建及测试

    前言 因为最近公司项目升级,需要将外网数据库的信息导入到内网数据库内.于是找了一些springboot多数据源的文章来看,同时也亲自动手实践.可是过程中也踩了不少的坑,主要原因是我看的文章大部分都是s ...

  8. springboot+mybatis+druid+sqlite/mysql/oracle

    搭建springboot+mybatis+druid+sqlite/mysql/oracle附带测试 1.版本 springboot2.1.6 jdk1.8 2.最简springboot环境 http ...

  9. 记录一下自己搭建springboot+mybatis+druid 多数据源的过程

    前言  上次的一个项目(springboot+mybatis+vue),做到后面的时间发现需要用到多数据源.当时没有思路..后来直接用了jdbc来实现.这几天不是很忙,所以决定自己再搭建一次.不多说, ...

  10. 【springboot spring mybatis】看我怎么将springboot与spring整合mybatis与druid数据源

    目录 概述 1.mybatis 2.druid 壹:spring整合 2.jdbc.properties 3.mybatis-config.xml 二:java代码 1.mapper 2.servic ...

随机推荐

  1. jmeter完成文件上传接口

    前提:测试项目中有一个上传本地文件(excel)测被测接口. 测试工具:jmeter 协议:http 测试项目如下图: 第一步:点击模板上传,选择本地excel文件 第二步:上传成功,系统识别exce ...

  2. SpringBoot接口开发

    依赖的jar包<dependency> <groupId>org.springframework.boot</groupId> <artifactId> ...

  3. i-MES生产制造管理系统-SMT物料防错与追溯

    说起 SMT,相信大家或多或少都有一些了解,主要是用来贴片的,简单点说就是给空白的 PCB 板贴上一些元器件,比如二极管.IC.电阻等等各种电子元器件,以前客户对这些元器件物料的追溯管控的并不严格,只 ...

  4. TypeError: 'module' object is not callable (pytorch在进行MNIST数据集预览时出现的错误)

    在使用pytorch在对MNIST数据集进行预览时,出现了TypeError: 'module' object is not callable的错误: 上报错信息图如下: 从图中可以看出,报错位置为第 ...

  5. MybatisPlus高级特性之SimpleQuery工具类

    1.是很么? SimpleQuery可以对selectList查询后的结果使用Stream流进行操作,使其可以返回指定的结果,简洁了api的调用 2.怎么玩? 案例演示 (1) list操作 /** ...

  6. 一文读懂遗传算法(附python)

    几天前,我着手解决一个实际问题--大型超市销售问题.在使用了几个简单模型做了一些特征工程之后,我在排行榜上名列第 219 名. 虽然结果不错,但是我还是想做得更好.于是,我开始研究可以提高分数的优化方 ...

  7. Docker的安装、镜像加速配置

    wget https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo -O /etc/yum.repos.d/docker-ce. ...

  8. 华企盾DSC邮件服务器测试连接提示Bad login or password(账号密码错误)

    解决方法:出现该提示说明账号和密码有一个填错了,注意:这里的密码不是邮箱本身的密码,是授权码,具体可以在邮箱设置中查看,而且必须开启smtp服务才能正常使用.

  9. 数字孪生为何通过融合GIS系统能够更好地助力智慧城市发展?

    随着城市化进程的不断加速,智慧城市建设已成为许多城市发展的重要方向.在智慧城市中,数字孪生技术和GIS系统的融合,为城市发展带来了全新的可能性和机遇.数字孪生是一种将物理世界和数字世界相结合的技术,通 ...

  10. 文心一言 VS 讯飞星火 VS chatgpt (172)-- 算法导论13.3 1题

    一.用go语言,在 RB-INSERT 的第 16 行,将新插人的结点 z 着为红色.注意到,如果将 z 着为黑色,则红黑树的性质4就不会被破坏.那么为什么不选择将 z 着为黑色呢? 文心一言: 在红 ...