写在前面 SpringBoot创建项目非常方便,而且进行数据访问抛弃了很多繁琐的配置,我前面写的系列博文中,有教大家如何使用SpringBoot进行数据访问,里面谈到了整合JDBC、MyBatis以及JPA。我自己实际开发中,如果没有什么要求限制的话,比较习惯使用JPA进行数据访问,所以在这里,我专门编写一篇博文,来教如何使用SpringBoot整合JPA,进行多数据库的配置,如果有帮助,记得点个关注和点个赞哦 。
准备 开始之前呢,我们需要先创建项目啦,创建项目使用的是Idea的Spring Initializr进行创建,选择SpringBoot场景的时候,勾选Web、Spring Data JPA、MySQL Driver三个就可以了,如下,然后项目创建成功。
主配置文件 如果我们只是进行一个数据库的访问,我们只需要对数据库进行简单的配置,提供相应账号和密码就可以了,不过多个数据库也不是很麻烦,也就是相当于多一份配置内容出来而已,所有配置内容如下
application.properties
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #数据库统一配置 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: 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: spring.datasource.secondary.username=root spring.datasource.secondary.password=123456 spring.datasource.secondary.driver-class -name =com.mysql.jdbc.Driver
配置类 我们都知道,我们在配置文件中写的配置,需要我们通过配置类的注入,覆盖掉默认的配置,这样才会生效,所以,我们能够想到,既然是需要使用多个数据库,对应的自然会有多个数据库的相关配置类(这篇博文的示例中,我使用两个数据库,所以有两个数据配置类)
我们知道,我们首先在只配置类中编写两个配置数据库的组件,然后分别其组件名,具体内容如下。
DataSourceConfig.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 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的序列化格式,生成出来的还是要增改(当然啦,你可以直接去更改实体类生成的模板,没错是可以改的,具体怎么改我这里就不赘述了,自己百度就可以知道),我就来说手动创建,手动创建的好处就是能够对知识点进行更加深入的掌握,当然啦,敲起来比较费时间。
User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 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层
1 2 3 4 5 6 7 8 9 10 11 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) ; }
1 2 3 4 5 6 7 8 9 10 11 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) ; }
测试 到此,我们的多数据库配置流程到此结束,最后就是测试阶段了,我们来验证一下我们的配置是否有用。测试类的内容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 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 () { } }
Author:
DengBoCong
Permalink:
http://dengbocong.cn/Spring-Boot/3ba32bdaaf99/
License:
Licensed under the Apache License, Version 2.0 (the "License")
Slogan:
Stay hungry, Stay foolish.