springboot学习入门简易版九---springboot2.0整合多数据源mybatis mysql8+(22)
一个项目中配置多个数据源(链接不同库jdbc),无限大,具体多少根据内存大小
项目中多数据源如何划分:分包名(业务)或注解方式。分包名方式类似多个不同的jar,同业务需求放一个包中。
分包方式配置多数据源
项目目录结构
2.14.1 pom文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.9.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<!-- mysql 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<!-- 提示建议引入 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
2.14.2 创建test1包名下类
public class Employee implements Serializable{ private static final long serialVersionUID = 1L; private Integer id; private String lastName;
public interface EmployeeDao { // @Insert("insert into myemployeee(last_name) values (#{lastName})") int insert(Employee emp); }
EmployeeMapping.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.springboot2.test1.dao.EmployeeDao"> <insert id="insert" parameterType="com.springboot2.test1.bean.Employee"> insert into myemployeee(last_name) values (#{lastName,jdbcType=VARCHAR}) </insert> </mapper>
service类
@Service public class EmployeeService { @Autowired EmployeeDao employeeDao; public Integer insert(Employee emp) { return employeeDao.insert(emp); } }
2.14.3 创建test2包名下类
public class User implements Serializable{ private static final long serialVersionUID = 1L; private Integer id; private String name; private Integer age;
public interface UserDao { // @Insert("insert into myuser(name,age) values (#{name},#{age})") int insert(User user); }
UserMapping.xml文件
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.springboot2.test2.dao.UserDao"> <insert id="insert" parameterType="com.springboot2.test2.bean.User"> insert into myuser(name,age) values (#{name,jdbcType=VARCHAR},#{age,jdbcType=INTEGER}) </insert> </mapper>
@Service public class UserService { @Autowired UserDao userDao; public Integer insert(User user2) { return userDao.insert(user2); } }
2.14.4 重点:多数据源配置
2.14.4.1首先application.yml文件
#多数据源配置 spring: datasource: test1: #数据源1(自定义) driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/mytest?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=GMT%2B8&allowMultiQueries=true username: root password: (***) test2: #数据源2(自定义) driver-class-name: com.mysql.cj.jdbc.Driver jdbc-url: jdbc:mysql://localhost:3306/mytest2?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=GMT%2B8&allowMultiQueries=true username: root password: (***)
注意:虽然为高版本,但多数据源配置时,必须为spring.datasource.test.jdbc-url而不是spring.datasource.test.url
2.14.4.2多数据源配置类
/** * 数据源配置 * @author admin * */ @Configuration @MapperScan(basePackages= "com.springboot2.test1.dao",sqlSessionFactoryRef="test1SqlSessionFactory") //注意:com.springboot2.test1.dao是dao类的包名!! public class DatasourceConfig1 { /** * 配置test1数据库 * @return */ @Bean(name="test1DataSource") @ConfigurationProperties(prefix="spring.datasource.test1") @Primary public DataSource test1DataSource() { return DataSourceBuilder.create().build(); } /** * 创建sqlsessinfactory会话工厂 * @param dataSource * @return * @throws Exception */ @Bean(name="test1SqlSessionFactory") @Primary public SqlSessionFactory test1SqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); //加载mapping文件 sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath:com/springboot2/test1/mapping/*.xml")); return sqlSessionFactoryBean.getObject(); } /** * 事务管理 */ @Bean(name="test1TransactionManager") @Primary public DataSourceTransactionManager test1TransactionManager(@Qualifier("test1DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } /** * 创建SqlSessionTemplate * @param sqlSessionFactory * @return */ @Bean(name="test1SqlSessionTemplate") @Primary public SqlSessionTemplate test1SqlSessionTemplate(@Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory){ return new SqlSessionTemplate(sqlSessionFactory); } }
/** * 数据源配置 * @author admin * */ @Configuration @MapperScan(basePackages= {"com.springboot2.test2.dao"},sqlSessionFactoryRef="test2SqlSessionFactory") public class DatasourceConfig2 { /** * 配置test2数据库 * @return */ @Bean(name="test2DataSource") @ConfigurationProperties(prefix="spring.datasource.test2") public DataSource test2DataSource() { return DataSourceBuilder.create().build(); } /** * 创建sqlsessinfactory会话工厂 * @param dataSource * @return * @throws Exception */ @Bean(name="test2SqlSessionFactory") public SqlSessionFactory test2SqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean(); sqlSessionFactoryBean.setDataSource(dataSource); //加载mapping文件 sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources("classpath:com/springboot2/test2/mapping/*.xml")); return sqlSessionFactoryBean.getObject(); } /** * 事务管理 */ @Bean(name="test2TransactionManager") public DataSourceTransactionManager test2TransactionManager(@Qualifier("test2DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } /** * 创建SqlSessionTemplate * @param sqlSessionFactory * @return */ @Bean(name="test2SqlSessionTemplate") public SqlSessionTemplate test2SqlSessionTemplate(@Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory){ return new SqlSessionTemplate(sqlSessionFactory); } }
注意:
1)分包方式下@Primary可以不写!
2)mapperscan扫描为dao类对应的包名而不是dao类,否则会导致无法注入,报错缺少component注解。
2.14.5 controller类
@RestController public class MultiDataSourceController { @Autowired EmployeeService employeeService1; @Autowired UserService userService; @RequestMapping("/insertEmployee") public String insert(String lastName){ Employee emp=new Employee(); emp.setLastName(lastName); int i=employeeService1.insert(emp); return i+""; } //接收json格式请求 @RequestMapping("/insertUser") public String insert(@RequestBody User user){ User user2=new User(); user2.setAge(user.getAge()); user2.setName(user.getName()); int i=userService.insert(user2); return i+""; } //接收普通格式多参数请求 @RequestMapping("/insertUser2") public String insertUser2(@RequestParam("name") String name,@RequestParam("age") Integer age){ User user2=new User(); user2.setAge(age); user2.setName(name); int i=userService.insert(user2); return i+""; }
2.14.7 启动类
@SpringBootApplication //@MapperScan("com.springboot2.dao")//多数据源下在数据源配置中配置DatasourceConfig1和DatasourceConfig2 public class StartApplication { public static void main(String[] args) { SpringApplication.run(StartApplication.class, args); } }
2.14.8 测试
1 Get请求:http://localhost:8080/insertEmployee?lastName=test2222
执行成功返回1
2 Post请求(且content-type为application/json类型)
http://localhost:8080/insertUser
请求参数:
{
"name":"test3",
"age":11
}
返回成功1
3 get请求(content-type类型随意)
http://localhost:8080/insertUser2?name=ttdd&age=22
返回成功1
2.15SpringBoot多数据源事务(24)
@Service public class EmployeeService { @Autowired EmployeeDao employeeDao; /** * 添加事务管理 * @param emp * @return * @throws Exception */ @Transactional(transactionManager="test1TransactionManager",rollbackFor=Exception.class) public Integer insert(Employee emp) throws Exception{ /** * 抛出异常事务无效:默认检测unchecked异常才回滚,checked异常也回滚需要设置rollbackFor=Exception.class * https://www.cnblogs.com/syp172654682/p/9811341.html */ int i=this.other(emp); return i; } @Transactional(transactionManager="test1TransactionManager") public Integer other(Employee emp) throws Exception{ int i=employeeDao.insert(emp); try { i=i/0; }catch(Exception e) { Logger.logMsg(Logger.INFO, "异常"); throw new Exception(); } return i; } }
启动类
@SpringBootApplication @EnableTransactionManagement //@MapperScan("com.springboot2.dao")//多数据源下在数据源配置中配置DatasourceConfig1和DatasourceConfig2 public class StartApplication { public static void main(String[] args) { SpringApplication.run(StartApplication.class, args); } }
问题:
1)抛出Exception异常事务无效,原因及解决方法见上面代码
2)其他事务失效问题见:https://www.cnblogs.com/cslj2013/p/10924755.html
github: https://github.com/cslj2013/springboot2.0_multi_datasources.git