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{ }
}

修改之后结果:

  

  

最新文章

  1. Django 开发投票系统
  2. Error 0x800704cf
  3. Python 实现发送、抄送邮件功能
  4. VBS_For Each...Next
  5. oracle学习 四(持续更新中)无法为表空间 MAXDATA 中的段创建 INITIAL 区
  6. 在asp.net mvc中使用PartialView返回部分HTML段
  7. Python:元组(tuple)
  8. nRF51 DFU 初始化包介绍及生成工具
  9. .net mvc笔记4_依赖注入
  10. CSS预处理器——Sass、LESS和Stylus实践
  11. java 基础知识二 基本类型与运算符
  12. fgets()函数以及fputs()函数
  13. set类型
  14. 面向对象设计模式_生成器模式详解(Builder Pattern)
  15. jmeter如何进行MQTT性能测试(测试前期准备二,MQTT插件及协议了解)
  16. 自学Aruba3.1-Aruba配置架构-WLAN配置架构
  17. Java JDBC调用存储过程:无参、输入带参、输出及输出带参
  18. CTSC 2018 游记
  19. Redis实战配置(三)
  20. 一、CSS实现横列布局的方法总结

热门文章

  1. 文件查找记录类型 - TSearchRec - 文件操作(二)
  2. [LeetCode 题解]: Longest Substring Without Repeating Characters
  3. 解决Struts2拦截器的对于参数传递无效问题
  4. CLR via C# 读书笔记-27.计算限制的异步操作(上篇)
  5. 4.Python的版本
  6. ubuntu里面如何以root身份使用图形界面管理文件?
  7. flutter 保存图片到本地
  8. 多线程DP
  9. OCP认证052考试最新考试题库和答案整理-33
  10. “全栈2019”Java第六十一章:如何实现接口?