1、创建两个实体类。

    一个实体类是商品类,另一个实体类是商品的分类类。

    在一对多关系的两个实体中,在编写实体类时必须要遵循以下规则:

      (1)在一的那一方的实体中,必须要有一个私有的多那一方的实体对象属性,并且提供公有的getter和setter方法。

        

    private Integer gid;
private String gname;
private String gmessage; /**
* 在一对多关系中,在一的这一方,必须要有一个多的对象的私有属性
* 别提供共有的getter和setter方法。
*/
private Sort sort;
public Sort getSort() {
return sort;
}
public void setSort(Sort sort) {
this.sort = sort;
}

      (2)在多的那一方的实体类中,必须要有一个私有的set集合属性来保存一的那一方的对象,并提供公有的getter和setter属性。

   private Integer sid;
private String gname;
private String gmessage; /**
* 在一对多关系中,在多的那一方,必须要有一个set集合属性来保存一个那个实体
* 并提供共有的getter和setter方法。
*/
private Set<Good> getSet = new HashSet<Good>();
public Set<Good> getGetSet() {
return getSet;
}
public void setGetSet(Set<Good> getSet) {
this.getSet = getSet;
}

2、编写两个实体类的映射文件。

   (1)一的那一方的映射文件。

      在一的这一方,需要使用<many-to-one>标签来配置对应关系。

<hibernate-mapping>
<class name="com.jack.entity.Good" table="t_good">
<id name="gid" column="gid">
<generator class="native"></generator>
</id>
<property name="gname" column="gname"></property>
<property name="gmessage" column="gmessage"></property> <!--
表示商品所属的分类
name属性的值:因为在Good商品实体中,用sort表示Sort实体类,所有这里写sort
class属性的值:sort类的全路径
column属性的值:外键的名称
-->
<many-to-one name="sort" class="com.jack.entity.Sort" column="gsid"></many-to-one>
</class>
</hibernate-mapping>

   (2)多的那一方的映射文件。

      在多的这一方,需要使用<set>标签来配置对应关系。

 <hibernate-mapping>
<class name="com.jack.entity.Sort" table="t_sort">
<id name="sid" column="sid">
<generator class="native"></generator>
</id>
<property name="sname" column="sname"></property>
<property name="smessage" column="smessage"></property> <!--
在多的这一边使用set标签来设置对应关系
name属性的值:因为在Sort中使用getSet保存good属性。
column属性的值:外键的名称,由于在Hibernate使用双向维护主键
所有在这边的column的值必须要和另一边的值一致
class属性的值:Good实体类的全路径。
-->
<set name="getSet">
<key column="gsid"></key>
<one-to-many class="com.jack.entity.Good" />
</set>
</class>
</hibernate-mapping>

3、编写核心配置文件

<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hibernatetest</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property> <property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name=" hibernate.current_session_context_class">thread</property> <mapping resource="com/jack/entity/Good.hbm.xml"/>
<mapping resource="com/jack/entity/Sort.hbm.xml"/>
</session-factory>
</hibernate-configuration>

4、编写工具类

public class HibernateUtils {
private static Configuration configuration = null;
private static SessionFactory sessionFactory = null;
static{
configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
} public static Session getSeeion() {
return sessionFactory.getCurrentSession();
}
}

5、编写级联保存代码

第一种代码(复杂):

@Test
public void TestAdd(){
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSeeion();
tx = session.beginTransaction(); /**
* 创建两个商品
*/
Good good1 = new Good();
good1.setGname("蛋糕");
good1.setGmessage("奶油蛋糕");
Good good2 =new Good();
good2.setGname("牙膏");
good2.setGmessage("冷酸灵牙膏"); /**
* 创建两个类别
*/
Sort sort1 =new Sort();
sort1.setSname("食品");
sort1.setSmessage("食品类");
Sort sort2 = new Sort();
sort2.setSname("生活用品");
sort2.setSmessage("生活用品类"); /**
* 将商品放到类别中
*/
sort1.getGetSet().add(good1);
sort2.getGetSet().add(good2);
/**
* 将类别设置到商品中
*/
good1.setSort(sort1);
good2.setSort(sort2);
/**
* 保存类别
* 保存商品
*/
session.save(sort1);
session.save(sort2);
session.save(good1);
session.save(good2);
tx.commit();
} catch (Exception e) {
tx.rollback();
}finally{ }
}

第二种代码(简单):

首先在多的那一方的配置文件的<set>标签内,写入cascade属性,其值为save-update。

 <set name="getSet" cascade="save-update">
<key column="gsid"></key>
<one-to-many class="com.jack.entity.Good" />
</set>

然后编写代码

@Test
public void TestAdd2(){
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSeeion();
tx = session.beginTransaction(); /**
* 创建两个商品
*/
Good good3 = new Good();
good3.setGname("面包");
good3.setGmessage("面包");
/**
* 获得食品类
*/
Sort sort1 = session.get(Sort.class, 1);
/**
* 将商品放到类别中
*/
sort1.getGetSet().add(good3); /**
* 保存类别
* 现在只需要保存类别,商品也会自动保存
*/
session.save(sort1); tx.commit();
} catch (Exception e) {
tx.rollback();
}finally{ }
}

6、Hibernate默认双方都要维护主键,这样会降低效率,通过配置inverse属性可以让一方放弃维护主键,这样可以提高操作效率。一般让多的那一方放弃。

  

 <!--
true:表示不维护
false:表示维护主键
默认为false,维护主键
-->
<set name="getSet" cascade="save-update" inverse="true">
<key column="gsid"></key>
<one-to-many class="com.jack.entity.Good" />
</set>

7、测试结果

     

8、级联删除

首先配置cascade属性,值为delete

 <set name="getSet" cascade="save-update,delete" inverse="true">
<key column="gsid"></key>
<one-to-many class="com.jack.entity.Good" />
</set>

编写代码实现删除(删除食品类)

@Test
public void TestDelete(){
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSeeion();
tx = session.beginTransaction(); /**
* 找到食品类
*/
Sort sort = session.get(Sort.class, 1); /**
删除食品类
*/
session.delete(sort);
tx.commit();
} catch (Exception e) {
tx.rollback();
}finally{ }
}

测试结果:

9、级联修改

修改前数据库

  

修改代码(把蛋糕放到生活用品中):

    @Test
public void TestUpdate(){
Session session = null;
Transaction tx = null;
try {
session = HibernateUtils.getSeeion();
tx = session.beginTransaction(); /**
* 找到生活用品
*/
Sort sort = session.get(Sort.class, 2);
/**
* 找到蛋糕
*/
Good good =session.get(Good.class, 4);
/**
* 把蛋糕放到生活用品中去
*/
sort.getGetSet().add(good);
/**
* 把生活用品设置到蛋糕中去
*/
good.setSort(sort);
tx.commit();
} catch (Exception e) {
tx.rollback();
}finally{ }
}

修改之后结果:

  

  

Hibernate一对多关系操作的更多相关文章

  1. 11.Hibernate一对多关系

    创建JavaBean 一方: Customer private long cust_id; private String cust_name; private long cust_user_id; p ...

  2. 菜鸟学习Hibernate——一对多关系映射

    Hibernate中的关系映射,最常见的关系映射之一就是一对多关系映射例如学生与班级的关系,一个班级对应多个学生.如图: Hibernate中如何来映射这两个的关系呢? 下面就为大家讲解一下: 1.创 ...

  3. hibernate一对多关系配置

    一.     表信息 公司表 cId cName cAdress Null Null Null 表t_company 员工表 sId sName sAge cId Null Null Null Nul ...

  4. hibernate 一对多关系中的孤儿属性

    @OneToMany(targetEntity = BenefitType.class, mappedBy = "sitePerson",cascade = CascadeType ...

  5. hibernate一对多关系映射(自身关联)

    示例:一个类别(Category)下面有多个子类别,多个子类别属于同一个父类别. public class Category  { private Integer id; private String ...

  6. hibernate一对多关系 在一方查询会获得重复数据,重复数量就是多端数据数量用@Fetch(FetchMode.SUBSELECT)解决

    先来看数据表 版块表只有两个数据 板块1是推荐,下边没有子栏目 板块2下边有14个子栏目 在1的一端来查询,发现结果有16条 也就是板块1+版块2+版块2和他的14个子集都列出来了,这明显不对 板块对 ...

  7. 【Java EE 学习 45】【Hibernate学习第二天】【对象的三种状态】【一对多关系的操作】

    一.对象的三种状态. 1.对象有三种状态:持久化状态.临时状态.脱管状态(游离状态) 2.Session的特定方法能使得一个对象从一个状态转换到另外一个状态. 3.三种状态的说明 (1)临时状态:临时 ...

  8. java框架之Hibernate(3)-一对多和多对多关系操作

    一对多 例:一个班级可以有多个学生,而一个学生只能属于一个班级. 模型 package com.zze.bean; import java.util.HashSet; import java.util ...

  9. hibernate中一对多关系中的inverse,cascade属性

    举例说明: 一对多关系的两张表:boy.girl(一个男孩可以多个女朋友) boy表结构 Field   Type        ------  -----------  name    varcha ...

随机推荐

  1. JS设置localStorage有效期

    localStorage是一个没有时间限制的数据存储,如果没有手动删除它,它将永久保存. 但是有些时候我们又需要它在一段时间后自动删除,这里我们可以对它进行扩展. var date = new Dat ...

  2. [Perl]Can't link/include C library 'ft2build.h', 'freetype', aborting.

    原文:http://www.code-by.org/viewtopic.php?f=60&t=284 错误提示 Font-FreeType-0.07>perl Makefile.PL B ...

  3. 当在安卓低版本呈现的界面(H5)出现问题的时候,我们怎么解决?

    昨天,在医院现场的客服人员,向我们反馈一个问题:说一位用户用他的安卓手机打开我们的app之后,界面是乱掉的:如下图: 向客服询问了具体的设备信息:安卓系统版本号是4.2 下意识觉得是因为css的兼容问 ...

  4. android相对布局中控件的常用属性

    Android布局属性详解 RelativeLayout用到的一些重要的属性: 第一类:属性值为true或false android:layout_centerHorizontal 水平居中 andr ...

  5. is 与 == 的区别;小数据池; 编码与解码

    1, is 与 == 的区别 ==  比较的是两边的值 is   比较的是两边的地址  id () 2,小数据池(在终端中) 数字小数据池的范围 -5 ~ 256 字符串中如果有特殊字符他们的内存地址 ...

  6. Oracle中对多行查询结果进行拼接

    to_char(wmsys.wm_concat(to_char( st.col_name))) as new_name to_char: 将当前值转换成字符串类型; wmsys.wm_concat:拼 ...

  7. <b>与<strong> <em>与<i>标签的区别

    <b>与 <strong>用在网页上都能使字体加粗,二者的不同是:<b>是物理元素 ;<strong>是逻辑元素. 物理元素强调的是一种物理行为.比如说 ...

  8. c语言-汉诺塔递归调用

    #include<stdio.h> int main() { void hano_tower(int n,char one,char two,char three); int m=0; p ...

  9. Requests库请求网站

    安装requests库 pip install requests 1.使用GET方式抓取数据: import requests #导入requests库 url="http://www.cn ...

  10. python全栈开发_day4_if,while和for

    一.if 1)if的用途 if常用于判断. 2)if的语法 tag=True tag2=True if tag: print("代码") elif tag2: print(&quo ...