zoukankan      html  css  js  c++  java
  • SpringBoot 集成多数据源

    一个项目中怎么划分数据库,可以通过具体业务需求。

    项目中数据源怎么如何划分,通过注解的方式@Datasource(ref="") 在方法上指定,会连接指定的数据源,这种方式比较繁琐。如果有1000个方法,就得写1000个这种注解。所以一般通过分包名的方式。

    通过分包名来划分数据源:

    1,mysql 里面有两个库,testdb,testdb2,里面各有一张user表,数据结构是一样的

    2,建立实体类:user

    @Data //相当于@Setter @Getter
    public class User {
        private int id;
        private String username;
        private String sex;
        private Date birthday;
        private String address;
    }

    2,datasource 包下有DataSource1Config,DataSource2Config,如下:

    package com.baiyue.datasource;
    
    import javax.sql.DataSource;
    
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.jdbc.DataSourceBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.Primary;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    
    // DataSource01
    @Configuration // 注册到springboot容器中
    @MapperScan(basePackages = "com.baiyue.db1", sqlSessionFactoryRef = "db1SqlSessionFactory")
    public class DataSource1Config {
        @Bean(name = "db1DataSource") //@Bean是注入到Spring 容器中
        @ConfigurationProperties(prefix = "spring.datasource.db1")//读取配置文件中以spring.datasource.db1 开头的
        public DataSource testDataSource() {
            return DataSourceBuilder.create().build();
        }
        @Primary
        @Bean(name = "db1SqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("db1DataSource") DataSource dataSource) throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations(
                    new PathMatchingResourcePatternResolver().getResources("classpath:com/baiyue/db1/mapping/*Mapper.xml"));
            return bean.getObject();
        }
    
        /**
         * 事务
         */
        @Bean(name = "db1TransactionManager")
        public DataSourceTransactionManager testTransactionManager(@Qualifier("db1DataSource") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    
        @Bean(name = "db1SqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
                @Qualifier("db1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    
    }

    DataSource2:

    package com.baiyue.datasource;
    
    import javax.sql.DataSource;
    
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.mybatis.spring.SqlSessionTemplate;
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.boot.jdbc.DataSourceBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    
    // DataSource01
    @Configuration // 注册到springboot容器中
    @MapperScan(basePackages = "com.baiyue.db2", sqlSessionFactoryRef = "db2SqlSessionFactory")
    public class DataSource2Config {
        
        @Bean(name = "db2DataSource") //@Bean是注入到Spring 容器中
        @ConfigurationProperties(prefix = "spring.datasource.db2")//读取配置文件中以spring.datasource.db2 开头的
        public DataSource testDataSource() {
            return DataSourceBuilder.create().build();
        }
        
    
        @Bean(name = "db2SqlSessionFactory")
        public SqlSessionFactory testSqlSessionFactory(@Qualifier("db2DataSource") DataSource dataSource) throws Exception {
            SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
            bean.setDataSource(dataSource);
            bean.setMapperLocations(
                    new PathMatchingResourcePatternResolver().getResources("classpath:com/baiyue/db2/mapping/*Mapper.xml"));
            return bean.getObject();
        }
    
        /**
         * 事务
         */
        @Bean(name = "db2TransactionManager")
        public DataSourceTransactionManager testTransactionManager(@Qualifier("db2DataSource") DataSource dataSource) {
            return new DataSourceTransactionManager(dataSource);
        }
    
        @Bean(name = "db2SqlSessionTemplate")
        public SqlSessionTemplate testSqlSessionTemplate(
                @Qualifier("db2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory);
        }
    
    }

    通过 @Configuration // 注册到springboot容器中,在启动类中会去读取所有的Bean,通过两个类以及配置文件,能够获取到不同包下的业务层对应不同的数据源..

    #多数据源
    spring:
      datasource:
        db1:
          driver-class-name: com.mysql.jdbc.Driver
          jdbcUrl: jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=utf-8
          username: root
          password: 123456
    
        db2:
          driver-class-name: com.mysql.jdbc.Driver
          jdbcUrl: jdbc:mysql://localhost:3306/testdb2?useUnicode=true&characterEncoding=utf-8
          username: root
          password: 123456

    3,db1 下的mapper,xml,service,sevice层需要指定业务相应的事务管理,否则会报有两个事务管理的错

    package com.baiyue.db1.mapper;
    
    import com.baiyue.entity.User;
    
    public interface UserMapperdb1 {
    
        void insertUser(User user);
    
        User selectUserById(int id);
    
    }
    <?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.baiyue.db1.mapper.UserMapperdb1">
    
        <!-- 根据 id 查询 user 表中的数据 id:唯一标识符,此文件中的id值不能重复 resultType:返回值类型,一条数据库记录也就对应实体类的一个对象 
            parameterType:参数类型,也就是查询条件的类型 -->
        <select id="selectUserById" resultType="com.baiyue.entity.User" parameterType="int">
            <!-- 这里和普通的sql 查询语句差不多,对于只有一个参数,后面的 #{id}表示占位符,里面不一定要写id,写啥都可以,但是不要空着,如果有多个参数则必须写pojo类里面的属性 -->
            select * from user where id = #{id}
        </select>
    
        <insert id="insertUser" parameterType="com.baiyue.entity.User">
            insert into
            user(id,username,sex,birthday,address)
            value(#{id},#{username},#{sex},#{birthday},#{address})
        </insert>
    
    </mapper>
    package com.baiyue.db1.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.baiyue.db1.mapper.UserMapperdb1;
    import com.baiyue.entity.User;
    
    import lombok.extern.slf4j.Slf4j;
    
    @Service
    @Slf4j
    public class UserServicedb1 {
    
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return super.toString();
    }
        
        @Autowired
        private UserMapperdb1 userMapper;
        
        @Transactional("db1TransactionManager")//指定事务管理
        public void insertUser(User user) {
            userMapper.insertUser(user);
        };
    
        public User selectUserById(int id) {
            User user = userMapper.selectUserById(id);
            return user;
        };
    
    }

    4,同理,db2 的mapper,xml,service

    package com.baiyue.db2.mapper;
    
    import com.baiyue.entity.User;
    
    public interface UserMapperdb2 {
    
        void insertUser(User user);
    
        User selectUserById(int id);
    }
    <?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.baiyue.db2.mapper.UserMapperdb2">
    
        <!-- 根据 id 查询 user 表中的数据 id:唯一标识符,此文件中的id值不能重复 resultType:返回值类型,一条数据库记录也就对应实体类的一个对象 
            parameterType:参数类型,也就是查询条件的类型 -->
        <select id="selectUserById" resultType="com.baiyue.entity.User" parameterType="int">
            <!-- 这里和普通的sql 查询语句差不多,对于只有一个参数,后面的 #{id}表示占位符,里面不一定要写id,写啥都可以,但是不要空着,如果有多个参数则必须写pojo类里面的属性 -->
            select * from user where id = #{id}
        </select>
    
        <insert id="insertUser" parameterType="com.baiyue.entity.User">
            insert into
            user(id,username,sex,birthday,address)
            value(#{id},#{username},#{sex},#{birthday},#{address})
        </insert>
    </mapper>
    package com.baiyue.db2.service;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    import com.baiyue.db2.mapper.UserMapperdb2;
    import com.baiyue.entity.User;
    import lombok.extern.slf4j.Slf4j;
    
    @Service
    @Slf4j
    public class UserServicedb2 {
    
        @Autowired
        private UserMapperdb2 userMapper;
    
        @Transactional("db2TransactionManager")//指定事务管理
        public void insertUser(User user) {
            log.info("正在添加");
            userMapper.insertUser(user);
        };
    
        public User selectUserById(int id) {
            User user = userMapper.selectUserById(id);
            return user;
        };
    
    }

    5,controller 层:

    package com.baiyue.controller;
    
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.baiyue.db1.service.UserServicedb1;
    import com.baiyue.db2.service.UserServicedb2;
    import com.baiyue.entity.User;
    
    @RestController
    public class Mybatis {
        
        @Autowired
        private UserServicedb1 userService1;
        
        @Autowired
        private UserServicedb2 userService2;
        
        @RequestMapping("/insertUserdb1")
        public String insertUserdb1(){
            User user = new User();
            user.setUsername("chris");
            user.setSex("male");
            userService1.insertUser(user);
            return "db1success";
        }
        
        @RequestMapping("/insertUserdb2")
        public String insertUserdb2() {
            User user = new User();
            user.setUsername("chris");
            user.setSex("male");
            userService2.insertUser(user);
            return "db2success";
        }
    
    }

    6,启动类

    @MapperScan({"com.baiyue.db1.mapper","com.baiyue.db2.mapper"})
    @ComponentScan(basePackages = "com.baiyue") //因为有一些bean 不在当前包或者子包下面,所以@SpringBootApplication 会有些bean 扫不到
    @SpringBootApplication
    public class App {
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }

    这样,能够多数据源操作了。。。

  • 相关阅读:
    Unity3d通用工具类之生成文件的MD5
    Unity3d-Socket之龙一编年史network.dll分析(2)-> CNetLogger
    Unity3d-Socket之龙一编年史network.dll分析(1)
    Unity3d设计模式之单例模式
    c#中的??运算符
    java 字节流
    java File文件操作
    java 线程池和lamda表达式
    java 线程状态(通信/等待/唤醒)
    java 线程安全
  • 原文地址:https://www.cnblogs.com/pickKnow/p/11194759.html
Copyright © 2011-2022 走看看