spring boot 整合JPA多数据源
上个文章介绍了spring boot在使用Mybatis持久化技术的时候如何使用多数据源,今天再补充一个使用spring data jpa实现多数据源的使用情况,JPA是一套数据库持久化规范,或者称之为一套接口,可以类比于Java中的接口,既然有接口就有实现,Hibernate就是其中的一个实现。
本例为查询两个数据库test1和test2中的用户信息,可以共用一个实体类,当然如果有需要也可以操作不同的实体类。
1.项目的整体结构如下:
2.pom文件说明
<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>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
<version>5.1.27</version>
</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>
pom文件中主要是需要锁定数据库驱动的版本,因为要使用多数据源,所以需要导入druid,因为后面要使用DruidDataSourceBuilder来初始化数据源。而spring-boot默认使用的HikariCP是不支持的。
3.项目配置文件
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.one.url=jdbc:mysql://localhost:3306/test1
spring.datasource.one.username=root
spring.datasource.one.password=123456 spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.two.url=jdbc:mysql://localhost:3306/test2
spring.datasource.two.username=root
spring.datasource.two.password=123456 spring.jpa.properties.hibernate.ddl-auto=update //每次启动项目如果发现实体类类更新则对应着更新表结构
spring.jpa.properties.show-sql=true //在控制台打印sql语句
spring.jpa.properties.database=mysql
spring.jpa.properties.database-platform=mysql
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
注意两个数据库的配置信息的前缀不一样,后面将根据配置信息的前缀对数据源进行初始化,还有就是关于JPA的属性配置都需要在spring.jpa后面增加properties关键字,为什么这样做呢?是因为后面配置JPA的时候
不仅需要数据源还需要JpaProperties对象,看一下JpaProperties类:
@ConfigurationProperties(prefix = "spring.jpa")
public class JpaProperties { /**
* Additional native properties to set on the JPA provider.
*/
private Map<String, String> properties = new HashMap<>();
我们自己定义的属性存到名为properties的HashMap中,再加上类的前缀为spring.jpa。所以想要spring boot自己读取需要按照其规则注入即为spring.jpa.properties。
4.用户类
@Entity(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
private String address;
省略get set 方法................
}
用户类比较简单,只有几个基本的属性。@Entity注解的name的值对应数据库的表名。
5.配置数据源
@Configuration
public class DataSourceConfig {
@Bean
@ConfigurationProperties(prefix = "spring.datasource.one")
@Primary
DataSource dsOne() {
return DruidDataSourceBuilder.create().build();
}
//primary注解表示某个类存在多个实例时优先使用当前bean
@Bean
@ConfigurationProperties(prefix = "spring.datasource.two")
DataSource dsTwo() {
return DruidDataSourceBuilder.create().build();
}
}
既然是多数据源那么肯定需要自己配置多个数据源的情况,注意这里需要增加@Primary注解,其含义就是表示某个类存在多个实例时优先使用当前实例,如果不加项目会报错,多个bean只能加一个,意思是dsTwo同样返回的DataSource,但是dsOne加了,其他的就不能再加了。
6.JPA配置
(1)第一个JPA的配置
@Configuration
@EnableJpaRepositories(basePackages = "com.hopec.jpa2.repository1",transactionManagerRef = "platformTransactionManager1",entityManagerFactoryRef = "localContainerEntityManagerFactoryBean1")
public class JpaConfigOne { @Autowired
@Qualifier(value = "dsOne")
DataSource dsOne; @Autowired
JpaProperties jpaProperties; @Bean
@Primary //相应的需要添加上此注解
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean1(EntityManagerFactoryBuilder factoryBuilder){
return factoryBuilder.dataSource(dsOne) //设置数据源
.properties(jpaProperties.getProperties()) //获取配置信息
.packages("com.hopec.jpa2.model") //设置扫描的实体类的包
.persistenceUnit("name1") //持久化单元的名称 不同的对象的名字不同就可以
.build();
}
@Bean
PlatformTransactionManager platformTransactionManager1(EntityManagerFactoryBuilder factoryBuilder){
LocalContainerEntityManagerFactoryBean bean = localContainerEntityManagerFactoryBean1(factoryBuilder);
return new JpaTransactionManager(bean.getObject());
}
}
(2)第二个JPA的配置
@Configuration
@EnableJpaRepositories(basePackages = "com.hopec.jpa2.repository2",transactionManagerRef = "platformTransactionManager2",entityManagerFactoryRef = "localContainerEntityManagerFactoryBean2")
public class JpaConfigTwo {
@Autowired
@Qualifier(value = "dsTwo")
DataSource dsTwo;
@Autowired
JpaProperties jpaProperties;
@Bean
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean2(EntityManagerFactoryBuilder factoryBuilder){
return factoryBuilder.dataSource(dsTwo) //设置数据源
.properties(jpaProperties.getProperties()) //获取配置信息
.packages("com.hopec.jpa2.model") //设置扫描的实体类的包
.persistenceUnit("name2") //持久化单元的名称 不同的对象的名字不同就可以
.build();
}
@Bean
PlatformTransactionManager platformTransactionManager2(EntityManagerFactoryBuilder factoryBuilder){
LocalContainerEntityManagerFactoryBean bean = localContainerEntityManagerFactoryBean2(factoryBuilder);
return new JpaTransactionManager(bean.getObject());
}
}
以上两个JPA的配置主要是注意包名路径的对应一定要保持一致。
7.持久层
(1)第一个持久层
public interface UserRepository1 extends JpaRepository<User,Integer>{ @Query(value = "select * from users where id=(select max(id) from users)",nativeQuery = true)
User findMaxIdUser(); //自定义的属性如何进行匹配
@Query(value = "insert into users(name,address) values(?1,?2)",nativeQuery = true)
@Modifying
@Transactional
Integer addUser1(String name,String author); @Query(value = "insert into users(name,address) values(:name,:address)",nativeQuery = true)
@Modifying
@Transactional
Integer addUser2(@Param("name") String name, @Param("address") String address); //自定义的对象与sql语句进行匹配
@Query(value = "insert into users(name,address) values(:#{#user.name},:#{#user.address})",nativeQuery = true)
@Modifying
@Transactional
Integer addUser3(@Param("user") User user);
这里其实不需要写这么复杂的,单纯查询所有用户信息,JpaRepository里面已经实现了,这里自定义查询和保存用户方法是为了多学习一点如何在JPA中自定义查询方法以及参数对应,也就是将自定义的方法中的普通参数或者对象与@Query中原生SQL的属性对应起来。
(2)第二个持久层
public interface UserRepository2 extends JpaRepository<User,Integer>{
}
实际上在本例中是这样的,不需要第一个那么复杂,第一个只是作为扩展的参考。
8.测试
@Test
public void test1(){
List<User> users = userRepository1.findAll();
System.out.println(users);
List<User> users1 = userRepository2.findAll();
System.out.println(users1);
}
@Test
public void test2(){
User user = new User();
user.setName("123");
user.setAddress("石家庄");
Integer r = userRepository1.addUser3(user);
System.out.println(r);
}
测试结果:
最后大功告成!
spring boot 整合JPA多数据源的更多相关文章
- Spring Boot2 系列教程(二十五)Spring Boot 整合 Jpa 多数据源
本文是 Spring Boot 整合数据持久化方案的最后一篇,主要和大伙来聊聊 Spring Boot 整合 Jpa 多数据源问题.在 Spring Boot 整合JbdcTemplate 多数据源. ...
- Spring Boot 整合 JPA 使用多个数据源
介绍 JPA(Java Persistence API)Java 持久化 API,是 Java 持久化的标准规范,Hibernate 是持久化规范的技术实现,而 Spring Data JPA 是在 ...
- spring boot 系列之四:spring boot 整合JPA
上一篇我们讲了spring boot 整合JdbcTemplate来进行数据的持久化, 这篇我们来说下怎么通过spring boot 整合JPA来实现数据的持久化. 一.代码实现 修改pom,引入依赖 ...
- Spring Boot整合JPA、Redis和Swagger2
好久没有总结了,最近也一直在学习.今天就把spring boot与其它技术的整合做个小总结,主要是jpa.redis和swagger2.公司里有用到这些,整合起来也很简单. 首先,新建一个Spring ...
- Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源
多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问 ...
- Spring Boot2 系列教程(二十四)Spring Boot 整合 Jpa
Spring Boot 中的数据持久化方案前面给大伙介绍了两种了,一个是 JdbcTemplate,还有一个 MyBatis,JdbcTemplate 配置简单,使用也简单,但是功能也非常有限,MyB ...
- Spring Boot从入门到精通之:二、Spring Boot整合JPA
springboot-jpa 开发工具 系统: windows10 开发工具: Intellij IDEA 2018.2.6 springboot: 2.0.6.RELEASE jdk: 1.8.0_ ...
- spring boot - 整合jpa
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring- ...
- spring boot 整合JPA bean注入失败
有时候报的错误让你匪夷所思,找错误得学会找根.源头在哪里? 比如:我们刚开始看的错误就是 org.springframework.beans.factory.UnsatisfiedDependency ...
随机推荐
- 10秒钟理解react生命周期
慎点!这是一篇很水很水的文章, 抄自react中文文档, 本文详细介绍了react生命周期函数执行顺序, 以及各生命周期函数的含义和具体作用. 不同阶段生命周期函数执行顺序 挂载(Mounting) ...
- jquery 取得select选中的值
1.取得选中的值 jQuery("#select").val();是取得选中的值 2.取得的文本 jQuery("#select option:selected&quo ...
- 死磕 java同步系列之终结篇
简介 同步系列到此就结束了,本篇文章对同步系列做一个总结. 脑图 下面是关于同步系列的一份脑图,列举了主要的知识点和问题点,看过本系列文章的同学可以根据脑图自行回顾所学的内容,也可以作为面试前的准备. ...
- tiki-graph_formula.php代码执行漏洞复现(或许??)
1.不知道从哪里翻出来的虚拟机镜像(不知道甚么时候出现在磁盘里面的) 打开配置一下是tikiwiki这个东西 2.遇到陌生的玩意总是忍不住好奇心的,打开nikto扫描一下,发现有些奇怪的东西 本来没抱 ...
- 手把手带你利用Ribbon实现客户端的负载均衡
之前的文章<SpringCloud搭建注册中心与服务注册>介绍了注册中心的搭建和服务的注册,本文将介绍下服务消费者通过Ribbon调用服务实现负载均衡的过程. 本文目录 一.Ribbon服 ...
- Java匹马行天下之教你用学汉语式方法学编程语言
Java匹马行天下之教你用学汉语式方法学编程语言 前言: 前段时间接连更新了带小白从入门到了解的几篇博客: <Java匹马行天下之编程常识知多少> <Java匹马行天下之走进编程的殿 ...
- Rust到底值不值得学--Rust对比、特色和理念
前言 其实我一直弄不明白一点,那就是计算机技术的发展,是让这个世界变得简单了,还是变得更复杂了. 当然这只是一个玩笑,可别把这个问题当真. 然而对于IT从业者来说,这可不是一个玩笑.几乎每一次的技术发 ...
- springboot使用百度富文本UEditor遇到的问题一览(springboot controller中request.getInputStream无法读取)
先吐槽一下UEditor作为一个前端的js类库,非要把4种后端的代码给出来,而实际生产中用的框架不同,其代码并不具有适应性.(通常类似其它项目仅仅是给出数据交互的规范.格式,后端实现就可以自由定制) ...
- python自动化测试三部曲之request+django实现接口测试
国庆期间准备写三篇博客,介绍和总结下接口测试,由于国庆期间带娃,没有按照计划完成,今天才完成第二篇,惭愧惭愧. 这里我第一篇博客的地址:https://www.cnblogs.com/bainianm ...
- unittest中的方法调用时报错ValueError: no such test method in <class 'mytestcase.MyTestCase'>: runTest
调用unittest中的方法时报错: ValueError: no such test method in <class 'mytestcase.MyTestCase'>: runTest ...