SpringBoot整合JPA,配置多数据库

写在前面

SpringBoot创建项目非常方便,而且进行数据访问抛弃了很多繁琐的配置,我前面写的系列博文中,有教大家如何使用SpringBoot进行数据访问,里面谈到了整合JDBC、MyBatis以及JPA。我自己实际开发中,如果没有什么要求限制的话,比较习惯使用JPA进行数据访问,所以在这里,我专门编写一篇博文,来教如何使用SpringBoot整合JPA,进行多数据库的配置,如果有帮助,记得点个关注和点个赞哦

准备

开始之前呢,我们需要先创建项目啦,创建项目使用的是Idea的Spring Initializr进行创建,选择SpringBoot场景的时候,勾选Web、Spring Data JPA、MySQL Driver三个就可以了,如下,然后项目创建成功。
在这里插入图片描述
在这里插入图片描述

主配置文件

如果我们只是进行一个数据库的访问,我们只需要对数据库进行简单的配置,提供相应账号和密码就可以了,不过多个数据库也不是很麻烦,也就是相当于多一份配置内容出来而已,所有配置内容如下

application.properties

#数据库统一配置
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.properties.hibernate.format_sql=true

#主数据库
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost/ubiquity?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver

#副数据库
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost/ubiquity_vote?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver

配置类

我们都知道,我们在配置文件中写的配置,需要我们通过配置类的注入,覆盖掉默认的配置,这样才会生效,所以,我们能够想到,既然是需要使用多个数据库,对应的自然会有多个数据库的相关配置类(这篇博文的示例中,我使用两个数据库,所以有两个数据配置类)
在这里插入图片描述

我们知道,我们首先在只配置类中编写两个配置数据库的组件,然后分别其组件名,具体内容如下。

DataSourceConfig.java

package com.dbc.ubiquity.Config;

import org.springframework.beans.factory.annotation.Autowired;
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.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;
import java.util.Map;

@Configuration
public class DataSourceConfig {
    @Autowired
    private JpaProperties jpaProperties;
    @Autowired
    private HibernateProperties hibernateProperties;

    @Bean(name = "primaryDataSource")
    @Primary
    @ConfigurationProperties("spring.datasource.primary")
    public DataSource firstDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondaryDataSource")
    @ConfigurationProperties("spring.datasource.secondary")
    public DataSource secondDataSource(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "vendorProperties")
    public Map<String, Object> getVendorProperties() {
        return hibernateProperties.determineHibernateProperties(
                jpaProperties.getProperties(), new HibernateSettings());
    }
}

然后我们编写了针对两个数据库的配置类,里面的代码非常的相似,相信你敲了一遍之后,能够感悟到点什么。

PrimaryConfig.java

package com.dbc.ubiquity.Config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.Map;

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
        entityManagerFactoryRef = "entityManagerFactoryPrimary",
        transactionManagerRef = "transactionManagerPrimary",
        basePackages = {"com.dbc.ubiquity.Repository.Primary"}//Dao层的位置
)
public class PrimaryConfig {
    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;

    @Autowired
    @Qualifier("vendorProperties")
    private Map<String, Object> vendorProperties;

    @Bean(name = "entityManagerFactoryPrimary")
    @Primary
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder){
        return builder
                .dataSource(primaryDataSource)
                .properties(vendorProperties)
                .packages("com.dbc.ubiquity.Model.Primary")//实体类的位置
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }

    @Bean(name = "entityManagerPrimary")
    @Primary
    public EntityManager entityManager(EntityManagerFactoryBuilder builder){
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }

    @Bean(name = "transactionManagerPrimary")
    @Primary
    PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder){
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }
}

SecondaryConfig.java

package com.dbc.ubiquity.Config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.dbc.ubiquity.Repository.Secondary"}
)
public class SecondaryConfig {
    @Autowired
    @Qualifier("secondaryDataSource")
    private DataSource secondaryDataSource;

    @Autowired
    @Qualifier("vendorProperties")
    private Map<String, Object> vendorProperties;

    @Bean(name = "entityManagerFactorySecondary")
    public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder){
        return builder
                .dataSource(secondaryDataSource)
                .properties(vendorProperties)
                .packages("com.dbc.ubiquity.Model.Secondary")
                .persistenceUnit("secondaryPersistenceUnit")
                .build();
    }

    @Bean(name = "entityManagerSecondary")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder){
        return entityManagerFactorySecondary(builder).getObject().createEntityManager();
    }

    @Bean(name = "transactionManagerSecondary")
    PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder){
        return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
    }
}

实体类

首先我先把实体类的目录结构放在这,方便后面编写,然后说道实体类的创建,这里可以使用Idea帮我们逆向生成实体类,也就是依照在数据库中已经创建好的数据库表,自动生成实体类,不过这种方式生成出来的实体类,不符合现在编写JPA的序列化格式,生成出来的还是要增改(当然啦,你可以直接去更改实体类生成的模板,没错是可以改的,具体怎么改我这里就不赘述了,自己百度就可以知道),我就来说手动创建,手动创建的好处就是能够对知识点进行更加深入的掌握,当然啦,敲起来比较费时间。
在这里插入图片描述

扫描二维码关注公众号,回复: 9605648 查看本文章

User.java

package com.dbc.ubiquity.Entity.Primary;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "USER", schema = "ubiquity", catalog = "")
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;
    @Column(nullable = false, unique = true)
    private String userName;
    @Column(nullable = false)
    private String passWord;
    @Column(nullable = false, unique = true)
    private String email;
    @Column(nullable = true, unique = true)
    private String nickName;
    @Column(nullable = false)
    private String regTime;

    public User() {
    }

    public User(String userName, String passWord, String email, String nickName, String regTime) {
        this.userName = userName;
        this.passWord = passWord;
        this.email = email;
        this.nickName = nickName;
        this.regTime = regTime;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getRegTime() {
        return regTime;
    }

    public void setRegTime(String regTime) {
        this.regTime = regTime;
    }
}

Userq.java

package com.dbc.ubiquity.Entity.Secondary;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name = "USERQ", schema = "ubiquity_vote", catalog = "")
public class Userq implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;
    @Column(nullable = false, unique = true)
    private String userName;
    @Column(nullable = false)
    private String passWord;
    @Column(nullable = false, unique = true)
    private String email;
    @Column(nullable = true, unique = true)
    private String nickName;
    @Column(nullable = false)
    private String regTime;

    public Userq() {
    }

    public Userq(String userName, String passWord, String email, String nickName, String regTime) {
        this.userName = userName;
        this.passWord = passWord;
        this.email = email;
        this.nickName = nickName;
        this.regTime = regTime;
    }

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getNickName() {
        return nickName;
    }

    public void setNickName(String nickName) {
        this.nickName = nickName;
    }

    public String getRegTime() {
        return regTime;
    }

    public void setRegTime(String regTime) {
        this.regTime = regTime;
    }
}

写到这里,就要说一下前面主配置文件里面的一些配置是什么了,如下
在这里插入图片描述
它还有其他属性,如下:

  • ddl-auto:create----每次运行该程序,没有表格会新建表格,表内有数据会清空
  • ddl-auto:create-drop----每次程序结束的时候会清空表
  • ddl-auto:update----每次运行程序,没有表格会新建表格,表内有数据不会清空,只会更新
  • ddl-auto:validate----运行程序会校验数据与数据库的字段类型是否相同,不同会报错

Dao层

在这里插入图片描述

package com.dbc.ubiquity.Repository.Primary;

import com.dbc.ubiquity.Entity.Primary.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserPrimaryPository extends JpaRepository<User, Long> {
    User findById(long id);
    User findByUserName(String userName);
    User findByUserNameOrEmail(String username, String email);
}

package com.dbc.ubiquity.Repository.Secondary;

import com.dbc.ubiquity.Entity.Secondary.Userq;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserSecondaryPository extends JpaRepository<Userq, Long> {
    Userq findById(long id);
    Userq findByUserName(String userName);
    Userq findByUserNameOrEmail(String username, String email);
}

测试

到此,我们的多数据库配置流程到此结束,最后就是测试阶段了,我们来验证一下我们的配置是否有用。测试类的内容如下:

package com.dbc.ubiquity;

import com.dbc.ubiquity.Entity.Primary.User;
import com.dbc.ubiquity.Entity.Secondary.Userq;
import com.dbc.ubiquity.Repository.Primary.UserPrimaryPository;
import com.dbc.ubiquity.Repository.Secondary.UserSecondaryPository;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.util.Date;

@SpringBootTest
class UbiquityApplicationTests {
	@Resource
	private UserPrimaryPository userPrimaryPository;
	@Resource
	private UserSecondaryPository userSecondaryPository;

	@Test
	public void testSave() throws Exception{
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
		String formattedDate = dateFormat.format(date);
		userPrimaryPository.save(new User("aa", "aa123456","[email protected]", "aa",  formattedDate));
		userPrimaryPository.save(new User("bb", "bb123456","[email protected]", "bb",  formattedDate));
		userSecondaryPository.save(new Userq("cc", "cc123456","[email protected]", "cc",  formattedDate));
	}

	@Test
	public void testDelete() throws Exception {
		userPrimaryPository.deleteAll();
		userSecondaryPository.deleteAll();
	}

	@Test
	public void testBaseQuery() {
		Date date = new Date();
		DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG);
		String formattedDate = dateFormat.format(date);
		User user=new User("ff", "ff123456","[email protected]", "ff",  formattedDate);
		Userq userq=new Userq("ff", "ff123456","[email protected]", "ff",  formattedDate);
		userPrimaryPository.findAll();
		userSecondaryPository.findById(3l);
		userSecondaryPository.save(userq);
		user.setId(2l);
		userPrimaryPository.delete(user);
		userPrimaryPository.count();
		userSecondaryPository.findById(3l);
	}

	@Test
	void contextLoads() {
	}

}

在这里插入图片描述
在这里插入图片描述

发布了109 篇原创文章 · 获赞 556 · 访问量 103万+

猜你喜欢

转载自blog.csdn.net/DBC_121/article/details/104685200