JPA 常用基础注解说明

系列文章目录

  1. JPA常用基础注解说明
  2. 一文搞定,详细说明JPA实体关系映射


@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个字符
  • precisionscale:表示精度,当字段类型为 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;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值