Hello,欢迎来到程序员社区。 今天聊一聊 SpringBoot整合JPA,配置多数据库,希望对大家有所帮助。
Java面试手册PDF下载:点击下载最全Java面试手册
写在前面
SpringBoot创建项目非常方便,而且进行数据访问抛弃了很多繁琐的配置,我前面写的系列博文中,有教大家如何使用SpringBoot进行数据访问,里面谈到了整合JDBC、MyBatis以及JPA。我自己实际开发中,如果没有什么要求限制的话,比较习惯使用JPAJava面试手册进行数据访问,所以在这里,我专门编写一篇博文,来教如何使用SpringBoot整合JPA,进行多数据库的配置,如果有帮助,记得点个关注和点个赞哦。
准备
开始之前呢,我们需要先创建项目啦,创建项目使用的是Idea的Spring Initializr进行创建,选择SpringBoot场景的时候,勾选Web、Spring Data JPA、MySQL Driver三个就可以了,如下,然后项目创建成功。
主配置文件
如果我们只是进行一个数据库的访问,我们只需要对数据库进行简单的配置,提供相应账号和密码就可以了,不过多个数据库也不是很麻烦,也就是相当于多一份配置内容出来而已,所有配置内容如下
application.properties
#数据库统一配置
spring.jpa.hiJava面试手册bernate.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 MapString, 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 MapString, 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 MapString, 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的序列化格式,生成出来的还是要增改(当然啦,你可以直接去更改实体类生成的模板,没错是可以改的,具体怎么改我这里就不赘述了,自己百度就可以知道),我就来说手动创建,手动创建的好处就是能够对知识点进行更加深入的掌握,当然啦,敲起来比较费时间。
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;
}
}
写到这里,就要说一下前面主配置文件里面的一些配置是什么了,如下
它还有其他属性,如下:
- dd编程电子书汇总l-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 JpaRepositoryUser, 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 JpaRepositoryUserq, 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","aa@126.com", "aa", formattedDate));
userPrimaryPository.save(new User("bb", "bb123456","bb@126.com", "bb", formattedDate));
userSecondaryPository.save(new Userq("cc", "cc123456","cc@126.com", "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","ff@126.com", "ff", formattedDate);
Userq userq=new Userq("ff", "ff123456","ff@126.com", "ff", formattedDate);
userPrimaryPository.findAll();
userSecondaryPository.findById(3l);
userSecondaryPository.save(userq);
user.setId(2l);
userPrimaryPository.delete(user);
userPrimaryPository.count();
userSecondaryPository.findById(3l);
}
@Test
void contextLoads() {
}
}
> 时间不一定能证明很多东西,但是一定能看透很多东西。坚信自己的选择,不动摇,使劲跑,明天会更好。