首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

hibernate实业关联注解版

2012-07-18 
hibernate实体关联注解版????? 以前用ssh做小项目的时候都是先建数据库再来写Model层,但是总觉得这样就太

hibernate实体关联注解版

????? 以前用ssh做小项目的时候都是先建数据库再来写Model层,但是总觉得这样就太浪费别人hibernate创始人的初衷,原原本本的ORM框架被我那么一用,面对对象的思想压根就没体现出来,于是今天就试了一把先建Model层,然后直接用 hibernate自带的工具hbm2ddl生成数据库表。其中最难搞的就是实体之间的关联关系,什么一对一,一对多,多对多,又是单向关联又是多向关联的,弄得自己头晕乎乎的,想着还是把它记下来,留着以后看看,俗话说“发表是最好的记忆”。

????一对一:

?? 使用@OneToOne注解可以建立实体bean之间的一对一的关联. 一对一关联有三种情况:

???①关联的实体都共享同样的主键

?? ②是其中一个实体通过外键关联到另一个实体的主键 (注意要模拟一对一关联必须在外键列上添加唯一约束).

?? ③过关联表来保存两个实体之间的连接关系 (注意要模拟一对一关联必须在每一个外键上添加唯一约束).

???

?? ?共享主键来进行一对一关联映射

@Entity
public class Body {
@Id
public Long getId() { return id; }

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

??? 表模型

??? mysql> DESCRIBE heart;
? ? +-------+------------+------+-----+---------+----------------+
? ? | Field | Type?????? | Null | Key | Default | Extra????????? |
? ? +-------+------------+------+-----+---------+----------------+
? ? | id??? | bigint(20) | NO?? | PRI | NULL??? | auto_increment |
??? +-------+------------+------+-----+---------+----------------+

?

? ? mysql> desc body;
? +-------+------------+------+-----+---------+-------+
? | Field | Type?????? | Null | Key | Default | Extra |
? +-------+------------+------+-----+---------+-------+
? | id??? | bigint(20) | NO?? | PRI | NULL??? |?????? |
? +-------+------------+------+-----+---------+-------+

?? 生成的SQL脚本

?? create table Body (
??????? id bigint not null,
??????? primary key (id)
??? )

??? create table Heart (
??????? id bigint not null auto_increment,
??????? primary key (id)
??? )

?

? ? 外键列进行实体的关联

@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() {
...
}

??? 表模型

? ? mysql>? DESCRIBE customer;
?? ?+-------------+--------------+------+-----+---------+----------------+
?? ?| Field?????? | Type???????? | Null | Key | Default | Extra????????? |
????+-------------+--------------+------+-----+---------+----------------+
? ? | id????????? | bigint(20)?? | NO?? | PRI | NULL??? | auto_increment |
? ??| name??????? | varchar(255) | YES? |???? | NULL??? |??????????????? |
?? ?| passport_fk | bigint(20)?? | YES? | MUL | NULL??? |??????????????? |
? ?+-------------+--------------+------+-----+---------+----------------+

?

? mysql>? DESCRIBE passport;
? +-------+------------+------+-----+---------+----------------+
??| Field | Type?????? | Null | Key | Default | Extra????????? |
??+-------+------------+------+-----+---------+----------------+
? | id??? | bigint(20) | NO?? | PRI | NULL??? | auto_increment |
??+-------+------------+------+-----+---------+----------------+??生成的sql脚本

??create table Customer (
??????? id bigint not null auto_increment,
??????? name varchar(255),
??????? passport_fk bigint,
??????? primary key (id)
??? )

? create table Passport (
??????? id bigint not null auto_increment,
??????? primary key (id)
??? )

? alter table Customer
??????? add index FK27FBE3FEDB47C7A (passport_fk),
??????? add constraint FK27FBE3FEDB47C7A
??????? foreign key (passport_fk)
??????? references Passport (id)

? 上面这个例子中,Customer 通过Customer 表中名为的passport_fk 外键列和 Passport关联. @JoinColumn注解定义了联接列(join column). 该注解和@Column注解有点类似, 但是多了一个名为referencedColumnName的参数. 该参数定义了所关联目标实体中的联接列. 注意,当referencedColumnName关联到非主键列的时候, 关联的目标类必须实现Serializable, 还要注意的是所映射的属性对应单个列(否则映射无效).

一对一关联可能是双向的.在双向关联中, 有且仅有一端是作为主体(owner)端存在的:主体端负责维护联接列(即更新). 对于不需要维护这种关系的从表则通过mappedBy属性进行声明. mappedBy的值指向主体的关联属性. 在上面这个例子中,mappedBy的值为 passport. 最后,不必也不能再在被关联端(owned side)定义联接列了,因为已经在主体端进行了声明.

如果在主体没有声明@JoinColumn,系统自动进行处理: 在主表(owner table)中将创建联接列, 列名为:主体的关联属性名+下划线+被关联端的主键列名. 在上面这个例子中是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() {
...
}

?? 表模型
?? mysql>? DESCRIBE CustomerPassports;
??+-------------+------------+------+-----+---------+-------+
??| Field?????? | Type?????? | Null | Key | Default | Extra |
? +-------------+------------+------+-----+---------+-------+
? | passport_fk | bigint(20) | YES? | MUL | NULL??? |?????? |
? | customer_fk | bigint(20) | NO?? | PRI | NULL??? |?????? |
? +-------------+------------+------+-----+---------+-------+

?

?mysql>? DESCRIBE customer;
?+-------+--------------+------+-----+---------+----------------+
?| Field | Type???????? | Null | Key | Default | Extra????????? |
?+-------+--------------+------+-----+---------+----------------+
?| id??? | bigint(20)?? | NO?? | PRI | NULL??? | auto_increment |
?| name? | varchar(255) | YES? |???? | NULL??? |??????????????? |
?+-------+--------------+------+-----+---------+----------------+

?

?mysql>? DESCRIBE passport;
?+-------+------------+------+-----+---------+----------------+
?| Field | Type?????? | Null | Key | Default | Extra????????? |
?+-------+------------+------+-----+---------+----------------+
?| id??? | bigint(20) | NO?? | PRI | NULL??? | auto_increment |
?+-------+------------+------+-----+---------+----------------+

?

?

Customer通过名为 CustomerPassports的关联表和 Passport关联; 该关联表拥有名为passport_fk的外键列,该 外键指向Passport表,该信息定义为inverseJoinColumn的属性值, 而customer_fk外键列指向Customer表, 该信息定义为 joinColumns的属性值.

这种关联可能是双向的.在双向关联中, 有且仅有一端是作为主体端存在的:主体端负责维护联接列(即更新). 对于不需要维护这种关系的从表则通过mappedBy属性进行声明. mappedBy的值指向主体的关联属性. 在上面这个例子中,mappedBy的值为 passport. 最后,不必也不能再在被关联端(owned side)定义联接列了,因为已经在主体端进行了声明.

你必须明确定义关联表名和关联列名.

?

一对多,多对多的关联基本上都是这三类方式关联,而单向还是双向则看是否持有对方的引用。在双向关联中, 有且仅有一端是作为主体端存在的:主体端负责维护联接列(即更新). 对于不需要维护这种关系的从表则通过mappedBy属性进行声明. mappedBy的值指向主体的关联属性。注意在一对多的关系都是在多端负责维护,一端则通过mappedBy,再设置fetch的属性为fetch.LAZY则可以尽量避免1+n的问题。

暂时写这么多吧,更详细的请参考hibernate官网?。。


?

热点排行