开始公司主要使用的是Springboot+JPA后来要对接一个其他系统,然后加了一个数据库,就成了Springboot+JPA+多数据源,但是后面随着业务发现JPA有时候用着太难受,就想着加个Mybatis,然后去网上搜如何整合JPA+Mybatis,但是网上的教程都是单数据源整合的,没有发现多数据源整合的案例。想着之前整合过Mybatis+多数据源,然后就把配置文件复制一份,开始踩坑之路。
目录
目录
一、注意点
二、文件目录
三、application文件和pom文件
applicatio文件
pom文件
四、配置文件
配置两个数据源
JPA的配置文件,
Mybats的配置文件
spring:
jpa:
hibernate:
ddl-auto: none
show-sql: true
properties:
hibernate:
primary-dialect: org.hibernate.dialect.PostgreSQLDialect
secondary-dialect: org.hibernate.dialect.MySQL5Dialect
temp:
use_jdbc_metadata_defaults: false
#primary
primary:
datasource:
driver-class-name: org.postgresql.Driver
jdbc-url: jdbc:postgresql://127.0.0.1:5432/xxxx
username: user
password: password
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 10000
timeBetweenEvictionRunMillis: 60000
minEvictableIdleTimeMillis: 30000
validationQuery: SELECT 'x'
testWhileIdle: true
testOnBorrow: true
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 10
filters: stat
#secondary
secondary:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
jdbc-url: jdbc:mysql://127.0.0.1:3307/bitnami_redmine?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&useLegacyDatetimeCode=false
username: bitnami
password: 928311f90a
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 10000
timeBetweenEvictionRunMillis: 60000
minEvictableIdleTimeMillis: 30000
validationQuery: SELECT 'x'
testWhileIdle: true
testOnBorrow: true
testOnReturn: false
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 10
filters: stat
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
mail:
host: smtp.glorysoft.com
port: 25
username: [email protected]
password: glory123
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
main:
allow:
bean:
definition:
overriding: true
logging:
config: classpath:config/logback.xml
level:
com:
glory:
oa:
pm:
mapper: debug
需要注意的地方就是,Springboot和mybatis的版本必须对应,这个很坑,这个我也不清楚具体的对应版本,只知道我用的这两个是不冲突的。SpringBoot-2.1.12和Mybatis-2.1.1
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.12.RELEASE
com.glory.oa
oa.pm
1.0.0
oa.pm
Demo project for Spring Boot
1.8
org.springframework.boot
spring-boot-starter-data-jpa
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.1
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-web-services
……
org.postgresql
postgresql
runtime
mysql
mysql-connector-java
……
org.springframework.boot
spring-boot-maven-plugin
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 javax.sql.DataSource;
/**
* 数据源的配置
*/
@Configuration
public class DataSourceConfig {
@Bean(name = "primaryDataSource")
@Qualifier("primaryDataSource")
@ConfigurationProperties(prefix = "spring.primary.datasource")
@Primary
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@Qualifier("secondaryDataSource")
@ConfigurationProperties(prefix = "spring.secondary.datasource")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* 数据源一
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactoryPrimary",
transactionManagerRef = "transactionManagerPrimary",
basePackages = {
"com.glory.oa.pm.repository"
}) //设置Repository所在位置
public class PrimaryConfig {
@Autowired
@Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(primaryDataSource)
.properties(getVendorProperties())
.packages(
"com.glory.oa.pm.domain"
) //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
private Map getVendorProperties() {
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;
/**
* 数据源二
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactorySecondary",
transactionManagerRef = "transactionManagerSecondary",
basePackages = {
"com.glory.oa.pm.readmine.repository"
}) //设置Repository所在位置
public class SecondaryConfig {
@Autowired
@Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@Bean(name = "entityManagerSecondary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactorySecondary")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondaryDataSource)
.properties(getVendorProperties())
.packages(
"com.glory.oa.pm.readmine.domain"
) //设置实体类所在位置
.persistenceUnit("secondaryPersistenceUnit")
.build();
}
@Autowired
private JpaProperties jpaProperties;
@Autowired
private HibernateProperties hibernateProperties;
private Map getVendorProperties() {
return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
}
//用来作为数据库事务回滚的限定词
//@Transactional(rollbackFor = OAPMException.class, value = "transactionManagerSecondary")
//事务管理器
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
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.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
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;
import javax.persistence.EntityManager;
import javax.sql.DataSource;
/**
* Created with IntelliJ IDEA.
*
* @Author: wpt
* @Date: 2020/02/10/11:07
* @Description:
*/
//表示这个类为一个配置类
@Configuration
// 配置mybatis的接口类放的地方
@MapperScan(basePackages = "com.glory.oa.pm.mapper.mybatis",
sqlSessionFactoryRef = "primarySqlSessionFactory")
public class PrimaryDataConfig {
// 创建SessionFactory
@Bean(name = "primarySqlSessionFactory")
@Primary
public SqlSessionFactory primarySqlSessionFactory(@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath*:/mybatis/Primary/*/*Mapper.xml"));
bean.setTypeAliasesPackage("com.glory.oa.pm.domain");
return bean.getObject();
}
// 创建事务管理器
@Bean("primaryTransactionMangerMybatis")
@Primary
public DataSourceTransactionManager primaryTransactionManger(@Qualifier("primaryDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
// 创建SqlSessionTemplate
@Bean(name = "primarySqlSessionTemplate")
@Primary
public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("primarySqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
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.boot.orm.jpa.EntityManagerFactoryBuilder;
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;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
/**
* Created with IntelliJ IDEA.
*
* @Author: wpt
* @Date: 2020/02/10/11:08
* @Description:
*/
@Configuration
@MapperScan(basePackages = "com.glory.oa.pm.redmine.repository.mybatis",
sqlSessionFactoryRef = "secondarySqlSessionFactory")
public class SecondaryDataConfig {
@Bean(name = "secondarySqlSessionFactory")
@Primary
public SqlSessionFactory SecondarySqlSessionFactory(@Qualifier("secondaryDataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/Secondary/*/*.xml"));
bean.setTypeAliasesPackage("com.glory.oa.pm.redmine.domain");
return bean.getObject();
}
@Primary
@Bean("SecondarySqlSessionTemplate")
public SqlSessionTemplate SecondarySqlsessiontemplate(
@Qualifier("secondarySqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
//用来作为数据库事务回滚的限定词
//@Transactional(rollbackFor = OAPMException.class, value = "transactionManagerSecondary")
// 创建事务管理器
@Bean("secondTransactionMangerMybatis")
@Primary
public DataSourceTransactionManager secondTransactionManger(@Qualifier("secondaryDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}