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

相关文章

Java方法重载与重写之同名方法的双面魔法(最新整理)

《Java方法重载与重写之同名方法的双面魔法(最新整理)》文章介绍了Java中的方法重载Overloading和方法重写Overriding的区别联系,方法重载是指在同一个类中,允许存在多个方法名相同... 目录Java方法重载与重写:同名方法的双面魔法方法重载(Overloading):同门师兄弟的不同绝

Spring配置扩展之JavaConfig的使用小结

《Spring配置扩展之JavaConfig的使用小结》JavaConfig是Spring框架中基于纯Java代码的配置方式,用于替代传统的XML配置,通过注解(如@Bean)定义Spring容器的组... 目录JavaConfig 的概念什么是JavaConfig?为什么使用 JavaConfig?Jav

Java数组动态扩容的实现示例

《Java数组动态扩容的实现示例》本文主要介绍了Java数组动态扩容的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录1 问题2 方法3 结语1 问题实现动态的给数组添加元素效果,实现对数组扩容,原始数组使用静态分配

Java中ArrayList与顺序表示例详解

《Java中ArrayList与顺序表示例详解》顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构,:本文主要介绍Java中ArrayList与... 目录前言一、Java集合框架核心接口与分类ArrayList二、顺序表数据结构中的顺序表三、常用代码手动

JAVA项目swing转javafx语法规则以及示例代码

《JAVA项目swing转javafx语法规则以及示例代码》:本文主要介绍JAVA项目swing转javafx语法规则以及示例代码的相关资料,文中详细讲解了主类继承、窗口创建、布局管理、控件替换、... 目录最常用的“一行换一行”速查表(直接全局替换)实际转换示例(JFramejs → JavaFX)迁移建

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

JAVA线程的周期及调度机制详解

《JAVA线程的周期及调度机制详解》Java线程的生命周期包括NEW、RUNNABLE、BLOCKED、WAITING、TIMED_WAITING和TERMINATED,线程调度依赖操作系统,采用抢占... 目录Java线程的生命周期线程状态转换示例代码JAVA线程调度机制优先级设置示例注意事项JAVA线程

JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)

《JavaWeb项目创建、部署、连接数据库保姆级教程(tomcat)》:本文主要介绍如何在IntelliJIDEA2020.1中创建和部署一个JavaWeb项目,包括创建项目、配置Tomcat服务... 目录简介:一、创建项目二、tomcat部署1、将tomcat解压在一个自己找得到路径2、在idea中添加

Java使用Spire.Doc for Java实现Word自动化插入图片

《Java使用Spire.DocforJava实现Word自动化插入图片》在日常工作中,Word文档是不可或缺的工具,而图片作为信息传达的重要载体,其在文档中的插入与布局显得尤为关键,下面我们就来... 目录1. Spire.Doc for Java库介绍与安装2. 使用特定的环绕方式插入图片3. 在指定位

springboot的controller中如何获取applicatim.yml的配置值

《springboot的controller中如何获取applicatim.yml的配置值》本文介绍了在SpringBoot的Controller中获取application.yml配置值的四种方式,... 目录1. 使用@Value注解(最常用)application.yml 配置Controller 中