JPA常用注解
所属分类 JPA
浏览量 82
基本注解
@Entity
@Table
@Basic(未加注解的默认注解)
@Transient
@Column
@Id
@GeneratedValue
@GenericGenerator
其他注解
@Enumerated
@Temporal
@DynamicInsert、@DynamicUpdate
@Access
复合主键
@EmbeddedId + @Embeddable
@IdClass
@Embedded + @AttributeOverride
实体间关联关系
@OneToOne
@OneToMany和@ManyToOne
@ManyToMany
//以下 表名都是 student_info
@Entity
public class StudentInfo{...}
@Entity(name="student_info")
public class StudentInfo{...}
@Entity
@Table(name = 'student_info')
public class StudentInfo{...}
@Table
当实体类与其映射的数据库表名不同名时使用@Table ,与@Entity标注 一起使用
@Entity
@Table(name = "student_info", uniqueConstraints = {@UniqueConstraint(columnNames = "class_id")})
public class StudentInfo {
@Column(name = "class_id")
private String classId;
}
没有任何注解的属性,默认为 @Basic
fetch: 表示该属性的读取策略,其中 EAGER (默认)表示立即加载,LAZY 表示延迟加载。
optional:表示该属性是否允许为 null ,默认为 true
@Transient 非数据库字段
表示该属性并非一个到数据库表的字段的映射,ORM 框架将忽略该属性。
如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic
@Column
name 列名
unique 是否是唯一标识,默认为 false(不唯一)
nullable 是否允许为 null,默认为true(null)
insertable 执行插入操作时,该字段是否应出现在 INSERT 语句中,默认为true
updatable 执行更新操作时,该字段是否应该出现在 UPDATE 语句中,默认为 true
length 仅对String类型的字段有效,默认值255
precision、scale 表示精度,当字段类型为double时,precision表示数值的总长度,scale表示小数点所占的位数,默认值均为0
columnDefinition 数据库字段实际类型 ,将 String 类型映射到特定数据库的 BLOB 或 TEXT 字段类型,该属性非常有用
@GeneratedValue
AUTO 自动选择合适的策略,默认
IDENTITY 自增 ,Oracle 不支持
SEQUENCE 序列生成主键 @SequenceGenerator 指定序列名,MySql 不支持
TABLE 通过表产生主键 , 与 @TableGenerator 一起使用
默认情况,JPA 自动选择一个最适合底层数据库的主键生成策略:SqlServer 对应 IDENTITY,MySQL 对应 AUTO
generator 设置生成器名
@GenericGenerator
name:生成器名称
strategy:预定义的 Hibernate 策略或完全限定的类名
@Data
@Entity
@Table(name = "student_info")
public class StudentInfo {
@Id
@Column(name = "id")
@GenericGenerator(name="idGenerator", strategy="uuid")
@GeneratedValue(generator = "idGenerator")
private String id;
@Transient
private String age;
@Column(name = "name")
private String name;
}
@Enumerated
直接映射枚举类型的字段
ORDINAL:映射到数据库字段为数字(默认)
String:映射到数据库字段为字符串
@Entity
@Data
@Table(name = "StudentInfo")
public class Student {
@Column
@Enumerated
private Sex sex;
}
@Temporal
日期时间 ,使用 @Temporal 调整精度
DATE:日期
TIME:时间
TIMESTAMP:日期时间
@Data
@Entity
@Table(name = "student_info")
public class Student {
@Column
@Temporal(TemporalType.DATE)
private Date birthday;
}
@DynamicInsert 设置为true,如果字段值为null ,不加入到insert语句中
@DynamicUpdate 设置为true, 如果字段的值是null ,不加入到update语句中
@Data
@Entity
@Table(name = "user_info")
@DynamicInsert
@DynamicUpdate
public class User {
@Access
指定实体的访问模式(Access mode), AccessType.FIELD AccessType.PROPERTY
AccessType.FIELD
通过字段来获取或设置实体的状态,getter和setter方法 可有可无
JPA默认的访问类型为AccessType.FIELD
AccessType.PROPERTY
持久化属性必须有getter和setter方法,属性的类型由getter方法的返回类型决定,同时必须与传递到setter方法的单个参数的类型相同
复合主键 两种实现
@EmbeddedId + @Embeddable
@IdClass
// 复合主键类
@Data
@Embeddable
public static class StudentId implements Serializable {
@Column(name = "id")
private Integer id;
@Column(name = "class_id")
private Integer classId;
}
//实体类
@Data
@Entity
@Table(name = "student_info")
public class StudentInfo {
@EmbeddedId
private StudentId studentId;
@Column(name = "name")
private String name;
}
@IdClass
复合主键类
实现Serializable接口
有默认的public无参数的构造方法
重写equals和hashCode方法
@Data
@Entity
@IdClass(StudentId.class)
@Table(name = "student_info")
public class StudentInfo {
@EmbeddedId
private StudentId studentId;
@Column(name = "name")
private String name;
}
实体间关联关系
@OneToOne
fetch:立即加载和延迟加载
cascade:当前类对象操作了之后,级联对象的操作。
REMOVE:级联删除操作。删除当前实体时,与它有映射关系的实体也会跟着被删除。
MERGE:级联更新(合并)操作。当前对象中的数据改变,会相应地更新级联对象中的数据。
DETACH:级联脱管/游离操作。如果要删除一个实体,但是它有外键无法删除,你就需要这个级联权限了。它会撤销所有相关的外键关联。
REFRESH:级联刷新操作。更新数据前先刷新对象和级联对象,再更新。
PERSIST:级联持久化(保存)操作。持久保存拥有方实体时,也会持久保存该实体的所有相关数据。
ALL,当前类增删改查改变之后,关联类跟着增删改查,拥有以上所有级联操作权
mappedBy:拥有关联关系的域,如果关系是单向的就不需要,双向关系表,那么拥有关系的这一方有建立、解除和更新与另一方关系的能力,而另一方没有,只能被动管理,这 个属性被定义在关系的被拥有方。
orphanRemoval:如果设置为true,当关系被断开时,多方实体将被删除。否则会将对象的引用置为null。
targetEntity:表示该属性关联的实体类型。该属性通常不必指定,ORM 框架根据属性类型自动判断。
一对一关系的例子
people 表(id,name,sex,birthday,address_id) address 表(id,phone,zipcode,address)
People和Address是一对一的关系。
方式一:通过外键的方式(一个实体通过外键关联到另一个实体的主键)
@JoinColum:保存表与表之间关系的字段,它要标注在实体属性上。一般修饰在主控方,用来定义一对一,一对多等关系列。
关联的实体的主键一般是用来做外键的。但如果此时不想主键作为外键,则需要设置referencedColumnName属性。
@Entity
public class People {
@Id
@Column(name = "id")
@GenericGenerator(name = "idGenerator", strategy = "uuid")
@GeneratedValue(generator = "idGenerator")
private String id;
@Column(name = "name")
private String name;//姓名
@Column(name = "sex")
private String sex;//性别
@Column(name = "birthday")
private Date birthday;//出生日期
@OneToOne(cascade=CascadeType.ALL)//People是关系的维护端,当删除 people,会级联删除 address
@JoinColumn(name = "address_id", referencedColumnName = "id")
private Address address;//地址
}
@Entity
public class Address {
@Id
@Column(name = "id")
@GenericGenerator(name = "idGenerator", strategy = "uuid")
@GeneratedValue(generator = "idGenerator")
private String id;
@Column(name = "phone")
private String phone;//手机
@Column(name = "zipcode")
private String zipcode;//邮政编码
@Column(name = "address")
private String address;//地址
}
方式二:通过关联表的方式来保存一对一的关系。
关联表:people_address (people_id,address_id)
@JoinTable:用于构建一对多,多对多时的连接表,默认会以主控表加下划线加反转表为表名。
JoinColumns:该属性值可接受多个@JoinColumn,用于配置连接表中外键列的信息,这些外键列参照当前实体对应表的主键列。
inverseJoinColumns:该属性值可接受多个@JoinColumn,用于配置连接表中外键列的信息,这些外键列参照当前实体的关联实体对应表的主键列。
@Entity
public class People {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Long id;//id
@Column(name = "name")
private String name;//姓名
@Column(name = "sex")
private String sex;//性别
@Column(name = "birthday")
private Timestamp birthday;//出生日期
@OneToOne(cascade=CascadeType.ALL)//People是关系的维护端
@JoinTable(name = "people_address",
joinColumns = @JoinColumn(name="people_id"),
inverseJoinColumns = @JoinColumn(name = "address_id"))
private Address address;//地址
}
@Entity
public class Address {
@Id
@Column(name = "id")
@GenericGenerator(name = "idGenerator", strategy = "uuid")
@GeneratedValue(generator = "idGenerator")
private String id;
@Column(name = "phone")
private String phone;//手机
@Column(name = "zipcode")
private String zipcode;//邮政编码
@Column(name = "address")
private String address;//地址
}
@OneToMany和@ManyToOne
注解一对多和多对一关系。
JPA使用@OneToMany和@ManyToOne来标识一对多的双向关联。一端(One)使用@OneToMany,多端(Many)使用@ManyToOne。
在JPA规范中,一对多的双向关系由多端(Many)来维护。就是说多端(Many)为关系维护端,负责关系的增删改查。一端(One)则为关系被维护端,不能维护关系。
一端(One)使用@OneToMany注释的mappedBy属性表明是关系被维护端。
多端(Many)使用@ManyToOne和@JoinColumn来注释属性,@ManyToOne表明是多端,@JoinColumn设置在表中的关联字段(外键)。
例子
文章表 article (id,title,content,author_id)
作者表 author (id,name)
@Entity
public class Author {
@Id
@Column(name = "id")
@GenericGenerator(name = "idGenerator", strategy = "uuid")
@GeneratedValue(generator = "idGenerator")
private String id;
@Column
private String name;//姓名
//级联保存、更新、删除、刷新;延迟加载。当删除用户,会级联删除该用户的所有文章
//拥有mappedBy注解的实体类为关系被维护端
//mappedBy="author"中的author是Article中的author属性
@OneToMany(mappedBy = "author",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
private List< Article> articleList;//文章列表
}
@Entity
public class Article {
@Id
@Column(name = "id")
@GenericGenerator(name = "idGenerator", strategy = "uuid")
@GeneratedValue(generator = "idGenerator")
private String id;
@Column
private String title;
@Lob // 大对象,映射 MySQL 的 Long Text 类型
@Basic(fetch = FetchType.LAZY) // 懒加载
@Column(nullable = false)
private String content;//文章全文内容
//可选属性optional=false,表示author不能为空。删除文章,不影响用户
@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false)
//设置在article表中的关联字段(外键)
@JoinColumn(name="author_id")
private Author author;//所属作者
}
@ManyToMany
注解多对多的关系。
角色和权限是多对多的关系。一个角色可以有多个权限,一个权限也可以被很多角色拥有。
JPA中使用@ManyToMany来注解多对多的关系,由一个关联表来维护。这个关联表的表名默认是:主表名+下划线+从表名。
这个关联表只有两个外键字段,分别指向主表ID和从表ID。字段的名称默认为:主表名+下划线+主表中的主键列名,从表名+下划线+从表中的主键列名。
例子
权限表 user_permission(id,permission_name)
角色表 user_role(id,department_id, create_time, description, name, update_time)
关联表 user_role_permission 表(role_id, permission_id)
注意
多对多关系中一般不设置级联保存、级联删除、级联更新等操作。
本例中,由于加了@JoinTable注解,关联关系表会按照注解指定的生成。否则去掉注解,指定Role为关系维护端,所以生成的关联表名称为:user_role_permission,关联表的字段为:role_id 和permission_id。
1
@Data
@Entity
@Table(name = "user_permission")
public class Permission implements Comparable {
@Id
@Column(name = "id")
private String id;
@Column(name = "permission_name")
private String permissionName;
@ManyToMany(mappedBy="permissions")
private Set< Role> roles;
}
@Data
@Entity
@Table(name = "user_role")
public class Role {
@Id
@Column(name = "id")
@GenericGenerator(name = "idGenerator", strategy = "uuid")
@GeneratedValue(generator = "idGenerator")
private String id;
@Column(name = "create_time")
private Long createTime;
@Column(name = "update_time")
private Long updateTime;
@Column(name = "name")
private String name;
@Column(name = "description")
private String description;
@Column(name = "department_id")
private String departmentId;
@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
@JoinTable(name = "user_role_permission", joinColumns = {@JoinColumn(name = "role_id")},
inverseJoinColumns = {@JoinColumn(name = "permission_id")})
private List< Permission> permissions;
}
上一篇
下一篇
vue3 技术栈
JdbcTemplate BeanPropertyRowMapper 使用
家常炒挂面
Springboot 过滤器 拦截器 全局异常处理
jackson 笔记
mybatis之MappedStatement getBoundSql