<三>重温Hibernate one to many 映射配置

原创 2015年07月09日 13:51:49

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

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


用户表:

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>

运行出现异常:

org.hibernate.exception.ConstraintViolationException:  could not insert: [wb.wk.review.mapping.onetomany.sigenlMapping.Bank]

Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException

Cannot add or update a child row: a foreign key constraint fails

 (`ppi`.`tbl_bank`, CONSTRAINT `FK_tbl_bank_tbl_user` FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

 

一看就是外键的问题。查了半天,也看了hibernate文档,没有针对外键这一块的解释。但是两张表必须通过外键关联啊。最后删除了外键约束。插入成功。不知道咋回事。

Hibernate: 

    insert  intotbl_user (user_name, password) values(?, ?)

Hibernate: 

    insert  intotbl_bank(bank_card, user_id) values(?, ?)

Hibernate: 

insert  intotbl_bank(bank_card, user_id) values(?, ?)

Hibernate: 

    insert  intotbl_bank(bank_card, user_id) values(?, ?)

 

Hibernate: 

update tbl_bank set  user_id=? where  id=?

Hibernate: 

    update tbl_bank set  user_id=? where  id=?

 

Hibernate: 

    update tbl_bank set  user_id=? where  id=?

总结:另外要注意inverse属性,当时我设置了true,维护段就交给"一"端user了,结果插入时候先插入bank,后插入user,bank获取不到user_id

就出错了。



 

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();

}

出现异常:

null id in wb.wk.review.mapping.onetomany.bean.Users entry (don't flush the Session after an exception occurs)

原因:

这个异常原因很多,这块主要是我没有设置外键(外键约束因为单向一对多的时候报错给在删除了),

设置后插入数据成功。

执行如下sql语句:

Hibernate: 

    insert into tbl_user(user_name, password) values (?, ?)

Hibernate: 

    insert into tbl_bank(bank_card, user_id) values (?, ?)

Hibernate: 

    insert  into tbl_bank (bank_card, user_id) values (?, ?)

Hibernate: 

    insert into tbl_bank (bank_card, user_id) values  (?, ?)

Hibernate: 

    update tbl_bank set user_id=? where  id=?

Hibernate: 

    update tbl_bank set  user_id=?  where id=?

Hibernate: 

Update tbl_bank  set user_id=? Where id=?

 

如果在“一”的一方在加上: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>

运行main方法:

Hibernate: 

    insert into tbl_user(user_name, password) values (?, ?)

Hibernate: 

    insert into tbl_bank(bank_card, user_id) values (?, ?)

Hibernate: 

    insert  into tbl_bank (bank_card, user_id) values (?, ?)

Hibernate: 

insert into tbl_bank (bank_card, user_id) values  (?, ?)

发现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建立多对多关系也是将他们分离成两个一对多关系,中间连接一个连接表。所以通用存在一对多的关系,也可以这样说:一对多是多对多的基本组成部分。

 

 

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Hibernate关联映射(多对一 --- many-to-one)

Hibernate的关联映射关系有: 多对一 ---- many-to-one 一对多 ---- one-to-many 一对一 ---- one-to-one 多对多 ---- many-t...

hibernate中hbm.xml<many-to-one><one-to-many>中一些属性详解

级联方式的操作说明与配置

hibernate注解版关联映射Many-to-One/Many-to-Many等&异常处理

链接:http://blog.csdn.net/superdog007/article/details/8534443 属性介绍: 1.多对一: span style="font-size:...
  • xn_28
  • xn_28
  • 2017-03-15 16:12
  • 942

Hibernate的配置文件的映射many-to-one错误

先看一下错误 虽然,这么多错误挺吓人的,还有SessionFactory为空,但是其实就一个错误文件是这样的Customer.javapackage ch06.pojo;import jav...

使用注解的Hibernate one-to-many映射

One to many映射关系指的是两个实体间一个实体可以和多个实体有关联关系,但是多的这一端只能和一的这一端的一个实例有关系。它是一个1 到 n的关系。例如在任何的公司员工可以注册多个银行账户,一个...

Hibernate基于注解的双向one-to-many映射关系的实现

2、Hibernate基于注解的双向one-to-many映射关系的实现项目中用到了一对多的实体类关系映射,之前接触的都是基于配置文件的映射实现,但是公司的大部分都是基于注解的,因此自己参考之前的代码...

hibernate映射文件many-to-one 元素属性

name:映射类属性的名字 column:关联的字段 class:关联类的名字 cascade:设置操作中的级联策略 可选值为 all所有操作情况均进行级联、none所有操作情况均不进行级联、s...

hibernate映射技巧one-to-many(单项一对多)

一对多关系在系统实现中也很常见。典型的例子就是父亲与孩子的关系。 而在我们现在的这个示例中,每个用户(TUser)都关联到多个地址(TAddress),如一个用户可能拥有办公室地址、家庭地址等多个地址...

hibernate集合映射,one-to-many,删除集合成员

1、one方映射文件  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">     Mapping file a...
  • joyyq
  • joyyq
  • 2012-03-15 23:37
  • 1482

hibernate映射文件many-to-one元素属性

many-to-one 元素 属性:   name:映射类属性的名字column:关联的字段class:关联类的名字cascade:设置操作中的级联策略 可选值为 all所有操作情况均进...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)