Hibernate(6)——注解的使用

Hibernate注解的简介


Hibernate注解基于JPA2规范,并支持其所有功能,它的分类可以分为:类级别的注解,属性级别的注解以及映射关系的注解。所有JPA注释都在javax.persistence.*包中定义。 Hibernate EntityManager实现由JPA规范定义的接口和生命周期。

使用注解的优势

使用hibernate注释的核心优点是我们不需要创建映射(*.hbm.xml)文件直接创建对象关联。 在这里,hibernate注释用于提供元数据。
关于注解,我们可以从不同级别的角度来进行介绍,这样显得比较有条理,也方便学习记忆。

类级别注解


  • @Entity:将目标类标注为实体。它有一个属性name,表示的是映射到数据库的表名。一般默认不设置,此时实体类与数据库表名一致。需要注意的是,使用@Entity 需要指定实体类的主键属性(利用@Id 来生成)。
  • @Table:注释指定要保留此实体的数据的表名。 如果不使用@Table注释,hibernate将使用类名作为表名称bydefault。常用的属性有name,catalog以及schema,@Table通常和@Entity配合使用,只能注解在实体类上,表示实体对应的数据库表信息。name是可选属性,表示映射表的名称,默认表名和实体名称一致,只有在不一致时才需要指定表名。catalog也是可选,表示目录,默认为空。schema表示数据库的模式。从数据库的结构而言,数据库系统中可以有很多个目录,然后一个目录下又可以有多个schema,schema下又可以有多个数据库对象,但是不同的数据库对于schema和catalog的支持又是有差别的,例如ORACLE和M有SQL就并不支持catalog这个属性,但支持schema,SQLSERVER支持schema和catalog,DB2的支持又不一样。MySQL中,默认schema为数据库名,ORACLE中则是用户名。
  • @Embbadable:表示该类为嵌入类。被注解的类并非实体类,但是可以作为实体类的一个属性而存在。

属性级别注解


  • @Id :定义了映射到数据库的主键的属性。一个实体类可以有一个或者多个属性被映射为主键,但是需要注意,如果一个类有多个属性被映射为主键(也就是所谓的复合主键),那么该类需要实现Serializable接口,如果联合主键中使用到字符串,那么还应该在@Column中指定该字段的长度,默认的vachar(255)是不合适的。
  • @SquenceGenerator:不常用,省略先。
  • @GeneratedValue:它是可选的,该注解有两个属性,一个是strategy,用于指定主键生成策略,取值有:GenerationType.AUTO:根据底层数据库自动选择,例如MySQL的自动策略为increment,字符串不能自增长,此时应当指定生成器(@GenerationValue(strategy="xxx"),@GenericGenerator(name="xxx",strategy="assigned"));GenerationType.IDENTITY:根据数据库的Identity字段生成;GenerationType.SQUENCE:使用Squence来决定主键的取值,例如Oracle没有increment,那么就可以选择Squence来实现自动增长;GenerationType.TABLE:使用指定表来决定取值,可以结合@TableGenerator使用。另一个是generator,为主键生成器
  • @Column:将实体类的属性映射为表中的字段,@Column描述了数据库表中字段的详细定义,这对于根据JPA生成数据库表的工具非常有用。常用属性:name:可选,表示数据库中字段的名称,默认与属性名称一致;nullable:可选,表示该字段是否允许为null,默认为true;unique:可选,表示该字段是否位唯一标识,默认为false;length:可选,表示该字段的大小,仅对String类型的属性有效,默认为255,如果是主键,不能使用默认值;insertable:可选,表示在ORM框架执行插入操作时,该字段是否应出现在insert语句中,默认为true;updateable:可选,表示在ORM框架执行更新操作时,该字段是否应出现在update语句中,默认为true。对于一经创建就不可更改的字段,例如Date,就十分有用。
  • @Embedded:表示某个属性是个嵌入类,需要注意的是,嵌入类上同时也需要标注@Emeddable注解
  • @EmbeddedId:用于嵌入类式主键类实现复合主键。注意:嵌入式主键类必须实现Serializable接口,必须有默认的public无参构造方法,必须覆盖equals以及hashCode方法
  • @Lob: 略
  • @Version: 略
  • @Basic: 略
  • @Transient: 可选,表示该属性并非映射到数据库表中的一个字段,ORM框架将忽略该属性,如果一个属性并非映射到数据库中的字段,那么就应该标为@Transient,否则,ORM框架将默认其注解为@Basic

关系映射级别的注解


实体之间的关系

常见的有一对一,例如一个人只能对应一个身份证号;一对多,一个人可以有多个微信;多对多,例如,一个项目可以有多个开发人员,一个开发人员可以承担多个项目的开发工作。

一对一的单向外键关联

这里使用到的主要是:

  • @OneToOne:它的属性cascade,表示级联关系,这与我们之前在所提到的级联是相同的。
  • @JoinColumn:表示把被控类的外键要写到主控类中,name表示外键名称,unique为true时表示唯一。注意:在保存时应该先保存外键对象,再保存主表对象。
    上述注解使用在主控类所持有的被控类实例上,或者其getter访问器上。

一对一的双向外键关联关系

所谓双向,即是双方均持有对方的实例。
首先主控方的配置与单向的外键关联关系是相同的。被控方需要添加@OneToOne注解,该注解标注在被控方所持有的主控方的实例上,并使用它的mappedBy属性指明外键。需要注意,受控方的mappedBy是必须要设置的,因为双向关联只能交由一方来控制,不可能在双方都设置外键来保存关联关系,否则双方都无法保存。
如果要使用一对一的双向外键联合主键,那么需要创建一个主键类,再强调一遍,主键类需要实现Serializable接口,有默认无参构造方法,重写hashCode()以及equals()方法。主键类上添加@Embeddable注解,实体类上的对于主键类的引用则添加@EmbeddedId

多对一的单向外键关联关系

所谓多对一关联关系,在我们使用映射文件配置Hibernate时,多个学生属于一个班级就是很好的例子。这里我们需要使用到的注解如下:

  • @ManyToOne:它有两个属性,一个是cascade,依然用于指定级联关系,以及fetch,是指某种抓取策略,默认为FetchType.EAGER,表示积极加载模式。
  • @JoinColumn:表示多方持有一方的引用,name属性用于指定一方的外键,referencedColumName表示该外键映射到数据库表中的字段名。依然要先行保存受控方。

一对多的单向外键关联关系

指一方持有多方的集合,即Set,它需要在一方添加如下注解:

  • @OneToMany:两个属性,cascade以及fetch,抓取策略一般使用懒加载,作用与上文中多对一一样。
  • @JoinColumn:name属性和上文中一致。
    这里说一下抓取策略,多对一时,使用EAGER,一对多时,则使用LAZY

多对一的双向外键关联关系

多方持有一方的引用,一方持有多方的集合。在所持有的对方的关联对象上分别加上上文中一对多,多对一的注解即可。注意,由于这里是双向的关联关系,因此,这里无论先保存多方还是一方,都是可行的。

多对多的单向外键关联关系

一个多方持有另一个多方的对象集合Set ,这里需要一个创建中间表进行支持,中间表可以借由注解自动生成。注解标注在主控方中的受控方对象集合上,注解:

@ManyToMany
@JoinTable(name="xxx",
joinCloumns={@JoinColumn(name="xxx")},
inverseJoinCloumn={@JoinColumn="xxx"})

其中@JoinTable的name属性指定了表名,joinColumn以及inverseJoinColumn指定了控制的字段。

你可能感兴趣的:(javaWEB)