1. As a supplement to the previous one, this article can be referred to.
https://my.oschina.net/swiftloop/blog/1031404
2. Realization
1)pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sorata.datasource</groupId> <artifactId>mybatis-pagehelper-mapper</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>mybatis-pagehelper-mapper</name> <description>Integrate mybatis Multiple Data Sources and Paging Plug-ins and Universal mapper Use</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.4.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <!-- Here is the package for configuring master and slave libraries when generating different databases dao,mapper,entity Need to change this package, or directly in generator.xml Hard Coding Under Files--> <!--Store generated dao and entity--> <targetJavaProject>${basedir}/src/main/java</targetJavaProject> <!--end--> <!-- XML Generation path --> <targetResourcesProject>${basedir}/src/main/resources</targetResourcesProject> <targetXMLPackage>mapper/master</targetXMLPackage> <!--end--> <!--Deposit dao Package--> <targetMapperPackage>com.sorata.datasource.dao.master</targetMapperPackage> <!--end--> <!--Deposit entity Package--> <targetModelPackage>com.sorata.datasource.entity.master</targetModelPackage> <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.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.29</version> </dependency> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-commons</artifactId> <version>1.13.1.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.30</version> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper</artifactId> <version>3.4.0</version> </dependency> </dependencies> </plugin> </plugins> </build> </project>
2)generator.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <properties resource="application.yml"/> <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat"> <property name="beginningDelimiter" value="`"/> <property name="endingDelimiter" value="`"/> <plugin type="tk.mybatis.mapper.generator.MapperPlugin"> <!-- Here is a class under the project package--> <property name="mappers" value="com.sorata.datasource.webmvc.MyMapper"/> </plugin> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test1" userId="root" password="root"> </jdbcConnection> <javaModelGenerator targetPackage="${targetModelPackage}" targetProject="${targetJavaProject}"/> <sqlMapGenerator targetPackage="${targetXMLPackage}" targetProject="${targetResourcesProject}"/> <javaClientGenerator targetPackage="${targetMapperPackage}" targetProject="${targetJavaProject}" type="XMLMAPPER" /> <table tableName="test" domainObjectName="CustomTest"> <!--mysql To configure--> <generatedKey column="id" sqlStatement="Mysql" identity="true"/> <!--oracle To configure--> <!--<generatedKey column="id" sqlStatement="select SEQ_{1}.nextval from dual" identity="false" type="pre"/>--> </table> </context> </generatorConfiguration>
3)MyMapper.java
package com.sorata.datasource.webmvc; import tk.mybatis.mapper.common.Mapper; import tk.mybatis.mapper.common.MySqlMapper; /** * Created by: Sorata 17/4/12 12:03 p.m. */ public interface MyMapper<T> extends Mapper<T>,MySqlMapper<T> { }
4)MasterDataSourceConfig.java
package com.sorata.datasource.config; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; 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; /** * Created by : Sorata 2017/6/27 0027 3:56. PM */ @Configuration @MapperScan(basePackages = MasterDataSourceConfig.MASTER_PACKAGE,sqlSessionFactoryRef = "masterSqlSessionFactory") public class MasterDataSourceConfig { private Logger logger = LoggerFactory.getLogger(MasterDataSourceConfig.class); static final String MASTER_PACKAGE = "com.sorata.datasource.dao.master"; private static final String MASTER_MAPPER_LOCAL = "classpath:mapper/master/*.xml"; /** Configure a main library * @return DruidDataSource */ @Bean(name = "masterDataSource") @Primary @ConfigurationProperties(prefix = "druid.datasource") public DruidDataSource masterDruidDataSource(){ return new DruidDataSource(); } @Bean(name = "masterSqlSessionFactory") @Primary public SqlSessionFactory masterSqlSessionFactory(){ final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(masterDruidDataSource()); try { sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MASTER_MAPPER_LOCAL)); return sessionFactoryBean.getObject(); } catch (Exception e) { logger.error("Configuring the main library SqlSessionFactory Failure error:{}",e.getMessage()); throw new RuntimeException(e.getMessage()); } } @Bean(name = "masterTransactionManager") @Primary public DataSourceTransactionManager masterTransactionManager(){ return new DataSourceTransactionManager(masterDruidDataSource()); } }
5)CustomDataSourceConfig.java
package com.sorata.datasource.config; import com.alibaba.druid.pool.DruidDataSource; import org.apache.ibatis.session.SqlSessionFactory; import org.mybatis.spring.SqlSessionFactoryBean; import org.mybatis.spring.annotation.MapperScan; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.context.properties.ConfigurationProperties; 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; /** * Created by : Sorata 2017/6/27 0027 3:56. PM */ @Configuration @MapperScan(basePackages = CustomDataSourceConfig.CUSTOM_PACKAGE,sqlSessionFactoryRef = "customSqlSessionFactory") public class CustomDataSourceConfig { private Logger logger = LoggerFactory.getLogger(CustomDataSourceConfig.class); static final String CUSTOM_PACKAGE = "com.sorata.datasource.dao.custom"; private static final String CUSTOM_MAPPER_LOCAL = "classpath:mapper/custom/*.xml"; /** Configure a slave Library * @return DruidDataSource */ @Bean(name = "customDataSource") @ConfigurationProperties(prefix = "custom.datasource") public DruidDataSource customDruidDataSource(){ return new DruidDataSource(); } @Bean(name = "customSqlSessionFactory") public SqlSessionFactory customSqlSessionFactory(){ final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); sessionFactoryBean.setDataSource(customDruidDataSource()); try { sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(CUSTOM_MAPPER_LOCAL)); return sessionFactoryBean.getObject(); } catch (Exception e) { logger.error("Configuring slave Libraries SqlSessionFactory Failure error:{}",e.getMessage()); throw new RuntimeException(e.getMessage()); } } @Bean(name = "customTransactionManager") public DataSourceTransactionManager customTransactionManager(){ return new DataSourceTransactionManager(customDruidDataSource()); } }
6)DataSourcesAutoConfiguration.java
package com.sorata.datasource.config; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.context.annotation.Configuration; import org.springframework.data.transaction.ChainedTransactionManager; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import org.springframework.transaction.annotation.TransactionManagementConfigurer; import javax.annotation.Resource; /** * Created by : Sorata 2017/6/27 0027 1:38. PM */ @Configuration @EnableTransactionManagement @ConditionalOnBean({MasterDataSourceConfig.class,CustomDataSourceConfig.class}) public class DataSourcesAutoConfiguration implements TransactionManagementConfigurer{ @Resource private MasterDataSourceConfig masterDataSourceConfig; @Resource private CustomDataSourceConfig customDataSourceConfig; // Configuring Distributed Transaction Management @Override public PlatformTransactionManager annotationDrivenTransactionManager() { return new ChainedTransactionManager(masterDataSourceConfig.masterTransactionManager(),customDataSourceConfig.customTransactionManager()); } }
Note: This solves the problem of using annotations to display transaction managers annotated from the repository when there are two transaction managers.
7) Druid. Note the addition of @ServletComponentScan to the startup class
package com.sorata.datasource.config; import com.alibaba.druid.support.http.StatViewServlet; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; /** * Created by: guobo 17/1/19 5:20 p.m. * * alibaba druid Page monitoring configuration accesses URL http://localhost:8080/project name/druid/index.html * * When using spring boot, you need to use the @ServletComponentScan annotation in the startup class */ @SuppressWarnings("serial") @WebServlet(urlPatterns = "/druid/*",initParams = { //@ WebInitParam (name = allow, value = 127.0.0.1, 192.168.1.142), //whitelist @WebInitParam(name = "deny",value = "126.12.22.1"),//Blacklist (deny takes precedence over allow when there is common ground) @WebInitParam(name="loginUsername",value="admin"),// User name @WebInitParam(name="loginPassword",value="123456"),// Password @WebInitParam(name="resetEnable",value="false")// Disable "Reset All" functionality on HTML pages }) public class DruidStateViewServlet extends StatViewServlet { }
package com.sorata.datasource.config; import com.alibaba.druid.support.http.WebStatFilter; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; /** * Created by: guobo 17/1/19 5:27 p.m. * * alibaba druid Filtration */ @WebFilter(filterName="druidWebStatFilter",urlPatterns="/*", initParams={ @WebInitParam(name="exclusions",value="*.mp4,*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*")// Ignore resources }) public class DruidStatFilter extends WebStatFilter { }
8)application.yml
druid: datasource: name: mydatabases url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver filters: stat,wall,log4j maxActive: 20 initialSize: 1 maxWait: 60000 minIdle: 1 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: select 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: false #If it is oracle, it can be set to true, if it is mysql, it can be set to false database with more sub-database and sub-table. It is recommended that it be configured as false. maxOpenPreparedStatements: 20 custom: datasource: name: mydatabases2 url: jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=utf-8&useSSL=false username: root password: root type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.jdbc.Driver filters: stat,wall,log4j maxActive: 20 initialSize: 1 maxWait: 60000 minIdle: 1 timeBetweenEvictionRunsMillis: 60000 minEvictableIdleTimeMillis: 300000 validationQuery: select 'x' testWhileIdle: true testOnBorrow: false testOnReturn: false poolPreparedStatements: false #If it is oracle, it can be set to true, if it is mysql, it can be set to false database with more sub-database and sub-table. It is recommended that it be configured as false. maxOpenPreparedStatements: 20 pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: count=countSql
3. Summary
After introducing general Mapper dependencies and PageHelper dependencies, they are all automatically configured. PageHeler has automatic configuration on multiple data sources, so it is not necessary to add plug-ins when configuring SqlSession Factory. If added, the exception of adding multiple paging plug-ins will be reported. And the manager that uses ChainedTransaction Manager to manage multiple transaction managers does not need to display annotated slave libraries anymore.
Attachment:
Pagehelper:https://github.com/pagehelper/Mybatis-PageHelper
Mapper:http://git.oschina.net/free/Mapper/blob/master/wiki/mapper3/2.Integration.md
This project: http://git.oschina.net/lencer93/mybatis-pagehelper-mapper