springboot整合springdata jpa 与多数据源

2023-11-11 09:41

本文主要是介绍springboot整合springdata jpa 与多数据源,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

springboot整合springdata jpa 与多数据源

1.整合springdata jpa

1.建库

新建一个数据库 命名为 jpa

不用建表,我们通过构建实体类来自动生成表

2.引入依赖

(默认是web项目,以提前引入了web和thymeleaf的starter)

          <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.9</version></dependency>

3.数据库配置

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql:///jpa?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123
#以上数据库的基本信息
spring.jpa.show-sql=true
#开启控制台打印生成sql过程
spring.jpa.database=mysql
#项目启动时根据实体类的值自动更新数据库中的表,可选有create,create-drop,validate,no
spring.jpa.hibernate.ddl-auto=update
#规定使用数据库的官方语言是MySQL57Dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

4.entity层

@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "t_book")
public class Book {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Integer id;@Column(name = "book_name", nullable = false)private String bookName;private String author;private Float price;
//@Transient 代表生成表时,不生成此字段@Transientprivate String description;
}

5.dao层

public interface BookDao extends JpaRepository<Book, Integer> {//    根据作者名字获取书的集合List<Book> getBooksByAuthorStartingWith(String author);//  根据提供价格大于的获取书的集合List<Book> getBooksByPriceGreaterThan(Float price);//获取编号最大的书 ,nativeQuery 开启原生sql@Query(value = "select * from t_book where id=(select max(id) from t_book)", nativeQuery = true)Book getMaxIdBook();//    :id ,:author 用来做参数绑定,这里使用的的列名是属性名 不是数据库中列的名字//采用此种方式,一定要写 @param@Query("select b from t_book b where b.id>:id and b.author=:author")List<Book> getBookByIdAndAuthor(@Param("author") String author, @Param("id") Integer id);//?1 ,?2是另一种参数声明方式,但要注意参数的顺序@Query("select b from t_book b where b.id<?2 and b.bookName like %?1%")List<Book> getBooksByIdAndName(String name, Integer id);//    对于update操作,需要添加@Modifying注解并添事务(可以在service实现层方法上加上 @Transactional(isolation = Isolation.READ_COMMITTED))@Modifying@Query(value = "update t_book b set b.book_name=:newName where b.id =:id", nativeQuery = true)void updateBookName(@Param("newName") String newName,@Param("id") Integer id);}

1.使用springdata jpa ,编写dao层使,我们可以直接继承 JpaRepository<实体类class ,主键类型> ,其中提供了一些基本的增删改善,分页查询,排序查询等

2.在springdata jpa中,只要方法的名字符合既定规范,springdata就能分析出你的意图,从而可以避免自己定义sql.也就是根据方法名字自动生成sql语句。我们可以在ecplice或idea中开启方法提示功能,那么输入find 或get 就会有很多的提示方法。当然我们也可以去看官方文档的命名规则,这里我们就不陈述了。

3.如果既定规范不能满足要求,那么 可以采用编写原生sql的方法。例如第10行代码,加上 nativeQuery = true

,就支持原生sql了。

4.传递参数 有两个方式,在上述代码中已经写明。

5.对于修改操作,需要添加@Modifying注解并添事务(可以在service实现层方法上加上 @Transactional(isolation = Isolation.READ_COMMITTED))。

6.service层

@Service
public class BookService {@AutowiredBookDao bookDao;public void addBook(Book book) {bookDao.save(book);}public Page<Book> getBookByPage(Pageable pageable) {return bookDao.findAll(pageable);}public List<Book> getBooksByAuthorStartingWith(String author) {return bookDao.getBooksByAuthorStartingWith(author);}public List<Book> getBooksByPriceGreaterThan(Float price) {return bookDao.getBooksByPriceGreaterThan(price);}public Book getMaxIdBook() {return bookDao.getMaxIdBook();}public List<Book> getBookByIdAndAuthor(String author, Integer id) {return bookDao.getBookByIdAndAuthor(author, id);}public List<Book> getBooksByIdAndName(String name, Integer id) {return bookDao.getBooksByIdAndName(name, id);}@Transactional(isolation = Isolation.READ_COMMITTED)public  void  updateBookName(String newName,Integer id){bookDao.updateBookName(newName,id);}

7.controller层

@RestController
public class BookController {@AutowiredBookService bookService;@GetMapping("/findAll")public void findAll() {
//        首先通过PageRequest.of方法获得一个PageRequest对象,arm1 代表第几页(从0开始),arm2代码每页显示的条数PageRequest pageable = PageRequest.of(1, 3);Page<Book> page = bookService.getBookByPage(pageable);System.out.println("总页数:" + page.getTotalPages());System.out.println("总记录数:" + page.getTotalElements());System.out.println("查询结果:" + page.getContent());System.out.println("当前页数:" + (page.getNumber() + 1));System.out.println("当前页记录数:" + page.getNumberOfElements());System.out.println("每页记录数:" + page.getSize());}
}

这里只做一个对分页查询的方法。数据库数据可以自己添加。

2.Jpa多数据源

1.建库

新建两个数据库 muljpa1muljpa2,不用建表,我们通过构建实体类来自动生成表.

2.引入依赖

依赖与上面差不多,只需要改变一个druid的依赖

        <dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency>

3,数据库连接和jpa相关配置

配置两个数据源,区别主要是数据库不同。

server.port=8081
#数据源1
spring.datasource.one.password=123
spring.datasource.one.username=root
spring.datasource.one.url=jdbc:mysql:///muljpa1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
#数据源2
spring.datasource.two.password=123
spring.datasource.two.username=root
spring.datasource.two.url=jdbc:mysql:///muljpa2?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
#jpa相关配置
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57InnoDBDialect
spring.jpa.properties.database=mysql
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.show-sql= true

4.配置数据源

创建DataSourceConfig配置数据源,根据application.properties中的配置生成两个数据源

@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties("spring.datasource.one")@PrimaryDataSource dsOne() {return DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.two")DataSource dsTwo() {return DruidDataSourceBuilder.create().build();}
}

@DataSourceConfig 中提供两个数据源:dsOne 和dsTwo,默认方法名即为实例名。

@ConfigurationProperties 注解表示使用不同前缀的配置文件来创建不同的DataSource实例。

5.实体类和两个dao(分成两个包,一个是dao1,一个是dao2)

在这里插入图片描述

@Entity(name = "t_user")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Integer id;private String name;private String gender;private Integer age;
}
public interface UserDao extends JpaRepository<User,Integer> {
}
public interface UserDao2 extends JpaRepository<User,Integer> {
}

6.创建JPA配置

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.hz.muljpa.dao1",entityManagerFactoryRef = "entityManagerFactoryBeanOne",transactionManagerRef = "platformTransactionManagerOne")
public class JpaConfigOne {@Resource(name = "dsOne")DataSource dsOne;@AutowiredJpaProperties jpaProperties;@Bean@PrimaryLocalContainerEntityManagerFactoryBean entityManagerFactoryBeanOne(EntityManagerFactoryBuilder builder) {return builder.dataSource(dsOne).properties(jpaProperties.getProperties()).packages("com.hz.muljpa.entity").persistenceUnit("pu1").build();}@BeanPlatformTransactionManager platformTransactionManagerOne(EntityManagerFactoryBuilder builder) {LocalContainerEntityManagerFactoryBean factoryOne = entityManagerFactoryBeanOne(builder);return new JpaTransactionManager(factoryOne.getObject());}
}

1.使用@EnableTransactionManagement注解来进行JPA的配置,该注解主要配置三个属性,basePackages用来指定repository所在的位置,entityManagerFactoryRef用来指定用来指定实体类管理工厂Bean的名字(就是上述代码,第一个方法的名字),transactionManagerRef用来指定事务管理器的引用名称,(就是上述代码方法的第二个名字)。

2.LocalContainerEntityManagerFactoryBean 创建该实例来提供entityManager实例,在创建该类过程中,首先设置配置源(dsOne),然后设置jpA的相关配置,在设置实体类所在的位置,最后配置实体化单元,若项目中只有一个EntityManagerFactory,则persistenceUnit可以省略,若有多个,则必须明确指定,对于我们配置多数据来说,肯定是多个,一会我们还要在创建一个jpaconfigTwo类。

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.hz.muljpa.dao2",
entityManagerFactoryRef = "entityManagerFactoryBeanTwo",
transactionManagerRef = "platformTransactionManagerTwo")
public class JpaConfigTwo {@Resource(name = "dsTwo")DataSource dsTwo;@AutowiredJpaProperties jpaProperties;@BeanLocalContainerEntityManagerFactoryBean entityManagerFactoryBeanTwo(EntityManagerFactoryBuilder builder) {return builder.dataSource(dsTwo).properties(jpaProperties.getProperties()).packages("com.hz.muljpa.entity").persistenceUnit("pu2").build();}@BeanPlatformTransactionManager platformTransactionManagerTwo(EntityManagerFactoryBuilder builder) {LocalContainerEntityManagerFactoryBean factoryTwo = entityManagerFactoryBeanTwo(builder);return new JpaTransactionManager(factoryTwo.getObject());}
}

注意这两个类中都有LocalContainerEntityManagerFactoryBean被创建,但只有一个上面加了 @Primary注解,代表该实例优先使用。

7.创建controller

@RestController
public class UserController {@AutowiredUserDao userDao;@AutowiredUserDao2 userDao2;@GetMapping("/testmuijpa")public void test1() {User u1 = new User();u1.setAge(55);u1.setName("鲁迅");u1.setGender("男");userDao.save(u1);User u2 = new User();u2.setAge(80);u2.setName("泰戈尔");u2.setGender("男");userDao2.save(u2);}
}

8.测试

localhost:8081/testmuijpa

查看数据库中有没有数据。

("/testmuijpa")
public void test1() {
User u1 = new User();
u1.setAge(55);
u1.setName(“鲁迅”);
u1.setGender(“男”);
userDao.save(u1);
User u2 = new User();
u2.setAge(80);
u2.setName(“泰戈尔”);
u2.setGender(“男”);
userDao2.save(u2);
}
}


### 8.测试localhost:8081/testmuijpa查看数据库中有没有数据。

这篇关于springboot整合springdata jpa 与多数据源的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/389175

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟&nbsp;开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚&nbsp;第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定