zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    一起谈.NET技术,ASP.NET MVC3 Service Location 狼人:
    一起谈.NET技术,大型高性能ASP.NET系统架构设计 狼人:
    一起谈.NET技术,.NET 4 并行(多核)编程系列之二 从Task开始 狼人:
    一起谈.NET技术,Silverlight 游戏开发小技巧:动感小菜单 狼人:
    一起谈.NET技术,打包Asp.Net 网站成为一个exe方便快捷的进行客户演示 狼人:
    一起谈.NET技术,ASP.NET Eval如何进行数据绑定 狼人:
    一起谈.NET技术,ASP.NET MVC开发人员必备的五大工具 狼人:
    一起谈.NET技术,写出优雅简明代码的论题集 Csharp(C#)篇[2] 狼人:
    mysql数据库解除外键
    JSF页面组件化
  • 原文地址:https://www.cnblogs.com/cslj2013/p/10852379.html
Copyright © 2011-2022 走看看