Hibernate学习笔记之关联关系

来源:互联网 发布:mysql statistics 多 编辑:程序博客网 时间:2024/06/05 03:25

这个星期在看《Hibernate开发指南》,边看边动手做了小例子,先记录下来。

Hibernate的关联关系映射主要有三种:
一对一关联
一对多关联
多对多关联

 

一、使用*.hbm.xml配置文件做简单示例

一对一关联包括两种形式:主键关联、唯一外键关联
主键关联:两张关联表通过主键形成一对一的映射关系。Hibernate中通过one-to-one节点对一对一关系进行定义。
示例:一个用户User属于一个组Group
User实体类:


Group实体类:

User.hbm.xml

Group.hbm.xml

测试方法:

 

唯一外键关联:通过增加外键字段实现,这种方式是多对一关系的一个特例。
User类没有变化,Group类中去掉user字段:

User.hbm.xml

Group.hbm.xml

测试方法:

注意:hibernate.cfg.xml的映射文件中不能存在同名文件,即使路径不一样。

 

二、使用JPA实现*.hbm.xml相同的功能
首先,使用JPA需要更改HibernateSessionFactory中Configuration的实现:private  static Configuration configuration = new

AnnotationConfiguration(); 或者在自定义Configuration cfg=new AnnotationConfiguration().configure();
其次,去掉hibernate.cfg.xml中<mapping resource="com/petrochina/onetoone/User.hbm.xml" />部分对映射文件的配置,改为<mapping class="com.petrochina.jpa.User" />
1、一对一

一对一关系有三种情况

示例:用户User、组Group

(1)关联的实体都共享同样的主键

1)一对一双向关联

执行插入测试方法:

Hibernate生成的sql语句如下:

Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into t_user (name, id) values (?, ?)
Hibernate: insert into t_group (name, id) values (?, ?)

查询表里的数据

SQL> select * from t_user;
        ID      NAME                                                                           
--------------------------------------------------------------------------------
       276      csdner                                                                                                                                              

SQL> select * from t_group;
        ID      NAME                                                                           
--------------------------------------------------------------------------------
       276      developer                                                             

可见,User和Group有相同的ID。

执行查询测试方法:

Hibernate生成的sql语句如下:

select user0_.id    as id2_2_,
       user0_.name  as name2_2_,
       group1_.id   as id3_0_,
       group1_.name as name3_0_,
       user2_.id    as id2_1_,
       user2_.name  as name2_1_
  from t_user user0_
  left outer join t_group group1_
    on user0_.id = group1_.id
  left outer join t_user user2_
    on group1_.id = user2_.id
 where user0_.id = ?
 csdner

 developer

可见User和Group通过ID关联。

 

2)一对一单向关联

执行插入测试方法:

Hibernate生成的sql语句如下:

Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into t_user (name, id) values (?, ?)
Hibernate: insert into t_group (name, id) values (?, ?)

查询表里的数据:

SQL> select * from t_user;

        ID NAME
---------- --------------------
       280 csdner

SQL> select * from t_group;

        ID NAME
---------- --------------------
       280 developer

User对象和Group对象也有相同的ID,但是由于是单向的,只能通过Group对象查找对应的User对象。

 

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

 

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

执行插入测试代码:

Hibernate生成的sql语句如下:

Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into t_group (name, id) values (?, ?)
Hibernate: insert into t_user (gp_id, name, id) values (?, ?, ?)

查询表里的数据:

SQL> select * from t_user;

        ID NAME                      GP_ID
---------- -------------------- ----------
       287 csdner                      288

SQL> select * from t_group;

        ID NAME
---------- --------------------
       288 developer

User对象通过group_id 列关联Group对象

 

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

执行插入测试方法:

Hibernate生成的sql语句如下:

Hibernate: select hibernate_sequence.nextval from dual
Hibernate: select hibernate_sequence.nextval from dual
Hibernate: insert into t_group (name, id) values (?, ?)
Hibernate: insert into t_user (name, id) values (?, ?)
Hibernate: insert into t_user_group (group_id, user_id) values (?, ?)

查询表里的数据:

 SQL> select * from t_user;

        ID NAME
---------- --------------------
       313 csdner

SQL> select * from t_group;

        ID NAME
---------- --------------------
       314 developer

SQL> select * from t_user_group;

   USER_ID   GROUP_ID
---------- ----------
       313        314

 

2、一对多

一对多关联包括两种形式:单向一对多关联、双向一对多关联
单向一对多关联只需在“一”方进行配置(onetomany),即通过“一”关联到“多”。双向一对多需要关联双方均加以配置,这样既能通过“一”关联其对应的“多”,也可以通过“多”关联其对应的“一”。以用户TUser和地址TAddress做演示


单向一对多:只在TUser类中维护@OneToMany

测试方法:

对应的Hibernate生成的sql语句如下:
Hibernate: insert into cui_user (name, id) values (?, ?)
Hibernate: insert into cui_addr (addr, zip_code, id) values (?, ?, ?)
Hibernate: insert into cui_addr (addr, zip_code, id) values (?, ?, ?)
Hibernate: update cui_addr set user_id=? where id=?
Hibernate: update cui_addr set user_id=? where id=?
可见单向一对多中Hibernate是先插入TAddress记录,然后再维护关联关系字段user_id.

 

双向一对多:在TUser类中维护@OneToMany,在TAddress类中维护@ManyToOne

 

测试代码:

对应的Hibernate生成的sql语句如下:
Hibernate: insert into cui_user (name, id) values (?, ?)
Hibernate: insert into cui_addr (addr, user_id, zip_code, id) values (?, ?, ?, ?)
Hibernate: insert into cui_addr (addr, user_id, zip_code, id) values (?, ?, ?, ?)
可见在双向一对多关联中在新增TAddress记录时直接将关联字段user_id填充了,相比单向一对多少了两条更新语句。

 

3、多对多

示例:角色Role、权限Privilege

 

测试方法:

对应的Hibernate生成的sql语句如下:
Hibernate: insert into t_privilege (name, id) values (?, ?)
Hibernate: insert into t_privilege (name, id) values (?, ?)
Hibernate: insert into t_role (name, id) values (?, ?)
Hibernate: insert into t_role (name, id) values (?, ?)
Hibernate: insert into t_role_privilege (role_id, privilege_id) values (?, ?)
Hibernate: insert into t_role_privilege (role_id, privilege_id) values (?, ?)
Hibernate: insert into t_role_privilege (role_id, privilege_id) values (?, ?)

 

原创粉丝点击