Spring Data JPA相关知识点

现在版本?

本文参考了Spring Data JPA官方文档,引用了部分文档的代码

据文章编辑时,Springboot的版本已经是v2.1.7.RELEASE,Spring Data的版本已经是Lovelace-SR10

Springboot

Spring Data
  • 使用Springboot,springboot将会替你选择最新的spring data模块(Spring Boot selects a recent version of Spring Data modules for you. If you still want to upgrade to a newer version, configure the property spring-data-releasetrain.version to the train name and iteration you would like to use.)。
image

image

Spring Data Jpa 是什么?

Spring Data JPA是更大的Spring Data系列的一部分,可以轻松实现基于JPA的存储库。此模块处理对基于JPA的数据访问层的增强支持。它使构建使用数据访问技术的Spring驱动应用程序变得更加容易。在相当长的一段时间内,实现应用程序的数据访问层一直很麻烦。必须编写太多样板代码来执行简单查询以及执行分页和审计。Spring Data JPA旨在通过减少实际需要的工作量来显着改善数据访问层的实现。作为开发人员,您编写存储库接口,包括自定义查找器方法,Spring将自动提供实现。

代码层面

实体类

package me.superning.tmall.pojo;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
@Entity
@Table(name = "category")
//表名(严格区分大小写)
@JsonIgnoreProperties({"handler", "hibernateLazyInitializer"})
public class Category  implements Serializable {

    @Id
//    主键使用这个注解
    @GeneratedValue(strategy = GenerationType.IDENTITY)
//    自增长策略
    @Column(name = "id")
    private int id;
    private String name;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
  • 1.@Entity:标识实体类是JPA实体,告诉JPA在程序运行时生成实体类对应表
  • 2.@Table:设置实体类在数据库所对应的表名
  • 3.@Id:标识类里所在变量为主键
  • 4.@GeneratedValue:设置主键生成策略,此方式依赖于具体的数据库
  • 5.@Basic:表示简单属性到数据库表字段的映射(几乎不用)
  • 6.@Column:表示属性所对应字段名进行个性化设置
  • 7.@Transient:表示属性并非数据库表字段的映射,ORM框架将忽略该属性(在与密码有关的实体类会用到这个注解,后续详解于另一篇文章)

常用的注解如上,其他注解可能会以独立文章讲解。

持久层

Spring data的中央接口是Repository,
它还提供了扩展了持久层技术的接口例如
CrudRepository
MongoRepository
JpaRepository
中央接口

CrudRepository和JpaRepository之间的区别

image

从上图你可以看出JpaRepository 继承了PagingAndSortingRepository,相应的也继承了CrudRepository

  • CrudRepository 主要提供了CRUD的方法功能
  • PagingAndSortingRepository,提供了分页和排序记录的方法
  • JpaRepository 则拥有了它们两个所有的方法功能,并扩展了其他方法

用法

public interface OrderItemDAO 
extends JpaRepository<OrderItem,Integer>
{
    List<OrderItem> findByOrderOrderByIdDesc(Order order);
}
由代码可知,Dao接口首先继承一个JpaRepository接口,
JpaRepository<T, ID> T是泛型,ID是主键的类型。
接口本身已经为我们提供了基础的CRUD方法,但有时我们有
一些特殊的查询,接口无法为我们提供,这时就需要我们进行特殊参数处理。
特殊参数处理
Page<User> findByLastname(String lastname, Pageable pageable);

Slice<User> findByLastname(String lastname, Pageable pageable);

List<User> findByLastname(String lastname, Sort sort);

List<User> findByLastname(String lastname, Pageable pageable);

关于使用@Query("sql语句")在dao层的方法上写原生sql语句,
以后以独立文章介绍

关系映射

借鉴这位先生的csdn博客以及自我理解结合而成

  • 一对一
@OneToOne(cascade=CascadeType.ALL,optional=true)
@JoinColumn(name="addressID")//注释本表中指向另一个表的外键。
public Address getAddress() { 
    return address;
}
现假设有Person表和Address表,是一对一的关系,
在Person中有一个指向Address表主键的字段addressID,
所以主控方一定是Person,所谓主控方就是能改变关联关系的一方,
Person只要改变addressID就改变了关联关系,所以Person是主控方,
所以@JoinColumn写在Person类中
  • 一对多单向

假如现在有Person表和Country表,那么一定是Person表中有country_id字段,由于我们是一对多的关系,所以站在一的角度,也就是Country的角度,在Country类中加入@JoinColumn


@OneToMany(cascade=CascadeType.ALL) 
@JoinColumn(name="country_id")//注释的是另一个表指向本表的外键。 
public List<Person> getPersons() {
    return persons; 
}

在一对多单向关系中,多的一方(Person)没有注解,一的一方(Country)有注解,如果一的一方不加@JoinColumn指定外键字段的话,Hibernate会自动生成一张中间表Country_PERSON来对Person和Country进行绑定。

  • 多对一单向

一个产品可以属于多个分类,因此@JoinColumn放在Product类中

image

看看数据库

image

可以看到在Product表出现了一个对应Category表的外键
但是Category表中却没有外键,因此这就是单向的多对一
image
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容