*一)【双向】一对多【客户 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双向一对多关联映射(XML)
hibernate 双向 多对对,一对多,一对一 映射的 集合 hibernate所有映射的集合 非常有用
hibernate核心,一对多,多对多映射讲解,看了就完全搞明白了
包含《多对多双向关联映射》《多对一单向关联映射》《多对一双向关联映射》《一对多单向关联映射》等文档,并有图解及例子,非常适合新手学习,尤其是刚刚接触hibernate,对映射关系不清楚的。。。。
Hibernate 一对一外键单向...Hibernate 一对一外键双向关联 Hibernate 一对一主键双向关联 Hibernate 一对一连接表双向关联 Hibernate 一对多外键双向关联 Hibernate 一对多连接表双向关联 Hibernate 多对多双向关联
Hibernate双向一对一关联映射(XML版)
1:Hibernate的关联映射,存在一对多和多对一映射,多对多映射: 1.1:一对多和多对一映射,举例说明: 学生和老师: 一个老师可以教多个学生 【一对多映射】 多个学生可以被一个老师教【多对一映射】 部门与员工: ...
博文链接:https://shaqiang32.iteye.com/blog/201309
NULL 博文链接:https://lijunabc.iteye.com/blog/438426
Hibernate的映射策略:一对一双向关联映射,有所有的测试用例,用以证明从任何一端都可以加载另一端信息。
http://blog.csdn.net/e421083458/article/details/8794127 该源码为Hibernate教程配套源码
博文链接:https://shaqiang32.iteye.com/blog/201312
Hibernate关联关系映射 单向关联 │ ├─ 一对一外键单向关联...├─ 一对一外键双向关联 ├─ 一对一主键双向关联 ├─ 一对一连接表双向关联 ├─ 一对多外键双向关联 ├─ 一对多连接表双向关联 └─ 多对多双向关联
简单的Hibernate的N对N关系的映射,这里主要的只是谈到了关于如何映射一对一,多对一,多对多的单向和双向映射。 当然,其实所谓的单双向映射最终还是要表现在select时的作用,但是这一部分并未介绍。 我想,要想搞...
Hibernate从入门到精通(六)一对一双向关联映射 - 赵帅 廊坊师范学院信息技术提高班
NULL 博文链接:https://hi-beijing.iteye.com/blog/1315150
主要介绍了hibernate一对多(多对一)双向关联映射的用法
hibernate one-to-one 一对一唯一外键关联映射_单向 and 双向