Hibernate one to many 映射配置

来源:互联网 发布:mac版tomcat下载 编辑:程序博客网 时间:2024/06/05 15:17

多对一关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是多指向一
一对多关联映射:在多的一端加入一个外键指向一的一端,它维护的关系是一指向多

也就是说一对多和多对一的映射策略是一样的,只是站的角度不同


用户表:

CREATE TABLE `tbl_user` 

(`id` INT(32) NOT NULL AUTO_INCREMENT,`user_name` VARCHAR(20) NULL DEFAULT NULL,

`password` VARCHAR(20) NULL DEFAULT NULL,PRIMARY KEY (`id`)

)

银行卡表:

CREATE TABLE `tbl_bank` 

(`id` INT(10) NOT NULL AUTO_INCREMENT,`bank_card` VARCHAR(50) NULL DEFAULT NULL,

`user_id` INT(10) NULL DEFAULT '0',PRIMARY KEY (`id`),

INDEX `FK__tbl_user` (`user_id`),

CONSTRAINT `FK__tbl_user` FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

)

1.单向一对多:只需在放进行配置

public class Users {

private int id;

private String userName;

private String password;

private Set<Bank> bank=new HashSet<Bank>();

}

<hibernate-mapping>

<class name="wb.wk.review.mapping.onetomany.sigenlMapping.Users" table="tbl_user">

<id name="id" column="id" type="Java.lang.Integer">

<generator class="identity"></generator>

</id>

<property name="userName" type="java.lang.String" column="user_name"/>

<property name="password" type="java.lang.String" column="password"/>

<!-- 一对多单向关联 -->

<set name="bank" table="tbl_bank" cascade="all" inverse="false">

<key column="user_id" /><!-- 确定关联的外键列 -->

            <one-to-many class="wb.wk.review.mapping.onetomany.sigenlMapping.Bank"/>

</set>

</class>

</hibernate-mapping>

public class Bank {

private int id;

private String bankCard;

private int userId;//不是users对象

}

<hibernate-mapping>

<class name="wb.wk.review.mapping.onetomany.sigenlMapping.Bank" table="tbl_bank">

<id name="id" column="id" type="java.lang.Integer">

<generator class="identity"></generator>

</id>

<property name="bankCard" type="java.lang.String" column="bank_card"/>

<!-- 一对多单向关联 -->

<!--外键-->

<property name="userId" type="java.lang.Integer" column="user_id"/>

</class>

</hibernate-mapping>

2.双向一对多:

一是关系维护端(owner side),多是关系被维护端(inverse side

需要在关联双方都加以配置,而且需要在一的一方设置inverse=true

 

public class Bank {

private int id;

private String bankCard;

private Users users;

}


Bank xml

<hibernate-mapping>

<class name="wb.wk.review.mapping.onetomany.bean.Bank" table="tbl_bank">

<id name="id" column="id" type="java.lang.Integer">

<generator class="identity"></generator>

</id>

<property name="bankCard" type="java.lang.String" column="bank_card"/>

<many-to-one name="users" class="wb.wk.review.mapping.onetomany.bean.Users" column="user_id"></many-to-one>

</class>

</hibernate-mapping>

 

public class Users {

private int id;

private String userName;

private String password;

private Set<Bank> bank;

}

User xml

<hibernate-mapping>

<class name="wb.wk.review.mapping.onetomany.bean.Users" table="print_user">

<id name="id" column="id" type="java.lang.Integer">

<generator class="identity"></generator>

</id>

<property name="userName" type="java.lang.String" column="user_name"/>

<property name="password" type="java.lang.String" column="password"/>

<set name="bank" table="tbl_bank" cascade="all">

<key column="user_id" /><!-- 确定关联的外键列 -->

            <one-to-many class="wb.wk.review.mapping.onetomany.bean.Bank" />

</set>

</class>

</hibernate-mapping>

测试的main方法:

Session session=null;

Transaction tran=null;

try {

session=HibernateSessionFactory.getSession();

tran=session.beginTransaction();

Users users=new Users();

users.setUserName("lko");

users.setPassword("1213456");

Set<Bank> bakSet=new HashSet<Bank>();

Bank b1=new Bank();

b1.setBankCard("s_001");

b1.setUsers(users);

Bank b2=new Bank();

b2.setBankCard("s_002");

b2.setUsers(users);

Bank b3=new Bank();

b3.setBankCard("s_003");

b3.setUsers(users);

bakSet.add(b1);

bakSet.add(b2);

bakSet.add(b3);

users.setBank(bakSet);

session.save(users);

tran.commit();

catch (HibernateException e) {

tran.rollback();

e.printStackTrace();

}finally{

session.flush();

session.close();

}

如果在“一”的一方在加上:inverse="true",如下:

<set name="bank" table="tbl_bank" cascade="all" inverse="true">

<key column="user_id" /><!-- 确定关联的外键列 -->

            <one-to-many class="wb.wk.review.mapping.onetomany.bean.Bank"/>

</set>

发现update语句没了。

这是因为:在一对多中,如果要""方维护关系,就会在插入或是删除""方时去update""方的每一个与这个""的对象有关系的对象。
而如果让" "方面维护关系时就不会有update操作,因为关系就是在多方的对象中的,直指插入或是删除多方对象就行了。
当然这时也要遍历""方的每一个对象显示的操作及关系的变化体现到DB中。不管怎样说,还是让""方维护关系更直观一些。

关于inverse的作用

在hibernate中是通过inverse的设置来决定是有谁来维护表和表之间的关系的。

我们说inverse设立不当会导致性能低下,其实是说inverse设立不当,会产生多余重复的SQL语句甚至致使JDBC exception的throw。这是我们在建立实体类关系时必须需要关注的地方。一般来说,inverse=true是推荐使用,双向关联中双方都设置 inverse=false的话,必会导致双方都重复更新同一个关系。但是如果双方都设立inverse=true的话,双方都不维护关系的更新,这也是 不行的,好在一对多中的一端:many-to-one默认是inverse=false,避免了这种错误的产生。但是多对多就没有这个默认设置了,所以很 多人经常在多对多的两端都使用inverse=true,结果导致连接表的数据根本没有记录,就是因为他们双分都没有责任维护关系。所以说,双向关联中最 好的设置是一端为inverse=true,一端为inverse=false。一般inverse=false会放在多的一端,那么有人提问了, many-to-many两边都是多的,inverse到底放在哪儿?其实hibernate建立多对多关系也是将他们分离成两个一对多关系,中间连接一个连接表。所以通用存在一对多的关系,也可以这样说:一对多是多对多的基本组成部分。



原创粉丝点击