13518219792

建站动态

根据您的个性需求进行定制 先人一步 抢占小程序红利时代

JPA实体类注解,看这篇就全会了

哈喽,大家好,我是指北君。

创新互联长期为上千客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为晋中企业提供专业的网站建设、做网站晋中网站改版等技术服务。拥有十年丰富建站经验和众多成功案例,为您定制开发。

今天给大家介绍一下 JPA 实体类中的注解,希望能对大家有帮助。

基本注解

@Entity

标注于实体类声明语句之前,指出该 Java 类为实体类,将映射到指定的数据库表。

不与 @Table 结合时,表名默认为类名的 SnakeCase(蛇形命名法),若使用name属性,则表名为 name 值。

//以下三个类皆映射表名 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(未加注解的默认注解)

表示一个简单的属性到数据库表的字段的映射,对于没有任何注解的属性,默认即为 @Basic 。

@Transient

表示该属性并非一个到数据库表的字段的映射,ORM 框架将忽略该属性。

如果一个属性并非数据库表的字段映射,就务必将其标示为@Transient,否则,ORM框架默认其注解为@Basic 。

@Column

当实体的属性与其映射的数据库表的列不同名时需要使用@Column 标注说明,该注解通常置于实体的属性前或属性的getter方法之前,还可与 @Id 标注一起使用。

@Id

用于声明一个实体类的属性映射为数据库的主键列。

@GeneratedValue

AUTO:JPA 自动选择合适的策略,是默认选项;

IDENTITY:采用数据库 ID自增长的方式来自增主键字段,Oracle 不支持这种方式;

SEQUENCE:通过序列产生主键,通过 @SequenceGenerator 注解指定序列名,MySql 不支持这种方式

TABLE:通过表产生主键,框架借由表模拟序列产生主键,使用该策略可以使应用更易于数据库移植。该策略一般与另外一个注解一起使用@TableGenerator。

@GenericGenerator

自定义主键生成策略

@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 注解来调整精度。

@Data
@Entity
@Table(name = "student_info")
public class Student {
@Column
@Temporal(TemporalType.DATE)
private Date birthday;
}

@DynamicInsert、@DynamicUpdate

@Data
@Entity
@Table(name = "user_info")
@DynamicInsert
@DynamicUpdate
public class User {
@Id
@Column(name = "id")
@GenericGenerator(name="idGenerator", strategy="uuid")
@GeneratedValue(generator = "idGenerator")
private String id;

@Column(name = "name")
private String name;

@Basic
private Integer age;

@Column(name = "create_time")
private Long createTime;

@Column(name = "remark")
private String remark;
}

@Access

指定实体的访问模式(Access mode),包括AccessType.FIELD及AccessType.PROPERTY。

复合主键

@EmbeddedId + @Embeddable

当需要多个属性作为复合主键时,可以把该属性做为一个内部类嵌套在实体类中,使用@EmbeddedId + @Embeddable实现:

必须要实现Serializable接口

需要有无参的构造函数

// 复合主键类
@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

注解复合主键的类,复合主键类必须满足:

// 复合主键类
@Data
@Embeddable
public static class StudentId implements Serializable {

@Column(name = "id")
private Integer id;

@Column(name = "class_id")
private Integer classId;
}

//实体类
@Data
@Entity
@IdClass(StudentId.class)
@Table(name = "student_info")
public class StudentInfo {

@EmbeddedId
private StudentId studentId;

@Column(name = "name")
private String name;

}

@Embedded + @AttributeOverride

// 复合主键类
@Data
@Embeddable
public static class StudentId implements Serializable {
private Integer id;
private Integer classId;
}

@Data
@Entity
@Table(name = "student_info")
public class StudentInfo {

@Embedded
@AttributeOverrides( {
@AttributeOverride(name = "id", column = @Column(name = "id")),
@AttributeOverride(name = "classId", column = @Column(name = "class_id"))
})
private StudentId id;

@Column(name = "name")
private String name;

}

实体间关联关系

@OneToOne

实体间一对一的关系。

REMOVE:级联删除操作。删除当前实体时,与它有映射关系的实体也会跟着被删除。

MERGE:级联更新(合并)操作。当前对象中的数据改变,会相应地更新级联对象中的数据。

DETACH:级联脱管/游离操作。如果要删除一个实体,但是它有外键无法删除,你就需要这个级联权限了。它会撤销所有相关的外键关联。

REFRESH:级联刷新操作。更新数据前先刷新对象和级联对象,再更新。

PERSIST:级联持久化(保存)操作。持久保存拥有方实体时,也会持久保存该实体的所有相关数据。

ALL,当前类增删改查改变之后,关联类跟着增删改查,拥有以上所有级联操作权

一对一关系的例子

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:用于构建一对多,多对多时的连接表,默认会以主控表加下划线加反转表为表名。

@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

注解一对多和多对一关系。

例子

@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
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。

@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 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 permissions;

}

小结

以上就是 JPA 实体类中的注解介绍,文中的例子仅仅浅尝辄止,希望大家可以实际应用一下,后续我也会更深入的讲解一些 JPA 的高级用法。


当前名称:JPA实体类注解,看这篇就全会了
转载注明:http://cdbrznjsb.com/article/dpiessj.html

其他资讯

让你的专属顾问为你服务