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可以不写!

2mapperscan扫描为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-typeapplication/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

posted on 2019-05-12 15:18  cslj2013  阅读(397)  评论(0编辑  收藏  举报

导航