*一)【双向】一对多【客户 vs 订单】优化
(1)传统:保存订单,级联保存客户,设置双向关联--------------7条SQL
问题的前提:是双向关系
问题的产生:在默认情况下,单方和多方,都负责产生SQL语句,这样的话,可能产生不必要的多余SQL语句。
理论上哪方负责都可以,
但实际中用多方负责产生SQL较佳,即多方是主控方。
inverse反转/向
(2)优化:保存订单,级联保存客户,设置单向关联--------------4条SQL
(3)什么情况下用cascade和inverse属性
cascade:
当你需要操作Customer时,同时又要操作对应的所有Order,这样可以使用cascade属性
常用取值:save-update,delete,all
inverse:
前提:必须是双向关联,单向关联不存在inverse的情况
保存多方,要级联保存单方的情况
常用取值:true
Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- hibernate映射文件 --> <hibernate-mapping package="one2many_double"> <class name="Customer" table="CUSTOMERS"> <id name="id" column="ID"> <generator class="native"/> </id> <property name="name" column="NAME"/> <property name="age" column="AGE"/> <property name="des" column="DES"/> <!-- inverse=true如果出现在Customer类中,表示 Order类是主控方,负责产生SQL语句 inverse=false如果出现在Customer类中,表示 Customer类是主控方,负责产生SQL语句 如果Customer和Order都无inverse的话,表示 Customer和Order都是主控方,负责产生SQL语句 如果这样的话:问题有二: 一)会产生多余的SQL(成功) 二)会产主键重重(失败) --> <set name="orders" table="ORDERS" cascade="all" inverse="true"> <key column="CUSTOMERS_ID"/> <one-to-many class="Order"/> </set> </class> </hibernate-mapping>
Order.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- hibernate映射文件 --> <hibernate-mapping package="one2many_double"> <class name="Order" table="ORDERS"> <id name="id" column="ID"> <generator class="native"/> </id> <property name="orderno" column="ORDERNO"/> <property name="price" column="PRICE"/> <property name="time" column="TIME"/> <many-to-one name="customer" column="customers_id" cascade="all" /> </class> </hibernate-mapping>
二)【双向】一对一【人 vs 身份证】
private Integer id; private String name; private Double salary; private Card card;
Person.hbm.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- hibernate映射文件 --> <hibernate-mapping package="onetoonedouble"> <class name="Person" table="PERSON"> <id name="id" column="ID"> <generator class="native"/> </id> <property name="name" column="NAME"/> <property name="salary" column="SALARY"/> <!-- name:表示Person类的关联属性 property-ref:表示Person类的对方Card类的关联属性 --> <one-to-one name="card" property-ref="person" cascade="all" /> </class> </hibernate-mapping>
private int id; private String number; private String location;
Card.hbm.xml文件
<hibernate-mapping package="onetoonedouble"> <class name="Card" table="CARD"> <id name="id" column="ID"> <generator class="native"/> </id> <property name="number" column="NUMBER"/> <property name="location" column="LOCATION"/> <!-- name:表示Card类的关联属性 column:表示cards表对应的外健 not-null:表示该列不能为NULL unique:表示该列的值必须惟一 --> <many-to-one name="person" column="PERSON_ID" not-null="true" unique="true" /> </class> </hibernate-mapping>
(1)保存人,级联保存身份证
(2)查询人,对象导航查询身份证
(3)更新人,级联更新身份证
(4)删除人,级联删除身份证
*三)【双向】多对多【学生 vs 老师】
use hibernate drop table if exists middles; drop table if exists students; drop table if exists teachers; create table if not exists students( id int primary key auto_increment, name varchar(20) ); create table if not exists teachers( id int primary key auto_increment, name varchar(20) ); create table if not exists middles( students_id int, teachers_id int, primary key(students_id,teachers_id), constraint students_id_FK foreign key(students_id) references students(id), constraint teachers_id_FK foreign key(teachers_id) references teachers(id) ); select * from students; select * from middles; select * from teachers;
int id; String name; Set<Teacher> teacherset = new HashSet<Teacher>();
Student.hbm.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- hibernate映射文件 --> <hibernate-mapping package="many2many_double"> <class name="Student" table="STUDENTS"> <id name="id" column="ID"> <generator class="native"/> </id> <property name="name" column="NAME"/> <!-- name:表示Student类的关联属性 table:表示middles表名 key-column:表示middles表中引用students表的外健 class:表示Student类对应的类型,即Teacher类型 many-to-many-column:表示middles表中引用teachers表的外健 --> <set name="teacherset" table="MIDDLES" cascade="all" inverse="true"> <key column="STUDENTS_ID"/> <many-to-many class="Teacher" column="TEACHERS_ID"/> </set> </class> </hibernate-mapping>
private int id; private String name; Set<Student> studentset = new HashSet<Student>();
Teacher.hbm.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- hibernate映射文件 --> <hibernate-mapping package="many2many_double"> <class name="Teacher" table="TEACHERS"> <id name="id" column="ID"> <generator class="native"/> </id> <property name="name" column="NAME"/> <set name="studentset" table="MIDDLES" cascade="all"> <key column="TEACHERS_ID"/> <many-to-many class="Student" column="STUDENTS_ID"/> </set> </class> </hibernate-mapping>
(1)保存老师,级联保存学生【学生是主控方或老师是主控方】
(2)删除1号老师,不级联删除学生
@Test public void test2() { Session session = sessionFactory.openSession(); Transaction t = session.beginTransaction(); try { Teacher t1 = (Teacher) session.load(Teacher.class, 1); for (Student s : t1.getStudentset()) { s.getTeacherset().remove(t1); } t1.setStudentset(null); session.delete(t1); t.commit(); } catch (Exception e) { e.printStackTrace(); t.rollback(); } finally { session.close(); } }
四)映射组件整体与部分的关系【客户 vs 公司地址和家庭地址】
(1)hibernate将持久化对象分为二种类型
>>含有OID的对象:实体型,一定对应一条完整记录
>>不含OID的对象:值类型,不能对应一条完整记录,只能对应一条记录的某些部分
<hibernate-mapping package="cn.itcast.web.hibernate.component"> <class name="User" table="USERS"> <id name="id" column="ID"> <generator class="increment"/> </id> <property name="name" column="NAME"/> <!-- name:表示User中JavaBean的属性 class:表示该JavaBean属性的类型 --> <component name="homeAddress" class="Address"> <property name="province" column="HOME_PROVINCE"/> <property name="city" column="HOME_CITY"/> <property name="area" column="HOME_AREA"/> </component> <component name="comAddress" class="Address"> <property name="province" column="COM_PROVINCE"/> <property name="city" column="COM_CITY"/> <property name="area" column="COM_AREA"/> </component> </class> </hibernate-mapping>
(2)保存客户
(3)查询客户
(4)更新客户
(5)删除客户
*五)深入理解session一级缓存与批处理
(1)对象生命周期图堆栈图
Session是Hibernate中操作数据库的重要对象,完成CRUD操作
Session就是由集合组成
只要Session有引用存在,它所引用的对象,就不会被GC回收
(2)hibernate自动清理session一级缓存的时间
清理flush:session一级缓存根据持久化对象属性值的改变情况,自动生成SQL的过程,叫清理。
注意:此时并没有与数据库交互
(3)对比以下方法:
>>session.flush()
清理session缓存,但session缓存中的持久化对象没有删除
*>>session.evict()
将【一个】持久状态对象转成游离状态对象
>>session.clear()
一次性将位于session缓存中的所有持久状态对象,清出session缓存区
将【多个】持久状态对象转成游离状态对象
*>>transaction.commit()
它包括二个子步骤:
A)session.flush()
B)事务提交,就与数据库交互
*>>session.close()
它包括二个子步骤:
A)session.clear()
B)回收资源
注意:如果要全完销毁Session,一定要加上如下代码:session = null
(4)批量向MySQL数据库插入10万条数据,并记录所耗时间
public void test1() { Session session = sessionFactory.openSession(); Transaction t = session.beginTransaction(); try { long begin = System.currentTimeMillis(); for (int i = 1; i <= 100001; i++) { User user = new User("用户" + i); session.save(user); if (i % 1000 == 0) { t.commit(); session.clear(); t = session.beginTransaction(); } }// end of for loop t.commit(); long end = System.currentTimeMillis(); System.out.println((end - begin) / 1000 + "��"); } catch (Exception e) { e.printStackTrace(); t.rollback(); } finally { session.close(); } }
参见<<PPT第21,22页>>
六)安装Oracle数据库11g版本
相关推荐
本主题聚焦于“Hibernate双向一对一关联映射”的注解实现,这是一种高级的数据库设计模式,用于处理两个实体之间一对一的关系。 在Hibernate中,一对一关联映射分为单向和双向。单向一对一映射通常涉及一个实体持有...
标题"Hibernate一对一主键关联映射(双向关联)"中的"主键关联"指的是两个实体通过共享相同的主键来建立关联。"双向关联"则意味着在两个实体类中,都可以直接访问到对方的实例,即在实体A中有一个对实体B的引用,...
在Java持久化框架Hibernate中,双向一对一(OneToOne)基于主键的关联映射是一种常见的对象关系映射(ORM)技术。这种映射方式允许两个实体类之间建立一对一的关联,且关联是通过主键来实现的。接下来,我们将深入...
**标题:“Hibernate双向一对多经典实例”** 在Java开发中,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者能够用面向对象的方式处理数据。本实例将聚焦于Hibernate中的一对多关系...
一、Hibernate一对一关联类型 一对一关联在现实世界中很常见,例如一个人只有一个身份证,一个身份证也只能属于一个人。在数据库设计中,这种关系通常通过主键和外键的方式实现,其中一方的主键作为另一方的外键,...
总之,Hibernate的一对一双向外键关联是数据库设计中一个重要的概念,它使得Java对象和数据库记录之间的关系管理更加方便。理解并掌握这种关联方式对于开发高效、健壮的Java应用程序至关重要。通过实践和探索提供的...
标题"Hibernate双向一对多"指的是Hibernate框架中的一个重要关系映射概念,即在一个实体类中,一个实例可以与多个另一个实体类的实例相关联,而在另一个实体类中,每个实例也可以关联到该实体类的一个实例。...
在本章中,我们将深入探讨Hibernate中的关联映射,包括一对多、多对一以及多对多的关系。这些映射关系对于理解如何在Java应用程序中有效地管理数据库对象至关重要。 首先,我们来解决描述中提到的问题。`...
在这个“hibernate双向多对多关联映射(注解版)”的主题中,我们将深入探讨如何使用Hibernate的注解配置来处理数据库中的双向多对多关联关系。 首先,多对多关联在数据库设计中是指两个实体之间存在多个对应关系,...
总结起来,Hibernate的双向多对多、一对多、一对一映射提供了灵活的数据关联方式,使得Java对象和数据库表之间的关系得以顺畅地转换和操作。理解并熟练掌握这些映射关系,对于开发高效、稳定的Java持久层代码至关...
在Java的持久化框架Hibernate中,双向一对多关联映射是一种常见的关系映射方式,它模拟了数据库中的外键关联,使得一个实体可以拥有多个另一个实体的实例。在这个注解版的实现中,我们将深入探讨如何使用Hibernate的...
本教程将带你入门Hibernate的多对多实体映射,帮助你理解如何通过源码来实现这种复杂的关系映射。 一、Hibernate概述 Hibernate是一个对象关系映射(ORM)框架,它允许我们将Java对象(实体)与数据库表进行映射,...
包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。
在Java的持久化框架Hibernate中,双向一对多关联映射是一种常见的关系数据库模型与对象模型之间的映射方式。这种映射允许在一个实体类中存在多个另一个实体类的实例,而在另一个实体类中也可能存在对第一个实体类的...
在Java持久化框架Hibernate中,一对一双向关联映射是一种重要的数据对象关系映射策略,它允许我们在数据库中的两个实体之间建立一对一的关系,并且在Java对象模型中可以从任一侧访问另一侧的对象。这种映射方式增加...
这个压缩包文件“HibernateORM”很可能包含了关于如何在实际项目中设置和使用Hibernate一对多双向关联的示例代码、配置文件或者详细教程。通过学习这些材料,开发者能够深入理解如何在Java应用中利用Hibernate来处理...
本篇文章将深入探讨 Hibernate 中的一对多双向关联映射。 在数据库设计中,一对多关联是指一个实体可以与多个其他实体相关联,比如一个学生可以有多个课程,一个部门可以有多名员工。在Hibernate中,这种关系可以...
- 在一对一双向关联中,如果两个实体都维护外键,可能会导致数据不一致,因此要谨慎处理。 总结起来,Hibernate双向一对一关联映射通过XML配置文件使得我们在Java代码中可以方便地操作数据库中的一对一关系,同时...
1. **关联类型:** Hibernate支持四种基本的关联类型,包括一对一(OneToOne)、一对多(OneToMany)、多对一(ManyToOne)和多对多(ManyToMany)。本主题将主要聚焦在一对一和一对多关联。 2. **关联的方向性:**...
标题中的“hibernate 映射-一对多双向”指的是在Java Hibernate框架中处理数据库关系映射中的一对多关联关系,并且这种关联是双向的。...在实际项目中,可以通过分析此类数据来设计和实现Hibernate的一对多双向映射。