相关文章推荐
暗恋学妹的柳树  ·  vary origin ...·  3 年前    · 
豪气的青蛙  ·  ​day023: ...·  3 年前    · 
Long id; @Id
@GeneratedValue(generator="generator")
@GenericGenerator(name="generator", strategy = "native") public Long getId() { return id; } public void setId(Long id) { this .id = id; }

Hibernate 可以对类的属性或者方法进行注解。属性对应field类别,方法的 getXxx()对应property类别。

@Entity

声明一个类为实体Bean。

@Table

说明此实体类映射的表名,目录,schema的名字。

声明此表的主键。

@GeneratedValue

定义主键的增长策略。我这里一般交给底层数据库处理,所以调用了名叫generator的增长方式,由下边的 @GenericGenerator 实现

@GenericGenerator

hibernate内部的主键增长方式.

关于 @GeneratedValue 和 @GenericGenerator 的详细说明,在我的另一篇转载的文章里边有。
@GeneratedValue 与 @GenericGenerator

@Table(name="tbl_sky",
uniqueConstraints = {@UniqueConstraint(columnNames={"month", "day"})} )

@UniqueConstraint

将对应的字段设置唯一性标识

(注: UniqueConstraint 只在 hibernate.hbm2ddl.auto设置为create-drop 才会起作用)

1 public class Flight implements Serializable {
2    @Version 
3    @Column(name="OPTLOCK") 
4     public Integer getVersion() {} } 

@Version

注解用于支持乐观锁版本控制。一般可以用 数字 或者 timestamp 类型来支持 version.

@Column

用于映射对应的字段,其中参数详解如下:

name = "columnName"; (1)
boolean unique() default false; (2)
boolean nullable() default true; (3)
boolean insertable() default true; (4)
boolean updatable() default true; (5)
String columnDefinition() default ""; (6)
String table() default ""; (7)
int length() default 255; (8)
int precision() default 0; (9)
int scale() default 0; (10)
(1) name 可选,列名(默认值是属性名)
(2) unique 可选 , 是否在该列上设置唯一约束(默认值false)
(3) nullable 可选 , 是否设置该列的值可以为空(默认值true)
(4) insertable 可选 , 该列是否作为生成的insert语句中的一个列(默认值true)
(5) updatable 可选 , 该列是否作为生成的update语句中的一个列(默认值true)
(6) columnDefinition 可选 , 为这个特定列覆盖SQL DDL片段 (这可能导致无法在不同数据库间移植)
(7) table 可选 , 定义对应的表(默认为主表)
(8) length 可选 , 列长度(默认值255)
(9) precision 可选 , 列十进制精度(decimal precision)(默认值0)
(10) scale 可选 , 如果列十进制数值范围(decimal scale)可用,在此设置(默认值0)

public class user
    @Transient    
    private Integer id;
    @Basic(fetch=FetchType.LAZY,optional=true)
    private String name;
    @Transient
    public Integer getId() {}
@Temporal(TemporalType.TIME)
public java.util.Date getDatetime() {};

@Transient
     被注解成 @Transient 的 getter 方法或属性,将不会被持久化(自己测试,只有放在getter方法内才起作用)

@Basic
    所有没有定义注解的属性,等价于在其上面添加了 @Basic注解可以声明属性的获取策略 ( fetch strategy )

    fetch:抓取策略,延时加载与立即加载,optional:指定在生成数据库结构时字段是否允许为 null.

@Temporal

    在核心的 Java API 中并没有定义时间精度 ( temporal precision )。因此处理时间类型数据时,你还需要定义将其存储在数据库中所预期的精度。
    在数据库中,表示时间类型的数据有 DATE,TIME,和 TIMESTAMP 三种精度 ( 即单纯的日期,时间,或者两者兼备 )。 可使用 @Temporal 注解来调整精度。

映射实体Bean的关联关系

使用 @OneToOne 注解可以建立实体Bean 之间的一对一关系。一对一关系有3种情况。

• 关联的实体都共享同样的主键。

 @Entity
public class Body {
public Long getId() { return id; }
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public Heart getHeart() {
return heart;
@Entity
public class Heart {
public Long getId() { ...}

通过@PrimaryKeyJoinColumn 注解定义了一对一的关联关系。

其中一个实体通过外键关联到另一个实体的主键。注:一对一,则外键必须为唯一约束。

 @Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name="passport_fk")
public Passport getPassport() {
@Entity
public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {

通过@JoinColumn注解定义一对一的关联关系。如果没有@JoinColumn注解,则系统自动处理,在主表中将创建连接列,列名为:主题的关联属性名 + 下划线 + 被关联端的主键列名。上例为 passport_id, 因为Customer 中关联属性为 passport, Passport 的主键为 id.

通过关联表来保存两个实体之间的关联关系。注:一对一,则关联表每个外键都必须是唯一约束。

 @Entity
public class Customer implements Serializable {
@OneToOne(cascade = CascadeType.ALL)
@JoinTable(name = "CustomerPassports",
joinColumns = @JoinColumn(name="customer_fk"),
inverseJoinColumns = @JoinColumn(name="passport_fk")
public Passport getPassport() {
@Entity public class Passport implements Serializable {
@OneToOne(mappedBy = "passport")
public Customer getOwner() {

Customer 通过 CustomerPassports 关联表和 Passport 关联。该关联表通过 passport_fk 外键指向 Passport 表,该信心定义为 inverseJoinColumns 的属性值。 通过 customer_fk 外键指向 Customer 表,该信息定义为 joinColumns 属性值。

使用 @ManyToOne 注解定义多对一关系。

 @Entity()
public class Flight implements Serializable {
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
@JoinColumn(name="COMP_ID")
public Company getCompany() {
return company;

其中@JoinColumn 注解是可选的,关键字段默认值和一对一关联的情况相似。列名为:主题的关联属性名 + 下划线 + 被关联端的主键列名。本例中为company_id,因为关联的属性是company, Company的主键为 id.

@ManyToOne 注解有个targetEntity属性,该参数定义了目标实体名。通常不需要定义,大部分情况为默认值。但下面这种情况则需要 targetEntity 定义(使用接口作为返回值,而不是常用的实体)。

 @Entity()
public class Flight implements Serializable {
@ManyToOne(cascade= {CascadeType.PERSIST,CascadeType.MERGE},targetEntity= CompanyImpl.class)
@JoinColumn(name="COMP_ID")
public Company getCompany() {
return company;
public interface Company {
多对一也可以通过关联表的方式来映射,通过@JoinTable
注解可定义关联表。该关联表包含指回实体的外键(通过@JoinTable.joinColumns)以及指向目标实体表的外键(通过@JoinTable.inverseJoinColumns).

 @Entity()
public class Flight implements Serializable {
@ManyToOne( cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
@JoinTable(name="Flight_Company",
joinColumns = @JoinColumn(name="FLIGHT_ID"),
inverseJoinColumns = @JoinColumn(name="COMP_ID")
public Company getCompany() {
return company;

非主键多对一关联:

A表:sn   B表:cp_sn

A表配置:

 1 private List<B> sns;  
 3         @OneToMany(mappedBy = "a", fetch = FetchType.LAZY)  
 4         public List<B> getSns() {  
 5             return sns;  
 8         public void setSns(List<B> sns) {  
 9             this.sns = sns;  

B表配置:

1     private A a;  
3




    
         @ManyToOne(fetch = FetchType.LAZY)  
4         @JoinColumn(name = "CP_SN", referencedColumnName="sn",  insertable = false, updatable = false)  
5         public A getA() {  
6             return a;  

 name = "CP_SN" -- 本表中的字段

 referencedColumnName="sn" -- 关联表的字段

@OneToMany 注解可定义一对多关联。一对多关联可以是双向的。

规范中多对一端几乎总是双向关联中的主体(owner)端,而一对多的关联注解为 @OneToMany(mappedBy=)

 @Entity
public class Troop {
@OneToMany(mappedBy="troop")
public Set<Soldier> getSoldiers() {
@Entity
public class Soldier {
@ManyToOne
@JoinColumn(name="troop_fk")
public Troop getTroop() {

Troop 通过troop属性和Soldier建立了一对多的双向关联。在 mappedBy 端不必也不能定义任何物理映射。

 @Entity
public class Customer implements Serializable {
@OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
@JoinColumn(name="CUST_ID")
public Set<Ticket> getTickets() {
@Entity
public class Ticket implements Serializable {
... //no bidir

一般通过连接表来实现这种关联,可以通过@JoinColumn注解来描述这种单向关联关系。上例 Customer 通过 CUST_ID 列和 Ticket 建立了单向关联关系。

通过关联表来处理单向关联

 @Entity
public class Trainer {
@OneToMany
@JoinTable(
name="TrainedMonkeys",
joinColumns = @JoinColumn( name="trainer_id"),
inverseJoinColumns = @JoinColumn( name="monkey_id")
public Set<Monkey> getTrainedMonkeys() {
@Entity
public class Monkey {
... //no bidir

通过关联表来处理单向一对多关系是首选,这种关联通过 @JoinTable 注解来进行描述。上例子中 Trainer 通过TrainedMonkeys表和Monkey建立了单向关联关系。其中外键trainer_id关联到Trainer(joinColumns)而外键monkey_id关联到Monkey(inverseJoinColumns).

默认处理机制

通过连接表来建立单向一对多关联不需要描述任何物理映射,表名由一下3个部分组成,主表(owner table)表名 + 下划线 + 从表(the other side table)表名。指向主表的外键名:主表表名+下划线+主表主键列名 指向从表的外键定义为唯一约束,用来表示一对多的关联关系。

 @Entity
public class Trainer {
@OneToMany
public Set<Tiger> getTrainedTigers() {
@Entity
public class Tiger {
... //no bidir

上述例子中 Trainer 和 Tiger 通过 Trainer_Tiger 连接表建立单向关联关系。其中外键 trainer_id 关联到 Trainer表,而外键 trainedTigers_id 关联到 Tiger 表。

通过@ManyToMany 注解定义多对多关系,同时通过 @JoinTable 注解描述关联表和关联条件。其中一端定义为 owner, 另一段定义为 inverse(对关联表进行更新操作,这段被忽略)。

// 维护端注解
@ManyToMany (cascade = CascadeType.REFRESH)
@JoinTable (//关联表
           name =  "student_teacher" , //关联表名
           inverseJoinColumns =  @JoinColumn (name =  "teacher_id" ),//被维护端外键
           joinColumns =  @JoinColumn (name =  "student_id" ))//维护端外键被维护端注解
@ManyToMany(cascade = CascadeType.REFRESH,
            mappedBy = "teachers",//通过维护端的属性关联
            fetch = FetchType.LAZY)
// 关系维护端删除时,如果中间表存在些纪录的关联信息,则会删除该关联信息;
// 关系被维护端删除时,如果中间表存在些纪录的关联信息,则会删除失败 .

关联表名:主表表名 + 下划线 + 从表表名;关联表到主表的外键:主表表名 + 下划线 + 主表中主键列名;关联表到从表的外键名:主表中用于关联的属性名+ 下划线 + 从表的主键列名。

用 cascading 实现传播持久化(Transitive persistence)

cascade 属性接受值为 CascadeType 数组,其类型如下:

• CascadeType.PERSIST: cascades the persist (create) operation to associated entities persist() is called or if the entity is managed 如果一个实体是受管状态,或者当 persist() 函数被调用时,触发级联创建(create)操作。

CascadeType.MERGE: cascades the merge operation to associated entities if merge() is called or if the entity is managed 如果一个实体是受管状态,或者当 merge() 函数被调用时,触发级联合并(merge)操作。

CascadeType.REMOVE: cascades the remove operation to associated entities if delete() is called 当 delete() 函数被调用时,触发级联删除(remove)操作。

CascadeType.REFRESH: cascades the refresh operation to associated entities if refresh() is called 当 refresh() 函数被调用时,出发级联更新(refresh)操作。

CascadeType.ALL: all of the above 以上全部

其他属性:

@Enumerated
@javax.persistence.Enumerated(EnumType.STRING)
value:EnumType.STRING,EnumType.ORDINAL
枚举类型成员属性映射,EnumType.STRING指定属性映射为字符串,EnumType.ORDINAL指定属性映射为数据序

@javax.persistence.Lob
用于标注字段类型为Clob和Blob类型
Clob(Character Large Ojects)类型是长字符串类型,实体的类型可为char[]、Character[]、或者String类型
Blob(Binary Large Objects)类型是字节类型,实体的类型可为byte[]、Byte[]、或者实现了Serializable接口的类。
通常使用惰性加载的方式, @Basic(fetch=FetchType.LAZY)

@SecondaryTable 
@javax.persistence.SecondaryTable
将一个实体映射到多个数据库表中

@Entity
@SecondaryTables({ 
@SecondaryTable(name = "Address"), 
    @SecondaryTable(name = "Comments") 
public class Forum implements Serializable {
@Column(table = "Address", length = 100) 
private String street; 
@Column(table = "Address", nullable = false) 
private String city; 
@Column(table = "Address") 
private String conutry; 
@Column(table = "Comments") 
private String title; 
@Column(table = "Comments") 
private String Comments; 
@Column(table = "Comments") 

table属性的值指定字段存储的表名称 没有用 @Column 注解改变属性默认的字段将会存在于 Forum 表

@Index

给某一字段加索引

@Table(name = "tab_developer", indexes = {@Index(columnList = "username")})

根据注解,将会给username字段加上索引