Hibernate一对多关系操作
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一对多关系操作的更多相关文章
- 11.Hibernate一对多关系
		
创建JavaBean 一方: Customer private long cust_id; private String cust_name; private long cust_user_id; p ...
 - 菜鸟学习Hibernate——一对多关系映射
		
Hibernate中的关系映射,最常见的关系映射之一就是一对多关系映射例如学生与班级的关系,一个班级对应多个学生.如图: Hibernate中如何来映射这两个的关系呢? 下面就为大家讲解一下: 1.创 ...
 - hibernate一对多关系配置
		
一. 表信息 公司表 cId cName cAdress Null Null Null 表t_company 员工表 sId sName sAge cId Null Null Null Nul ...
 - hibernate 一对多关系中的孤儿属性
		
@OneToMany(targetEntity = BenefitType.class, mappedBy = "sitePerson",cascade = CascadeType ...
 - hibernate一对多关系映射(自身关联)
		
示例:一个类别(Category)下面有多个子类别,多个子类别属于同一个父类别. public class Category { private Integer id; private String ...
 - hibernate一对多关系 在一方查询会获得重复数据,重复数量就是多端数据数量用@Fetch(FetchMode.SUBSELECT)解决
		
先来看数据表 版块表只有两个数据 板块1是推荐,下边没有子栏目 板块2下边有14个子栏目 在1的一端来查询,发现结果有16条 也就是板块1+版块2+版块2和他的14个子集都列出来了,这明显不对 板块对 ...
 - 【Java EE 学习 45】【Hibernate学习第二天】【对象的三种状态】【一对多关系的操作】
		
一.对象的三种状态. 1.对象有三种状态:持久化状态.临时状态.脱管状态(游离状态) 2.Session的特定方法能使得一个对象从一个状态转换到另外一个状态. 3.三种状态的说明 (1)临时状态:临时 ...
 - java框架之Hibernate(3)-一对多和多对多关系操作
		
一对多 例:一个班级可以有多个学生,而一个学生只能属于一个班级. 模型 package com.zze.bean; import java.util.HashSet; import java.util ...
 - hibernate中一对多关系中的inverse,cascade属性
		
举例说明: 一对多关系的两张表:boy.girl(一个男孩可以多个女朋友) boy表结构 Field Type ------ ----------- name varcha ...
 
随机推荐
- JAVA IO总结及socket简单实现
			
为了方便理解与阐述,先引入两张图: a.Java IO中常用的类 在整个Java.io包中最重要的就是5个类和一个接口.5个类指的是File.OutputStream.InputStream.Writ ...
 - windows包管理工具和 ssh安装
			
Chocolatey windows下的包管理工具 https://chocolatey.org/ cmd里执行 @"%SystemRoot%\System32\WindowsPowerSh ...
 - python的requests库详解
			
快速上手 迫不及待了吗?本页内容为如何入门 Requests 提供了很好的指引.其假设你已经安装了 Requests.如果还没有,去安装一节看看吧. 首先,确认一下: Requests 已安装 Req ...
 - Python 的web自动化测试
			
安装selenium 上面python已安装完毕,接下来安装selenium. 安装selenium之前需安装些必要工具 1. 安装setuptools 下载地址:https://pypi.pytho ...
 - Web App三年将取代原生App?
			
从技术角度讲,html5现在是可以获取很多用户的资源,上传提交服务器,与用户进行交互.但是你可以观察一下PC或Mac,web网页发展了这么长时间了,取代了客户端了吗? 对于现在而言,html5虽已可以 ...
 - js的常用方法和对象学习
			
js的常用方法和对象学习String对象:操作字符的. 使用:字符串.函数名. 大小写转换: toUpperCase() 转换大写 toLowerCase() 转换小写 function testSt ...
 - SQLAlachemy 自动提交配置 SQLALCHEMY_COMMIT_ON_TEARDOWN
			
挖坑:自动提交省去了每次 commit,添加数据对象后立马取 id 返回None 填坑 :立马要取 id 的地方 commit一下
 - 【Leetcode】Binary Tree Traversal
			
把三个二叉树遍历的题放在一起了. 递归写法太简单,就不再实现了,每题实现了两种非递归算法. 一种是利用栈,时间和空间复杂度都是O(n). 另一种是借助线索二叉树,也叫Morris遍历,充分利用树中节点 ...
 - python高级(五)—— python函数(一等对象)
			
本文主要内容 一等对象 普通函数 & 高阶函数 可调用对象 & 自定义可调用类型 函数内省 函数注释 python高级——目录 文中代码均放在github上:https://githu ...
 - python全栈开发_day11_作用域,函数嵌套和闭包
			
一:作用域 1)什么是作用域 作用域是规定一个变量可以作用的范围,运行和销毁的范围 2)作用域的分类 1.内置作用域built_in:随着解释器的运行而产生,解释器运行的终止而销毁. 2.全局作用域g ...