文章目录
一、简介
Springboot-Data-JPA是在工作中经常使用到的ORM框架,我觉的比较好用的点是其集成了大量的对数据库的简单操作,基本满足对数据增删改的需要,JPA关系的映射使用注解的方式,很大程度上提高了代码的可读性。
二、关系类型
1.一对一(@OneToOne)
这里的address是一个Address(地址实体类),"JoinColumn"属性会在当前的student表中添加一个addressId字段,这个字段会和"referencedColumnName"设置的"id"属性进行关联(即addressId关联id属性),实现学生实体和地址实体的一对一关联。
package com.heitao.base.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
import java.util.Set;
/**
* @author seaua
* @description:学生实体类
* @date 2022/12/7 下午2:52
* Implements{@link }
* extend{@link }
**/
@Entity
public class Student {
/**
* PARAM:{@param id} [主键ID] TYPE: {@link Integer}
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* PARAM:{@param address} [AddressId] TYPE: {@link Address}
*/
@OneToOne
@JoinColumn(name="addressId",referencedColumnName="id")
private Address address;
/**
* PARAM:{@param clazz} [班级] TYPE: {@link Clazz}
*/
@ManyToOne
@JoinColumn(name = "cid")
@JsonIgnoreProperties("list")
private Clazz clazz;
/**
* PARAM:{@param course} [课程表] TYPE: {@link Set<Course>}
*/
@ManyToMany(cascade = {CascadeType.MERGE, CascadeType.REFRESH}, fetch = FetchType.EAGER)
@JoinTable(name = "stu_cou", joinColumns = {@JoinColumn(name = "stu_id")}, inverseJoinColumns = {@JoinColumn(name = "cou_id")})
@JsonIgnoreProperties({"student"})
private Set<Course> courses;
}
2.一对多(@OneToMany/@ManyToOne)
一个班级内有多个学生,多个学生在一个班级内,故学生和班级是多对一,教室和学生是一对多的关系。JPA通过@OneToMany标识一对多,通过@ManyToOne标识多对一。@JoinColum注解用在多的一方,表示在表中添加一个字段与class表的主键ID(默认)产生关联。mappedBy属性用在多方,值为关联实体类中当前类的名称(不可以错),fetch属性表示以积极(FetchType.EAGER)或懒加载(FetchType.LAZY)模式加载,@JsonIgnoreProperties({"clazz"})表示在循环关联时,遇到clazz变量则终止Json解析。
package com.heitao.base.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import javax.persistence.*;
import java.util.List;
/**
* @author seaua
* @description:班级-实体类
* @date 2022/12/7 下午2:52
* Implements{@link }
* extend{@link }
**/
@Entity
public class Clazz {
/**
* PARAM:{@param cid} [主键ID] TYPE: {@link Integer}
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer cid;
/**
* PARAM:{@param className} [教室名] TYPE: {@link className}
*/
private String className;
/**
* PARAM:{@param list} [学生列表] TYPE: {@link list}
*/
@OneToMany(mappedBy = "clazz",fetch = FetchType.EAGER)
@JsonIgnoreProperties({"clazz"})
private List<Student> list;
}
3.多对多(@ManyToMany)
一名学生(Student)可以选修多门课程(Course),一门课程(Course)可以被多个学生选修(Student),课程和学生互为多对多的关系。在Student使用@JoinTable注解来创建多对多中间表,
joinColumns,inverseJoinColumns表示两个关联表中的两个字段名(默认关联主键)。
package com.heitao.base.domain;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.Setter;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import javax.persistence.*;
import java.util.Set;
/**
* @author seaua
* @description:课程-实体类
* @date 2022/12/7 下午2:52
* Implements{@link }
* extend{@link }
**/
@Entity
@Getter
@Setter
public class Course {
/**
* PARAM:{@param id} [主键ID] TYPE: {@link Integer}
*/
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* PARAM:{@param courseName} [课程名称] TYPE: {@link String}
*/
private String courseName;
/**
* PARAM:{@param students} [学生列表] TYPE: {@link Set<Student>}
*/
@ManyToMany(fetch = FetchType.EAGER,mappedBy = "course")
@NotFound(action = NotFoundAction.IGNORE)
@JsonIgnoreProperties({"course"})
private Set<Student> students;
}
易发问题
1.为解决依赖关系的死循环问题,使用@JsonIgnoreProperties({"clazz"})注解,{}内为与之关联的变量名称(注意为变量名称)。
2.一对多关系,多端类使用@JoinColumn(name = "cid")注解添加外键字段。多对对关系,任意多端使用@JoinTable(name = "stu_cou", joinColumns = {@JoinColumn(name = "stu_id")}, inverseJoinColumns = {@JoinColumn(name = "cou_id")})注解添加关系联系表,该注解会自动生成一个已两端主键作为关系的主键表。(以上注解表示y生成一个stu_cou表,使用student的主键和coruse的主键作为主键创建关系。)
3.mappedBy的值是关系类的变量名。