• Spring Boot 应用系列 3 -- Spring Boot 2 整合MyBatis和Druid,多数据源


    本文演示多数据源(MySQL+SQL Server)的配置,并且我引入了分页插件pagehelper。

    1. 项目结构

    (1)db.properties存储数据源和连接池配置。

    (2)两个数据源的mapper配置分别在src/main/resources下面的datasource1和datasource2里面。

    2. pom.xml

    需要在dependencies节点中添加:

    <!-- MySQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.12</version>
    </dependency>
    <!-- MySQL end -->
    
    <!-- SQL Server -->
    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>mssql-jdbc</artifactId>
    </dependency>
    <!-- SQL Server end -->
    
    <!-- Connection Pool -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
        <version>1.1.10</version>
    </dependency>
    <!-- Connection Pool end -->
    
    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
    <!-- MyBatis end -->
    
    <!-- Page Helper -->
    <dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.1.5</version>
    </dependency>
    <!-- Page Helper end -->

    3. properties配置文件

    我们把主程序配置文件application.properties和数据库配置文件分开,这样可使application.properties不至于臃肿。

    (1) application.properties

    server.port=9008
    spring.application.name=devutility-test-database-mybatis-springboot
    
    #Configuration for druid
    spring.datasource.druid.stat-view-servlet.enabled=true
    spring.datasource.druid.stat-view-servlet.url-pattern=/druid/*
    spring.datasource.druid.stat-view-servlet.login-username=admin
    spring.datasource.druid.stat-view-servlet.login-password=admin

    Druid ui的配置也放在里面,可通过http://localhost:9008/druid来访问。

    (2) db.properties

     1 #Data source 1
     2 db1.sqlserver.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
     3 db1.sqlserver.url=${DB1_URL:jdbc:sqlserver://127.0.0.1:1433;DatabaseName=MyTestDb1}
     4 db1.sqlserver.username=${DB1_UID:tester}
     5 db1.sqlserver.password=${DB1_PWD:tester}
     6 db1.sqlserver.initial-size=1
     7 db1.sqlserver.min-idle=1
     8 db1.sqlserver.max-active=20
     9 db1.sqlserver.max-wait=60000
    10 db1.sqlserver.time-between-eviction-runs-millis=60000
    11 db1.sqlserver.min-evictable-idle-time-millis=300000
    12 db1.sqlserver.validation-query=select 1
    13 db1.sqlserver.test-on-borrow=true
    14 db1.sqlserver.test-While-Idle=true
    15 db1.sqlserver.test-on-return=false
    16 db1.sqlserver.pool-prepared-statements=false
    17 db1.sqlserver.max-pool-prepared-statement-per-connection-size=20
    18 
    19 db1.sqlserver.mybatis.config-location=classpath:datasource1/mybatis-config.xml
    20 
    21 db1.sqlserver.filter.stat.enabled=true
    22 db1.sqlserver.filter.stat.db-type=mssql
    23 db1.sqlserver.filter.stat.log-slow-sql=true
    24 db1.sqlserver.filter.stat.slow-sql-millis=200
    25 
    26 #Data source 2
    27 db2.mysql.driver-class-name=com.mysql.cj.jdbc.Driver
    28 db2.mysql.url=${DB2_URL:jdbc:mysql://127.0.0.1:3306/Test}?useUnicode=true&useSSL=false
    29 db2.mysql.username=${DB2_UID:tester}
    30 db2.mysql.password=${DB2_PWD:tester}
    31 db2.mysql.initial-size=1
    32 db2.mysql.min-idle=1
    33 db2.mysql.max-active=20
    34 db2.mysql.max-wait=60000
    35 db2.mysql.time-between-eviction-runs-millis=60000
    36 db2.mysql.min-evictable-idle-time-millis=300000
    37 db2.mysql.validation-query=select 1
    38 db2.mysql.test-on-borrow=true
    39 db2.mysql.test-While-Idle=true
    40 db2.mysql.test-on-return=false
    41 db2.mysql.pool-prepared-statements=false
    42 db2.mysql.max-pool-prepared-statement-per-connection-size=20
    43 
    44 db2.mysql.mybatis.config-location=classpath:datasource2/mybatis-config.xml
    45 
    46 db2.mysql.filter.stat.enabled=true
    47 db2.mysql.filter.stat.db-type=mysql
    48 db2.mysql.filter.stat.log-slow-sql=true
    49 db2.mysql.filter.stat.slow-sql-millis=1000

    注意19和44行,我们为两个数据源分别使用mybatis-config.xml来管理它们所属的mapper xml和其他一些配置。

    4. JavaConfig

    (1) DataSource1

    package devutility.test.database.mybatis.springboot.multi.source.config;
    
    import java.util.Properties;
    
    import javax.sql.DataSource;
    
    import org.apache.ibatis.plugin.Interceptor;
    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.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.core.io.Resource;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    
    import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
    import com.github.pagehelper.PageInterceptor;
    
    @Configuration
    @PropertySource("classpath:db.properties")
    @MapperScan(basePackages = { "devutility.test.database.mybatis.springboot.multi.source.ds1" }, sqlSessionFactoryRef = "sqlSessionFactory1", sqlSessionTemplateRef = "sqlSessionTemplate1")
    public class DataSource1Configuration {
        @Bean
        @ConfigurationProperties("db1.sqlserver")
        public DataSource dataSource1() {
            return DruidDataSourceBuilder.create().build();
        }
    
        @Bean
        @ConfigurationProperties("db1.sqlserver")
        public Properties ormProperties1() {
            return new Properties();
        }
    
        @Bean
        public Interceptor pageHelperInterceptor1() {
            Properties properties = new Properties();
            properties.setProperty("helperDialect", "sqlserver2012");
    
            Interceptor interceptor = new PageInterceptor();
            interceptor.setProperties(properties);
            return interceptor;
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactory1(DataSource dataSource1, Properties ormProperties1) throws Exception {
            String configLocation = ormProperties1.getProperty("mybatis.config-location");
            Resource[] resources = new PathMatchingResourcePatternResolver().getResources(configLocation);
    
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource1);
            sqlSessionFactoryBean.setConfigLocation(resources[0]);
            sqlSessionFactoryBean.setPlugins(new Interceptor[] { pageHelperInterceptor1() });
            return sqlSessionFactoryBean.getObject();
        }
    
        @Bean
        public SqlSessionTemplate sqlSessionTemplate1(SqlSessionFactory sqlSessionFactory1) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory1);
        }
    
        @Bean
        public DataSourceTransactionManager dataSourceTransactionManager1(DataSource dataSource1) {
            return new DataSourceTransactionManager(dataSource1);
        }
    }

    (2) DataSource2

    package devutility.test.database.mybatis.springboot.multi.source.config;
    
    import java.util.Properties;
    
    import javax.sql.DataSource;
    
    import org.apache.ibatis.plugin.Interceptor;
    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.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.core.io.Resource;
    import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
    import org.springframework.jdbc.datasource.DataSourceTransactionManager;
    
    import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;
    import com.github.pagehelper.PageInterceptor;
    
    @Configuration
    @PropertySource("classpath:db.properties")
    @MapperScan(basePackages = { "devutility.test.database.mybatis.springboot.multi.source.ds2" }, sqlSessionFactoryRef = "sqlSessionFactory2", sqlSessionTemplateRef = "sqlSessionTemplate2")
    public class DataSource2Configuration {
        @Bean
        @ConfigurationProperties("db2.mysql")
        public DataSource dataSource2() {
            return DruidDataSourceBuilder.create().build();
        }
    
        @Bean
        @ConfigurationProperties("db2.mysql")
        public Properties ormProperties2() {
            return new Properties();
        }
    
        @Bean
        public Interceptor pageHelperInterceptor2() {
            Properties properties = new Properties();
            properties.setProperty("helperDialect", "mysql");
    
            Interceptor interceptor = new PageInterceptor();
            interceptor.setProperties(properties);
            return interceptor;
        }
    
        @Bean
        public SqlSessionFactory sqlSessionFactory2(DataSource dataSource2, Properties ormProperties2) throws Exception {
            String configLocation = ormProperties2.getProperty("mybatis.config-location");
            Resource[] resources = new PathMatchingResourcePatternResolver().getResources(configLocation);
    
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource2);
            sqlSessionFactoryBean.setConfigLocation(resources[0]);
            sqlSessionFactoryBean.setPlugins(new Interceptor[] { pageHelperInterceptor2() });
            return sqlSessionFactoryBean.getObject();
        }
    
        @Bean
        public SqlSessionTemplate sqlSessionTemplate2(SqlSessionFactory sqlSessionFactory2) throws Exception {
            return new SqlSessionTemplate(sqlSessionFactory2);
        }
    
        @Bean
        public DataSourceTransactionManager dataSourceTransactionManager2(DataSource dataSource2) {
            return new DataSourceTransactionManager(dataSource2);
        }
    }

    注意,两个配置文件均有一个Properties类型的bean,该bean存储着db.properties中的所有配置,但是真正用到的配置只有一个"mybatis.config-location",它的值就是mybatis-config.xml的存储地址。当然,你也可以删掉ormProperties 这个bean,删掉db.properties的"mybatis.config-location"属性,然后以hardcode的方式在Configuration中配ConfigLocation.

    5. MyBatis相关配置

    MyBatis的配置主要包括mybatis-config.xml,mapper的xml文件,mapper的接口文件,和实体类,比单数据源多了一个mybatis-config.xml文件的配置。

    (1) mybatis-config.xml

    在本文中,该文件用来配置数据源相关的xml映射文件和实体类的包,其他配置项可参考MyBatis官网

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <settings>
            <setting name="logImpl" value="STDOUT_LOGGING" />
        </settings>
        <typeAliases>
            <package name="devutility.test.database.mybatis.springboot.multi.source.ds2.entities" />
        </typeAliases>
        <mappers>
            <mapper resource="datasource2/mappers/CustomerMapper.xml" />
        </mappers>
    </configuration>

    datasource1的配置类似,不再赘述。

    (2) mapper的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="devutility.test.database.mybatis.springboot.multi.source.ds2.mappers.CustomerMapper">
        <resultMap id="CustomerMapping" type="Customer">
            <id column="Name1" property="name" />
            <id column="Address1" property="address" />
        </resultMap>
        <select id="get" resultMap="CustomerMapping">
            select * from Customer where id = #{id};
        </select>
        <select id="list" resultMap="CustomerMapping">
            select * from Customer where Name1 is not null order by Created desc
        </select>
    </mapper>

    (3) mapper的接口文件

    package devutility.test.database.mybatis.springboot.multi.source.ds2.mappers;
    
    import java.util.List;
    
    import org.apache.ibatis.annotations.Mapper;
    
    import devutility.test.database.mybatis.springboot.multi.source.ds2.entities.Customer;
    
    @Mapper
    public interface CustomerMapper {
        Customer get(long id);
    
        List<Customer> list();
    }

    (4) 实体类

    package devutility.test.database.mybatis.springboot.multi.source.ds2.entities;
    
    public class Customer extends BaseEntity {
        private long id;
        private String name;
        private String address;
        private String city;
        private String state;
        private int zip;
        private String phone;
        private String email;

    6. 应用

    package devutility.test.database.mybatis.springboot.multi.source.controller;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import com.github.pagehelper.PageHelper;
    
    import devutility.test.database.mybatis.springboot.multi.source.ds2.entities.Customer;
    import devutility.test.database.mybatis.springboot.multi.source.ds2.mappers.CustomerMapper;
    
    @RestController
    @RequestMapping("/ds2")
    public class Ds2Controller {
        @Autowired
        private CustomerMapper customerMapper;
    
        @RequestMapping("/customer")
        public Customer customer(long id) {
            return customerMapper.get(id);
        }
    
        @RequestMapping("customers-page")
        public List<Customer> customersPage(int page) {
            return PageHelper.startPage(page, 10).doSelectPage(() -> customerMapper.list());
        }
    }

    Demo代码

  • 相关阅读:
    ViewPager+Fragmrnt最简单结合方法
    Microsoft SQL Server Version List(SQL Server 版本)
    hdu 2795 Billboard(线段树单点更新)
    面向对象程序设计的思想的长处
    iOS 友盟分享
    使用Broadcast实现android组件之间的通信
    jquery ui 分页插件 传入后台的连个參数名
    android adb常见问题的解决方法!
    UVa 11015
    优秀程序猿学习方法
  • 原文地址:https://www.cnblogs.com/eagle6688/p/9634521.html
Copyright © 2020-2023  润新知