您的位置:首页 > 其它

hibernate 注释多表 级联操作

2016-03-16 10:08 267 查看
一对多模型(单向)
说明:一个客户对应多个地址,通过客户可以获得该客户的多个地址的信息。客户和地址是一对多的关系,并且客户与地址是单向关联的关系。

映射策略
#外键关联:两个表的关系定义在一个表中;
#表关联:两个表的关系单独定义一个表中通过一个中间表来关联。

映射策略——外键关联

表结构如下:
TABLEcustomer(idint,namevarcher,PRIMARYKEYid)
TABLEaddress(idint,address_namevarcher,zipcodevarcher,cityvarcher,customer_idint,PRIMARYKEYid)

表address中的customer_id为customer表中的id的值,通过customer_id可以找到相应的customer的记录。
将表customer映射为CustomerEO实体,代码如下:
@Entity
@Table(name="customer")
publicclassCustomerEOimplementSerializable{
@Id
@GeneratedValue(stragegy=GenerationType=AUTO)
privateintid;

@OneToMany(casade={CascadeTypeType.ALL})
@JoinColumn(name="customer_id")
publicCollection<AddressEO>getAddress(){
returnaddress;
}
....
}

一对多@OneToMany注解说明:
@Target({METHOD,FIELD})@Retention(RUNTIME)
public@interfaceOneToMany{
ClasstargetEntity()defaultvoid.class;
CascadeType[]cascade()default{};
FetchTypefetch()defaultEAGER;
StringmappedBy()default"";
}
#targetEntity属性表示默认关联的实体类型,默认为当前标注的实体类;
因为一对多的实体集合时保存在集合类中,因此必须指明集合类中保存的具体类型:
1)指定集合泛型的具体类型;如:publicCollection<AddressEO>getAddress(){...
2)指定targetEntity属性类型;如:@OneToMany(targetEntity=AddressEO.class,casade={CascadeTypeType.ALL})
#cascade属性表示与此实体一对一关联的实体的联级样式类型。联级样式上当对实体进行操作时的策略。
说明:在定义关系时经常会涉及是否定义Cascade(级联处理)属性,担心造成负面影响.
·不定义,则对关系表不会产生任何影响
·CascadeType.PERSIST(级联新建)
·CascadeType.REMOVE(级联删除)
·CascadeType.REFRESH(级联刷新)
·CascadeType.MERGE(级联更新)中选择一个或多个。
·还有一个选择是使用CascadeType.ALL,表示选择全部四项
#fetch属性是该实体的加载方式,有两种:LAZY和EAGER。默认为惰性加载,一般也建议使用惰性加载。
#mappedBy属性用于双向关联实体时使用。

映射策略——表关联
在具体的设计中我们也会使用到使用另外单独的一张表来关联实体关系。比如customer和address例子中,我们增加一张ref_customer_address表保存以上两表的关系。
表结构如下:
TABLEcustomer(idint,namevarcher,PRIMARYKEYid)
TABLEaddress(idint,address_namevarcher,zipcodevarcher,cityvarcher,PRIMARYKEYid)
TABLEref_customer_address(customer_idintnotnull,address_idintnotnullunique)
将表customer映射为CustomerEO实体,代码如下:
@Entity
@Table(name="customer")
publicclassCustomerEOimplementSerializable{
@Id
@GeneratedValue(stragegy=GenerationType=AUTO)
privateintid;

@OneToMany(casade={CascadeTypeType.ALL})
@JoinTable(name="ref_customer_address",
joinColumn={@JoinColumn(name="customer_id",referencedColumnName="id")},
inverseJoinColumn={@JoinColumn(name="address_id",referencedColumnName="id")}
)
publicCollection<AddressEO>getAddress(){
returnaddress;
}
....
}

表关联(@JoinTable)注解说明:
@Target({METHOD,FIELD})
public@interfaceJoinTable{
Stringname()default"";
Stringcatalog()default"";
Stringschema()default"";
JoinColumn[]joinColumns()default{};
JoinColumn[]inverseJoinColumns()default{};
UniqueConstraint[]uniqueConstraintsdefault{};
}
#name属性为连接两个表的表名称。若不指定,则使用默认的表名称,格式如下:
"表名1"+"_"+"表名2"
#joinColumn属性表示,在保存关系的表中,所保存关联关系的外键的字段,并配合@JoinColumn标记使用;
#inverseJoinColumn属性与joinColumn类似,它保存的是保存关系的另外一个外键字段;
#catalog和schema属性表示实体指定点目录名称或数据库名称;
#uniqueConstraints属性表示该实体所关联的唯一约束条件,一个实体可以有多个唯一约束条件,默认没有约束;

注意:@JoinTable不仅能够定义一对多的关联,也可以定义多对多表的关联。

默认关联
如果使用了表关联,并且该表又设置了外键,则在映射的实体关系时可以使用默认的映射关系设置,举例如下:
表结构如下:
TABLEcustomer(idint,namevarcher,PRIMARYKEYid)
TABLEaddress(idint,address_namevarcher,zipcodevarcher,cityvarcher,PRIMARYKEYid)
TABLEref_customer_address(customer_idintnotnull,address_idintnotnullunique)
创建customer_id外键
ALTERTABLEref_customer_addressADDCONSTRAINTfk_ref_customerFOREIGNKEY(customer_id)REFERENCEScustomer(id);
创建address_id外键
ALTERTABLEref_customer_addressADDCONSTRAINTfk_ref_addressFOREIGNKEY(address_id)REFERENCESaddress(id);

映射实体CustomerEO的代码如下:
@Entity
@Table(name="customer")
publicclassCustomerEOimplementSerializable{
@Id
@GeneratedValue(stragegy=GenerationType=AUTO)
privateintid;

@OneToMany
publicCollection<AddressEO>getAddress(){
returnaddress;
}
....
}

/*
*@ManyToOne指明OrderItem和Order之间为多对一关系,多个OrderItem实例关联的都是同一个Order对象。
*其中的属性和@OneToMany基本一样,但@ManyToOne注释的fetch属性默认值是FetchType.EAGER。
*
*optional属性是定义该关联类对是否必须存在,值为false时,关联类双方都必须存在,如果关系被维护端不存在,查询的结果为null。
*值为true时,关系被维护端可以不存在,查询的结果仍然会返回关系维护端,在关系维护端中指向关系被维护端的属性为null。
*optional属性的默认值是true。举个例:某项订单(Order)中没有订单项(OrderItem),如果optional属性设置为false,
*获取该项订单(Order)时,得到的结果为null,如果optional属性设置为true,仍然可以获取该项订单,但订单中指向订单项的属性为null。
*实际上在解释Order与OrderItem的关系成SQL时,optional属性指定了他们的联接关系optional=false联接关系为innerjoin,
*optional=true联接关系为leftjoin。
*
*@JoinColumn:指明了被维护端(OrderItem)的外键字段为order_id,它和维护端的主键(orderid)连接,unique=true指明order_id列的值不可重复。
*/
@ManyToOne(cascade=CascadeType.REFRESH,optional=false)
@JoinColumn(name="order_id",referencedColumnName="orderid")
publicOrdergetOrder(){
returnorder;
}


                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: