第二章 @Entity实例里常用的注解详解

一、javax.persistence概况介绍

虽然Spring Data JPA已经帮我们对数据的操作封装得很好了, 约定大于配置思想,帮我们默认了很多东西。
JPA(Java持久性API) 是存储业务实体关联的实体来源。它显示了如何定义一个面向普通 Java对象(POJO)作为一个实体,以及如何与管理关系实体提供一套 标准。因此,javax.persistence下面的有些注解还是必须要去了解 的,以便于更好地提高工作效率。
 
(1)javax.persistence位于hibernate-jpa-**.jar包里面,可以通过Intellij Idea的maven插件直接分析一下maven的依赖,也可以用$ mvn dependency:tree分析,例如:
 
(2)通过Intellij Idea的Diagram来看一下此模块类的关键关系。
(3)图显示了JPA的类的层次结构,包括核心类和JPA接口。
每个在上述架构的显示单元。
 
上述的类和接口用于存储实体到数据库的一个记录,帮助程序员通过减少自己编写的代码将数据存储到数据库中,使他们能够专注于更重要的业务活动代码,如数据库表映射的类编写代码。
下面我们主要介绍一下在Entity里面常用的注解,对于其他没有介绍到的注解,建议读者直接到包的源码里面进行查找和分析。
 

二、基本注解

基本注解包括@Entity、@Table、@Id、@IdClass、@GeneratedValue、@Basic、@Transient、@Column、@Temporal、 @Enumerated、@Lob。
 

2.1 @Entity

@Entity
@Table(name="user")
public class UserPO {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;

    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }

}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@Entity定义对象将会成为被JPA管理的实体,将映射到指定的数据库表。
 

2.2 @Table

@Table指定数据库的表名。

2.3 @Id

@Id定义属性为数据库的主键,一个实体里面必须有一个。

2.3 @IdClass

@IdClass利用外部类的联合主键。

作为复合主键类,要满足以下几点要求。

  1. 必须实现Serializable接口。
  2. 必须有默认的public无参数的构造方法。
  3. 必须覆盖equals和hashCode方法。equals方法用于判断两个对象是否相同,EntityManger通过find方法来查找Entity时是根据equals的返回值来判断的。在本例中,只有对象的name和 email值完全相同或同一个对象时才返回true,否则返回 false。hashCode方法返回当前对象的哈希码,生成的hashCode相同的概率越小越好,算法可以进行优化。

用法

① 我们假设UserBlog的联合主键是createUserId和title,新增一个UserBlogKey的类。UserBlogKey.class代码如下:
 

② UserBlogEntity.java要稍加改动:实体类上需要加@IdClass注解,主键上都得加@Id。

③ UserBlogRepository中的改动如下:

④ 使用的时候:
 

 因为Jpa默认会提供根据主键信息进行查询内容的方法,所以如果表的主键为双主键的时候,相应的实现主键查询的方法也要进行调整,要和主键的类型一致。这就是为什么③ ④要进行调整的原因。

2.4 @GeneratedValue

@GeneratedValue为主键生成策略,例如:

GenerationType一共有以下4个值:

IDENTITY:主键由数据库自动生成(主要是自动增长型)

SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。

AUTO:主键由程序控制

TABLE:使用一个特定的数据库表格来保存主键

2.5 @Basic 、@Transient

@Basic表示属性是到数据库表的字段的映射。如果实体的字段上没有任何注解,默认即为@Basic。
@Transient表示该属性并非一个到数据库表的字段的映射,表示非持久化属性,与@Basic作用相反。JPA映射数据库的时候忽略它。
 

2.6 @Column

@Column定义该属性对应数据库中的列名。

2.7 @Temporal

@Temporal用来设置Date类型的属性映射到对应精度的字段。
(1)@Temporal(TemporalType.DATE)映射为日期∥date(只有日期)。
(2)@Temporal(TemporalType.TIME)映射为日期∥time(只有时间)。
(3)@Temporal(TemporalType.TIMESTAMP)映射为日期∥datetime(日期+时间)。
 
 

2.8 @Enumerated

@Enumerated很好用,直接映射enum枚举类型的字段。

(1)看源码:

(2)看例子:

这时插入两条数据,数据库里面的值是MAIL/FMAIL,而不是“男性”/“女性”。如果我们用@Enumerated(EnumType.ORDINAL),那么
这时数据库里面的值是0,1。但是实际工作中,不建议用数字下标,因为枚举里面的属性值是会不断新增的,如果新增一个,位置变化了就惨了。
 

2.9 @Lob

@Lob 将属性映射成数据库支持的大对象类型,支持以下两种数据库类型的字段。
(1)Clob(Character Large Ojects)类型是长字符串类型,java.sql.Clob、Character[]、char[]和String将被映射为Clob类型。
(2)Blob(Binary Large Objects)类型是字节类型, java.sql.Blob、Byte[]、byte[]和实现了Serializable接口的类型将被映射为Blob类型。
(3)Clob、Blob占用内存空间较大,一般配合@Basic(fetch=FetchType.LAZY)将其设置为延迟加载。
 

三、关联关系注解(一般不使用了解即可)

关联关系注解包括@JoinColumn、@OneToOne、@OneToMany、 @ManyToOne、@ManyToMany、@JoinTable、@OrderBy。
 

3.1 @JoinColumn定义外键关联的字段名称

用法:@JoinColumn主要配合@OneToOne、@ManyToOne、 @OneToMany一起使用,单独使用没有意义。
@JoinColumns定义多个字段的关联关系。
 

3.2 @OneToOne关联关系

用法:@OneToOne需要配合@JoinColumn一起使用。注意:可以双向关联,也可以只配置一方,需要视实际需求而定。
 
假设一个部门只有一个员工。Department的内容如下:
employee_id指的是Department里面的字段,而referencedColumnName="id"指的是Employee表里面的字段。
 
如果需要双向关联,Employee的内容如下:
 

当然也可以不选用mappedBy,和下面效果是一样的:

 

3.3 @OneToManyg与@ManyToOne关联关

@OneToMany与@ManyToOne可以相对存在,也可只存在一方。

@OneToMany源码语法如下:

 

使用示例,必须和@JoinColumn配合使用才有效。

3.4 @ManyToMany关联关系

源码语法如下:

@ManyToMany表示多对多,和@OneToOne、@ManyToOne一样也有单向、双向之分。单向双向和注解没有关系,只看实体类之间是否相互引用。
(2)示例:一个博客可以拥有多个标签,一个标签也可以使用在多个博客上,Blog和Tag就是多对多关系。
 

BlogTagRelation为中间关联关系表blog_tag_relation对应的实体。

3.5 关于关系查询的一些坑

  1. 所有的注解要么全配置在字段上,要么全配置在get方法上,不能混用,混用就会启动不起来,但是语法配置没有问题。
  2. 所有的关联都是支持单向关联和双向关联的,视具体业务场景而定。JSON序列化的时候使用双向注解会产生死循环,需要人为手动转化一次,或者使用@JsonIgnore。
  3. 在所有的关联查询中,表一般是不需要建立外键索引的。@mappedBy的使用需要注意。
  4. 级联删除比较危险,建议考虑清楚,或者完全掌握。
  5. 不同的关联关系的配置,@JoinClumn里面的name、referencedColumnName代表的意思是不一样的,很容易弄混,可以根据打印出来的SQL做调整。
  6. 当配置这些关联关系的时候建议大家直接在表上面,把外键建好,然后通过后面我们介绍的开发工具直接生成,这样可以减少自己调试的时间。
  • 4
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值