系列文章目录
注解说明
@Entity 注解
注解用于类
上面,用来指定该类是一个实体
@Entity
@Table(name = "app_user")
public class User {
@Id
private Long id;
}
如果 @Entity 注解不与 @Table 注解结合,则默认将实体名称转换成小写后作为表名称。
// 将使用实体名称作为表名,即 userentity
@Entity
public class UserEntity {
//...
}
如果使用 @Entity 注解的 name 属性且没有与 @Table 结合,则默认将 name 属性的值转换成小写后作为表名称,如下示例:
// 将使用指定的实体名称作为表名,即 ue
@Entity(name = "UE")
public class UserEntity {
//...
}
注意:
@Entity 注解必须与 @Id 注解结合使用,否则将抛出" Entity does not have primary key " 错误。
@Table 注解
注解用来为拥有 @Entity 注解的实体类指定主数据表名称
。
@Entity
@Table(name = "app_user") // 表名:app_user
public class User {
// ....
}
@GeneratedValue 注解
用于为 @Id
注解修饰的主键指定值的生成策略
,可通过 strategy 属性指定。默认情况下,JPA 自动选择一个最适合底层数据库的主键生成策略:
strategy 属性
- GenerationType.IDENTITY :ID 自增长(Oracle 不支持)
- GenerationType.AUTO:把主键生成策略交给JPA厂商选择,默认策略
- GenerationType.SEQUENCE:选用序列作为主键生成策略(Oracle、PostgreSQL、DB2支持)
- GenerationType.TABLE:使用一个特定的数据库表格存放主键,建议不要优先使用
@Entity
@Table(name = "app_user")
public class User {
// ID 自增长
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
}
generator属性
主键生成器的名称,与@SequenceGenerator
、@GenericGenerator
等注解结合使用。
@SequenceGenerator 注解
- name:自定义的名字,主要是与另一个注解
@GeneratedValue
的generator使用。 - sequenceName,Oracle表中定义的sequence名字。
- allocationSize - 每次主键值增加的大小,例如设置成1,则表示每次创建新记录后自动加1,默认为50.
@Entity
@Table(name = "COURSE")
public class Course {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "courseSeq")
@SequenceGenerator(name = "courseSeq", sequenceName = "COURSE_SEQ", allocationSize = 1)
private long id;
...
}
@GenericGenerator 注解(hibernate包下)
注:@GenericGenerator注解不在Java Persistence API中,而是hibernate包中的注解。它的主要作用是用来指定一个ID的生成器的自定义类
属性如下:
- name: 自定义的名字,主要是与另一个注解
@GeneratedValue
的generator使用。 - strategy: ID的实现类(可以是
类名
、也可以是已经存在的内置类
)
@Entity
@Table(name = "app_user")
public class User {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid",strategy = "org.hibernate.id.UUIDGenerator")
private String uuid;
}
@GenericGenerator已经存在的内置类
Hibernate在类DefaultIdentifierGeneratorFactory预先内置了很多生成ID的类
public DefaultIdentifierGeneratorFactory() {
register( "uuid2", UUIDGenerator.class ); // 主键自增,UUID
register( "guid", GUIDGenerator.class ); // can be done with UUIDGenerator + strategy
register( "uuid", UUIDHexGenerator.class ); // "deprecated" for new use
register( "uuid.hex", UUIDHexGenerator.class ); // uuid.hex is deprecated
register( "assigned", Assigned.class );
register( "identity", IdentityGenerator.class );
register( "select", SelectGenerator.class );
register( "sequence", SequenceStyleGenerator.class );
register( "seqhilo", SequenceHiLoGenerator.class );
register( "increment", IncrementGenerator.class ); // 单机版,它是单机版的,并不是分布式的。
register( "foreign", ForeignGenerator.class );
register( "sequence-identity", SequenceIdentityGenerator.class );
register( "enhanced-sequence", SequenceStyleGenerator.class );
register( "enhanced-table", TableGenerator.class );
}
比如使用uuid2来生成ID,这时候@GenericGenerator的strategy值不是一个类名了,而是hibernate预置的值generator name了。代码如下:
@Entity
@Table(name = "app_user")
public class User {
@Id
@GeneratedValue(generator = "uuid")
@GenericGenerator(name = "uuid",strategy = "uuid2")
private String uuid;
}
@Column 注解
用来标识实体类中属性与数据表中字段的对应关系。
@Column 注解一共有10个属性,这10个属性均为可选属性,各属性含义分别如下:
- name:定义了被标注字段在数据库表中所对应字段的名称
@Column(name = "name")
private String name;
- unique:表示该字段是否为唯一标识(不允许该值重复),默认为 false
@Column(name = "name", unique = true)
private String name;
- nullable: 表示该字段是否可以为 null 值,默认为 true
@Column(name = "name", unique = true, nullable = false)
private String name;
- insertable:表示在使用“INSERT”脚本插入数据时,是否需要插入该字段的值
- updatable:表示在使用“UPDATE”脚本插入数据时,是否需要更新该字段的值。insertable 和 updatable 属性一般多用于只读的属性,例如主键和外键等。这些字段的值通常是自动生成的。
- columnDefinition:表示创建表时,该字段创建的SQL语句,一般用于通过 Entity 生成表定义时使用(也就是说,如果DB中表已经建好,该属性没有必要使用)
@Column(columnDefinition = "varchar(128) DEFAULT 'default@gmail.com'")
private String email = "default@gmail.com";
@Column(columnDefinition = "varchar(128) DEFAULT '三年级'",insertable = false)
private String grade;
使用JPA save() 插入时,会导致插入的时候默认值是空值覆盖了我们数据库默认的值,导致看到默认值为null,所以可以用上述俩种方法进行,
默认值的填充
或不允许字段插入
操作即可。
- table:定义了包含当前字段的表名
// 指定 name 字段来自 usercolumn 数据表
@Column(name = "name", table = "usercolumn")
private String name;
- length:表示字段的长度,当字段的类型为varchar时,该属性才有效,默认为255个字符
- precision 和 scale:表示精度,当字段类型为 double 时,precision 表示数值的总长度,scale 表示小数点所占的位数。
// salary 字段最大8位数字,其中3位为小数点
@Column(scale = 3, precision = 8)
private Float salary;
@Transient 注解
使用 @Transient 注解来修饰某个属性并非一个到数据库表的字段的映射,ORM 框架将忽略该属性。
private Integer age;
// 保存年龄级别(不持久化到数据库)
@Transient
private String ageLevel;
public void setAge(Integer age) {
this.age = age;
if(age < 18) {
this.ageLevel = "未成年";
} else if(age < 30) {
this.ageLevel = "青年";
} else if(age < 60) {
this.ageLevel = "成年人";
} else {
this.ageLevel = "朽朽老矣";
}
}
@Enumerated 注解
用来直接映射 enum 枚举类型的字段。
只有唯一 一个属性 EnumType
,它枚举定义了枚举类型的映射。此枚举类型的常量指定如何持久化枚举类型的持久属性或字段。可选值如下:
- ORDINAL:将枚举类型属性或字段持久化为整数 (默认)
- STRING:将枚举类型属性或字段持久化为字符串
定义一个枚举类
枚举类:
public enum SexEnum {
MALE("男"), FEMALE("女");
private String value;
private SexEnum(String value) {
this.value = value;
}
}
ORDINAL实例(不推荐)
@Enumerated
private SexEnum sex;
对应表字段如下(类型为 int):
查询结果如下:
STRING实例(推荐)
@Enumerated(EnumType.STRING)
private SexEnum sex;
对应表字段如下(类型为 varcher):
查询结果如下:
注意:不推荐使用 EnumType.ORDINAL,当我们在枚举类中添加新的枚举值,或枚举值顺序变了,数据库中保存的顺序值就不能与以前的值对应了
@JoinColumn 注解
用来在表中定义外键,即定义主键字段和外键字段的对应关系(如果要映射的字段/列本身就是主键,则可以省略该注解)
@JoinColumn 属性详细说明如下:
- name:指定实体中外键字段的名称。name 不是必填的,你可以不写,采用默认值(假如使用 @OneToOne 进行一对一映射,此时 name 默认值格式为“副表名_副表主键名”)
- referencedColumnName:指定此外键列引用的列的名称
- unique:指定属性是否是唯一键,一般用不到,因为主键具有唯一性
- nullable:外键列是否为空
- insertable:指定该列是否包含在持久性提供程序生成的 INSERT SQL 语句中
- updatable:指定该列是否包含在持久性提供程序生成的 UPDATE SQL 语句中
- columnDefinition:指定为列生成 DDL 时使用的 SQL 片段
- table:包含列的表的名称。 如果未指定表,则假定该列位于使用实体的主表中
注意:不能单独使用 @JoinColumn 注解,该注解需要配合 @OneToOne、@ManyToOne、@OneToMany 一起使用,单独使用没有意义。
@JoinTable 注解
@JoinTable 注解用于关联映射
,它是在关联的拥有方进行配置
。使用 @JoinTable 注解将创建一个连接表,也称为“中间表”。
连接表(join table)通常用于 many-to-many 和单向 one-to-many 关联的映射。@JoinTable 还可以用于映射双向 many-to-one/one-to-many 关联、单向 many-to-one 关系和 one-to-one 关联(双向和单向)。
即当 @JoinTable 用在哪个实体,那个实体就是关系的拥有者。
@JoinTable 属性详细说明如下:
- catalog:可选属性,用于指定数据库实例名
- schema:作用与 catalog 属性作用一致,可自行测试
- name:指定连接表(中间表)的名称;如果不指定名称,则使用默认表名,默认名称规则为“主表名称_副表名称”
- joinColumns:连接表中对应主表外键
- inverseJoinColumns:连接表中对应副表外键
- uniqueConstraints:表唯一约束,为连接表(中间表)指定一个或多个唯一约束
举例:
public class User{
@JsonProperty(access = Access.WRITE_ONLY)
@ManyToMany
@JoinTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"), inverseJoinColumns = @JoinColumn(name = "role_id"))
private List<Role> roles;
}
@OrderBy 注解
@OrderBy 注解用来指定在查询一对多、多对多关联关系中,关联集合元素的顺序
// JPA 默认根据 Student 的 ID 主键对 studentList 集合数据进行递增排序
@OneToMany(cascade = CascadeType.ALL)
@OrderBy
private List<Student> studentList;
// 手动指定 salary字段的排序方式,ASC 递增排序,DESC 递减排序
@OneToMany(cascade = CascadeType.ALL)
@OrderBy("salary desc")
private List<Student> studentList;
// 手动指定按照多个属性进行排序
// 下面将根据 sex 和 salay 进行递增排序
@OneToMany(cascade = CascadeType.ALL)
@OrderBy("sex,salary")
private List<Student> studentList;
// 下面将根据 sex 递增排序,salary 递减排序
@OneToMany(cascade = CascadeType.ALL)
@OrderBy("sex asc,salary desc")
private List<Student> studentList;