Writing in the front
SpringBoot is very convenient to create projects, and data access without a lot of tedious configuration. In my previous series of posts, I have taught you how to use SpringBoot for data access, which talks about integrating JDBC, MyBatis, and JPA. I am used to using JPA for data access if there is no requirement, so here I am writing a blog post to teach how to use SpringBoot to integrate JPA and configure multiple databases. If it is helpful, please click follow and click like oh.
To prepare
Spring Initializr of Idea is used to create the project. When selecting the SpringBoot scenario, check Web, Spring Data JPA, MySQL Driver, as follows: Then the project is created successfully.
Master profile
If we only have one database access, we only need to configure the database simply, providing the corresponding account and password, but multiple databases are not very troublesome, that is, it is equivalent to one more configuration content, all configuration content is as follows
application.properties
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# master database spring. The 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 # vice database spring. The 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
Copy the code
The configuration class
As we all know, in the configuration file we write configuration, we need through the injection configuration class, override the default configuration, this will only take effect, so, we can think of, since it is need to use multiple databases, the corresponding natural there will be multiple database related configuration class (this blog example, I use two databases, so there are two data configuration class)
As we know, we first write two components that configure the database in the configure only class, and then their component names, as follows.
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(a){
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@ConfigurationProperties("spring.datasource.secondary")
public DataSource secondDataSource(a){
return DataSourceBuilder.create().build();
}
@Bean(name = "vendorProperties")
public Map<String, Object> getVendorProperties(a) {
return hibernateProperties.determineHibernateProperties(
jpaProperties.getProperties(), newHibernateSettings()); }}Copy the code
Then we wrote the configuration class for the two databases, the code is very similar, I believe you knock once, can feel something.
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. The Primary "} / / the location of the Dao layer)
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")// The location of the entity class
.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 newJpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); }}Copy the code
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 newJpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); }}Copy the code
Entity class
First of all, I put the directory structure of a entity class on this first, convenient to write back, and then the said entity class created, here you can use the Idea to help us reverse generating entity class, which is in accordance with the already created good database tables in the database, automatically generated entity class, generated entity class, but this way is not in conformity with the now write JPA serialization format, Change generated will increase (of course, you can go directly to change the entity class generation templates, that’s right, you can change, how to change I will not go into here, baidu can know), I will manually create, manually create benefits is to be able to to further grasp of knowledge, of course, to knock up more time consuming.
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(a) {}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(a) {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUserName(a) {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord(a) {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getEmail(a) {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNickName(a) {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getRegTime(a) {
return regTime;
}
public void setRegTime(String regTime) {
this.regTime = regTime; }}Copy the code
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(a) {}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(a) {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getUserName(a) {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord(a) {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getEmail(a) {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getNickName(a) {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getRegTime(a) {
return regTime;
}
public void setRegTime(String regTime) {
this.regTime = regTime; }}Copy the code
What are some of the configurations in the main configuration file
It has other properties as follows:
- Ddl-auto :create—- Each time you run the program, no table will be created and data in the table will be cleared
- Ddl-auto :create-drop—- Clears the table at the end of each program
- Ddl-auto :update—- Every time you run the program, no table will be created, and data in the table will not be cleared, but only updated
- Ddl-auto :validate—- The program will check whether the data and database field types are the same. If they are different, an error will be reported
Dao layer
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);
}
Copy the code
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);
}
Copy the code
test
This concludes our multi-database configuration process, and it’s time for the testing phase to verify that our configuration works. The test class has the following contents:
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(a) 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(a) throws Exception {
userPrimaryPository.deleteAll();
userSecondaryPository.deleteAll();
}
@Test
public void testBaseQuery(a) {
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(a) {}}Copy the code