美文网首页
springboot jpa多数据源

springboot jpa多数据源

作者: adced06edef5 | 来源:发表于2020-01-04 14:39 被阅读0次

    由于现在很多系统都不在使用单一数据库,所以想试下springboot jpa多数据源配置,网上也有很多这方便的文章,可能是版本不一致,存在这各种问题,始终无法成功运行,后经过反复尝试,最后终于成功运行,这里做下记录:
    springboot 版本:2.2.2.RELEASE
    数据库:mysql 5.7
    开发工具:idea 2019.2
    1、首先要有多个数据库,我这里创建了2个数据库demo、demo2
    2、创建项目
    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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.2.2.RELEASE</version>
            <relativePath/> <!-- lookup parent from repository -->
        </parent>
        <groupId>com.example</groupId>
        <artifactId>demo1</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>demo1</name>
        <description>Demo project for Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-jpa</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-devtools</artifactId>
                <scope>runtime</scope>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
                <optional>true</optional>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    

    2、application.yml

    spring:
      datasource:
        ds1:
          driver-class-name: com.mysql.cj.jdbc.Driver
          jdbc-url: jdbc:mysql://localhost:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
          username: root
          password: 1234
        ds2:
          driver-class-name: com.mysql.cj.jdbc.Driver
          jdbc-url: jdbc:mysql://localhost:3306/demo2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
          username: root
          password: 1234
      jpa:
        hibernate:
          ddl-auto: update
        open-in-view: true
        properties:
          hibernate:
            physical_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
            implicit_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
            dialect:  org.hibernate.dialect.MySQL57Dialect
            format_sql: true
            hbm2ddl:
              auto: update
        show-sql: true
        database: mysql
    

    配置说明:
    springboot默认使用的HikariPool数据源,数据源配置应使用jdbc-url,而不是常用的url。单个数据源时使用的spring.jpa.hibernate下的配置,而使用多数据源时则使用的是spring.jpa.hibernate.properties下的配置,具体配置网上有很多数据,在此就不多做说明,不清楚的可以网上查一下。这里就提一下physical_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
    implicit_naming_strategy: org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy
    这两个配置是创建表时表字段使用下划线形式,而不是驼峰形式,若不配置,表字段和实体属性一致。
    3、实体类,此处创建两个实体类,分别对应demo、demo2两个数据库
    Person类

    @Entity
    @Table(name = "d_person")
    public class Person implements Serializable {
    
        private static final long serialVersionUID = 580119470723651341L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        private String personNo;
    
        private String name;
    
        private Integer age;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getPersonNo() {
            return personNo;
        }
    
        public void setPersonNo(String personNo) {
            this.personNo = personNo;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    }
    

    Student类

    @Entity
    @Table(name = "d_student")
    public class Student implements Serializable {
    
        private static final long serialVersionUID = 7993941906610435818L;
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        private Long id;
    
        private String studentNo;
    
        private String name;
    
        public Long getId() {
            return id;
        }
    
        public void setId(Long id) {
            this.id = id;
        }
    
        public String getStudentNo() {
            return studentNo;
        }
    
        public void setStudentNo(String studentNo) {
            this.studentNo = studentNo;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    

    4、Repository类

    @Repository
    public interface PersonRepository extends BaseRepository<Person,Long> {
    
    }
    
    @Repository
    public interface StudentRepository extends BaseRepository<Student,Long> {
    }
    

    这里的BaseRepository是我自己定义的接口,主要继承了Repository接口
    5、配置类
    DataSourceConfigDs1和DataSourceConfigDs2分别对应demo、demo2

    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactoryDs1",//配置连接工厂 entityManagerFactory
            transactionManagerRef = "transactionManagerDs1", //配置 事物管理器  transactionManager
            basePackages = {"com.example.demo1.repository.ds1"}
    )
    public class DataSourceConfigDs1 {
    
        @Bean(name = "ds1")
        @Primary
        @ConfigurationProperties(prefix = "spring.datasource.ds1")
        public DataSource dataSourceDs1(){
            return DataSourceBuilder.create().build();
        }
    
        @Autowired
        private JpaProperties jpaProperties;
    
        @Bean("entityManagerDs1")
        @Primary
        public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
            return entityManagerFactoryBean(builder).getObject().createEntityManager();
        }
        @Bean("entityManagerFactoryDs1")
        @Primary
        public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
            return builder.dataSource(dataSourceDs1())
                    .properties(jpaProperties.getProperties())
                    .packages("com.example.demo1.repository.ds1")
                    //持久化单元名称,当存在多个EntityManagerFactory时,需要制定此名称
                    .persistenceUnit("persistenceUnitDs1")
                    .build();
    
        }
    
        @Bean("transactionManagerDs1")
        @Primary
        public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
        }
    }
    
    @Configuration
    @EnableTransactionManagement
    @EnableJpaRepositories(
            entityManagerFactoryRef = "entityManagerFactoryDs2",//配置连接工厂 entityManagerFactory
            transactionManagerRef = "transactionManagerDs2", //配置 事物管理器  transactionManager
            basePackages = {"com.example.demo1.repository.ds2"}
    )
    public class DataSourceConfigDs2 {
    
        @Bean(name = "ds2")
        @ConfigurationProperties(prefix = "spring.datasource.ds2")
        public DataSource dataSourceDs2(){
            return DataSourceBuilder.create().build();
        }
    
        @Autowired
        private JpaProperties jpaProperties;
    
        @Bean("entityManagerDs2")
        public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
            return entityManagerFactoryBean(builder).getObject().createEntityManager();
        }
        @Bean(value = "entityManagerFactoryDs2")
        public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(EntityManagerFactoryBuilder builder) {
            return builder.dataSource(dataSourceDs2())
                    .properties(jpaProperties.getProperties())
                    .packages("com.example.demo1.repository.ds2")
                    //持久化单元名称,当存在多个EntityManagerFactory时,需要制定此名称
                    .persistenceUnit("persistenceUnitDs2")
                    .build();
    
        }
    
        @Bean("transactionManagerDs2")
        public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
            return new JpaTransactionManager(entityManagerFactoryBean(builder).getObject());
        }
    }
    

    配置多数据源时需要指定主数据源,使用@Primary即可。basePackages 为Reporitory类路径,对应的实体类应该在Repository类路径下。
    项目启动后可以看到控制台有sql打印:


    image.png
    image.png

    通过navicat工具查看:


    image.png
    表结构:
    image.png
    image.png
    由上图可以看出字段为下划线格式

    到此整个springboot jpa多数源的配置过程就完成了。
    代码github:https://github.com/panli1988/demo1/tree/master/src/main/java/com/example/demo1

    相关文章

      网友评论

          本文标题:springboot jpa多数据源

          本文链接:https://www.haomeiwen.com/subject/akgxactx.html