SpringBoot 整合 JPA

前言:之前一直用的都是Mybatis,最近由于工作原因,要使用JPA,因此整理一下学习笔记防止忘记,也希望能够帮到需要使用这个技术的人

1. Spring Data JPA 概念

  • JPA(Java Persistence API,Java持久层api) 是一套ORM规范,使得应用程序以统一的方式访问持久层
  • JPA 是 Hibernate 的一个抽象,从功能上来说是 Hibernate 的一个子集
  • Spring Data JPA 是 Spring 的一个子项目,用于简化数据库访问,支持 nosql(redis,mongoDB) 和关系型数据库(jdbc,jpa)存储

2. 使用

2.1 引入JPA依赖

  • 创建SpringBoot项目,引入 JPA,MySQL,Web依赖,和数据库连接池依赖
  • 因为我本地的数据库版本是5.7,因此引入mysql依赖的时候标注version 版本号
<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>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    <version>5.1.28</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

2.2 配置连接数据库参数和jpa参数

  • 在resources 目录下的 application.properties 文件中
# 配置数据库连接池及数据库驱动
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 配置mysql的链接信息
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/jpaDemo?useUnicode=true&characterEncoding=utf-8

#jpa
spring.jpa.database=mysql
spring.jpa.database-platform=mysql
#是否自动生成dd
spring.jpa.generate-ddl=true
# 生成方式 update 运行时在数据库生成表,若有更新则去更新数据
spring.jpa.hibernate.ddl-auto=update
# 格式化sql语句
spring.jpa.properties.hibernate-format_sql=true
# 控制台展示 JPA 框架生成的sql语句
spring.jpa.show-sql=true
# 解决 hibernate multiple merge 问题
spring.jpa.properties.hibernate.event.merge.entity_copy_observer = allow  
# 使用JPA 创建表时,默认使用的存储引擎是MyISAM,通过指定数据库版本,可以使用InnoDB
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

2.3 基本使用

2.3.1 创建实体类

package com.bisnow.demo.pojo;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String bookname;

    private String author;

    get + set + toString
}

2.3.2 对数据库操作

需要一个接口继承JpaRepository<实体类名,id类型>,在接口中有现成的方法或者自定义方法

package com.bisnow.demo.repository;

import com.bisnow.demo.pojo.Book;
import org.springframework.data.jpa.repository.JpaRepository;

public interface BookRepository extends JpaRepository<Book,Integer> {
}
  • 运行建表插入数据

在这里插入图片描述

2.3.3 测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

    @Autowired
    BookRepository bookRepository;

    @Test
    public void test1(){
        List<Book> books = bookRepository.findAll();
        books.forEach(b-> System.out.println(b));
    }
}

在这里插入图片描述

2.4 JPA 实体类常用注解

JPA项目运行的时候会根据实体类自动的去数据库建表

2.4.1 @Entity

表示这是一个实体类,默认情况下,类名就是表名

2.4.2 @Table

@Entity并列使用,自定义数据库表名

2.4.3 @Id

标注主键

2.4.4 @GeneratedValue

  • 同@Id 共同使用,标注主键的生成策略,通过strategy属性指定
  • IDENTITY 采用数据库ID自增长的方式产生主键,oracle不支持
  • AUTO JPA自动选择合适的策略,是默认选项
  • SEQUENCE Oracle不支持主键自增长,其提供了一种叫做"序列(sequence)"的机制生成主键,GenerationType.SEQUENCE就可以作为主键生成策略,不足之处是只能使用于部分支持序列的数据库(Oracle,PostgreSQL,DB2),一般与@SequenceGenerator一起使用,@SequenceGenerator注解指定了生成主键的序列,不指定序列时自动生成一个序列SEQ_GEN_SEQUENCE
  • TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略更易于做数据库移植。
package com.bisnow.demo.pojo;

import javax.persistence.*;

@Entity 
@Table(name = "t_person")  
public class Person {

    @Id 
    
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

    private Integer age;

    get + set 方法
}
  • 此时运行项目,可以在控制台看到建表语句,并且可以在数据库中查看表及表关系

在这里插入图片描述

  • 删除之间建好的表。若将 @Table 属性注释,更改 @GeneratedValue 策略,则
@GeneratedValue(strategy = GenerationType.IDENTITY)

在这里插入图片描述

2.4.5 @Column

用来描述实体属性对应数据表字段,其中name、nullable、unique、length属性用的较多,分别用来描述字段名、字段是否可以null、字段是否唯一、字段的长度,实际开发中需要用其他属性时,可从参考文献获取api文档地址,查阅文档配置。

@Column(length = 400,name = "p_name",nullable = false,unique = true)
private String name;

此时建表能看到

在这里插入图片描述

2.4.6 @Transient

在数据库中建表的时候忽略该属性

@Transient
private String name;

在这里插入图片描述

2.4.7 @OneToOne 单向关联

两个实体一对一关系,例如人和身份证就是一对一的关系

查询包含关联属性的实体对象时,能同步从数据库中获取关联的实体对象,反过来不行

  • 创建两个实体类 Person,Card
package com.bisnow.demo.pojo;

import javax.persistence.*;

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

    @OneToOne
    //关联的字段 name属性可以标注表中字段的值
    @JoinColumn(name = "card_id")
    private Card card;

    get + set + toString ...
}
package com.bisnow.demo.pojo;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Card {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String num;

    get + set + toString ... 
}
  • 创建repository 接口,测试查询
    @Autowired
    PersonRepository personRepository;

    @Autowired
    CardRepository cardRepository;

    @Test
    public void contextLoads() {
        Optional<Person> person = personRepository.findById(1);
        Person p = person.get();
        System.out.println(p);
        Optional<Card> card = cardRepository.findById(1);
        Card c = card.get();
        System.out.println(c);
    }

在这里插入图片描述

  • 此时可以看到,查询Person能同步获取到对应的Card,但是查询Card获取不到
  • 数据库中的表关系

在这里插入图片描述

2.4.8 @OneToMany和@ManyToOne 单向关联

两实体一对多关系,例如人和电话就是一对多关系,一个人可以有多个电话,一个电话只能属于一个人

2.4.8.1 @ManyToOne
  • 创建实体类 Person 和 Phone
package com.bisnow.demo.pojo;

import javax.persistence.*;

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

    get + set + toString ...
}

package com.bisnow.demo.pojo;

import javax.persistence.*;

@Entity
public class Phone {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private Integer number;

    @ManyToOne
    @JoinColumn(name = "person_id")
    private Person person;

    get + set + toString ...
}

  • 插入数据

在这里插入图片描述

  • 创建repository 接口,测试查询
    @Autowired
    PersonRepository personRepository;

    @Autowired
    PhoneRepository phoneRepository;

    @Test
    public void test2(){
        List<Person> all = personRepository.findAll();
        all.forEach(p-> System.out.println(p));
        List<Phone> all1 = phoneRepository.findAll();
        all1.forEach(p-> System.out.println(p));
    }

在这里插入图片描述

2.4.8.2 @OneToMany
  • 创建实体类 Person 和 Phone
package com.bisnow.demo.pojo;

import javax.persistence.*;

@Entity
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

    @OneToMany(cascade = CascadeType.MERGE,fetch = FetchType.EAGER)
    @JoinColumn(name = "phone_id")
    private List<Phone> phone;

    get + set + toString ...
}

package com.bisnow.demo.pojo;

import javax.persistence.*;

@Entity
public class Phone {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private Integer number;

    get + set + toString ...
}
  • 插入数据

在这里插入图片描述

  • 创建repository 接口,测试查询
    @Autowired
    PersonRepository personRepository;

    @Autowired
    PhoneRepository phoneRepository;

    @Test
    public void test2(){
        List<Person> all = personRepository.findAll();
        all.forEach(p-> System.out.println(p));
        List<Phone> all1 = phoneRepository.findAll();
        all1.forEach(p-> System.out.println(p));
    }

在这里插入图片描述

2.4.8.3 fetch属性指明数据抓取策略
  • EAGER即立即抓取
  • LAZY延迟加载
2.4.8.4 cascade属性指明级联特性
  • CascadeType.PERSIST:级联持久化操作,当将实体保存至数据库时,其对应的关联实体也会被保存至数据库
  • CascadeType.REMOVE:级联删除操作,从数据库删除当前实体时,关联实体也会被删除
  • CascadeType.DETACH:级联脱管,当前实体被ORM框架脱管,关联实体也被同步脱管,处于脱管状态的实体,修改操作不能持久化到数据库
  • CascadeType.MERGE:级联合并操作,实体数据改变时,会相应的更新Course中的数据
  • CascadeType.REFRESH:级联刷新,当前实体修改保存至数据库时,关联的实体状态会重新从数据库加载,忽略掉先前的状态
  • CascadeType.ALL:包含上述所有级联操作

2.4.9 @ManyToMany

多对多的实体关系,例如学生和所选课程的关系,一个学生可以选多个课程,一个课程可被多个学生选择

  • 创建实体类 Student 和 Course
@Entity
public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

    @ManyToMany(targetEntity = Course.class,fetch = FetchType.EAGER)
    private List<Course> courses;

    get + set + toString ...
}

@Entity
public class Course {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    private String name;

    get + set + toString
}
  • 插入数据

在这里插入图片描述

  • 创建repository 接口,测试查询
    @Autowired
    StudentRepository studentRepository;
    @Autowired
    CourseRepository courseRepository;

    @Test
    public void test3(){
        List<Student> all = studentRepository.findAll();
        System.out.println(all);
        List<Course> all1 = courseRepository.findAll();
        System.out.println(all1);
    }

在这里插入图片描述

2.5 对数据库操作

需要一个接口继承 JpaRepository<实体类名,id类型>,可在接口中写现有方法或者自定义的方法

  • 自定义方法规范

在这里插入图片描述

public interface BookRepository extends JpaRepository<Book,Integer> {

    List<Book> getBookByBooknameContains(String bookname);

    List<Book> getBookByIdGreaterThanAndAuthorEndsWith(Integer id,String author);

    //表示自定义的 dml 操作方法
    @Query(value = "select * from book where id = (select max(id) from book)",nativeQuery = true)
    Book getMaxIdBook();

    // 两种传参方式 使用 ?1 的方式不需要 @Param 注解
    // @Query(value = "select * from book where id > ?1",nativeQuery = true)
    @Query(value = "select * from book where id > :id",nativeQuery = true)
    List<Book> idGreaterThan(@Param("id") Integer id);

    //自定义 ddl 操作方法 需要 @Modifying 注解,告知此操作会对数据库的数据进行修改
    // 对数据库的数据进行修改时 需要添加事务管理@Transactional(一般加在Service层)
    @Query(value = "update t_book set bookname = ?1 where id = ?2",nativeQuery = true)
    @Modifying
    int updateBookById(String bookname,Long id);
}
  • 插入数据并测试

在这里插入图片描述

    @Autowired
    BookRepository bookRepository;

    @Test
    public void test4(){
        List<Book> b = bookRepository.getBookByBooknameContains("拾");
        System.out.println(b);
        List<Book> b2 = bookRepository.getBookByIdGreaterThanAndAuthorEndsWith(2, "夏达");
        System.out.println(b2);
        Book maxIdBook = bookRepository.getMaxIdBook();
        System.out.println(maxIdBook);
        List<Book> books = bookRepository.idGreaterThan(2);
        System.out.println(books);
    }

在这里插入图片描述

  • 通过 @Query 自定义 dml 和 ddl 方法
  • 自定义 dml 方法可以通过 ?1、?2 或者 ?_id + (@Param(“s_id”)) 来传参
  • 自定义ddl方法需要在自定义的方法上面加上 @Modifying 注解,并且在操作时需要添加事务管理@Transactional(一般加在Service层)`
@Service
@Transactional
public class BookService {
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要将Spring Boot与JPA整合,首先需要在pom.xml文件中添加相应的依赖。这些依赖包括Spring Data JPA和MySQL驱动。例如,在pom.xml文件中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> ``` 接下来,你需要在Spring Boot应用程序的配置文件中添加数据库连接配置。你可以在application.properties或application.yml文件中添加以下配置: ```yaml spring.datasource.url=jdbc:mysql://localhost:3306/your_database_name spring.datasource.username=your_username spring.datasource.password=your_password spring.jpa.show-sql=true spring.jpa.hibernate.ddl-auto=update ``` 在这个配置中,你需要将`your_database_name`替换为你的数据库名称,`your_username`替换为你的数据库用户名,`your_password`替换为你的数据库密码。 然后,你可以创建实体类和存储库接口。实体类用于映射数据库表,而存储库接口用于定义对数据库的操作。可以使用`@Entity`和`@Table`注解来标识实体类,使用`@Repository`或`@RepositoryRestResource`注解来标识存储库接口。 最后,你可以在Spring Boot应用程序的启动类上添加`@EnableJpaRepositories`注解,以启用JPA存储库。 以上是将Spring Boot与JPA整合的基本步骤。通过这种方式,你可以使用JPA进行数据库操作,并且Spring Boot会自动为你处理大部分的配置和实现。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [springboot整合jpa,步骤详细(图文结合讲解)](https://blog.csdn.net/weixin_43442127/article/details/119953836)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [springboot整合JPA](https://blog.csdn.net/weixin_44740485/article/details/124904112)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值