1. 多对多关联:

在双方都要用一个类型为Set的属性保存对方的信息,并在映射配置文件中指定这个属性的名字,并指定中间表。还需要通过<key column=””>来指定自己在中间表中对应的外键。在<many-to-many>标签中,要配置对方的类,并且指定对方类在中间表中的对应的外键

*学生表配置文件:

<class name="edu.whu.swe.lxl.learn.hibernate.model.stucourse.Student" table="student" schema="dbforlearn">

<id name="id" column="id" >

<generator class="native"/>

</id>

<property name="num" column="num"/>

<property name="name" column="name"/>

<!--配置set集合描述类Student中的courses属性和中间表信息-->

<set name="courses" table="stu_course" >

<!--设置本类在连接表中对应的外键-->

<key column="student"/>

<!--配置关联类以及关联类在中间表中的外键-->

<many-to-many class="edu.whu.swe.lxl.learn.hibernate.model.stucourse.Course"

column="course"/>

</set>

</class>

*课程表的映射文件:
    <class
name="edu.whu.swe.lxl.learn.hibernate.model.stucourse.Course"
table="course" schema="dbforlearn">

<id name="id"
column="id">

<generator
class="native"

</id>

<property name="num"
column="num"/>

<property name="name"
column="name"/>

<!--配置关联类在本类中对应的属性以及中间表-->

<set name="students"
table="stu_course">

<!--设置本类在连接表中对应的外键-->

<key
column="course"/>

<!--配置关联类以及关联类在中间表中对应的外键-->

<many-to-many class="edu.whu.swe.lxl.learn.hibernate.model.stucourse.Student"

column="student"/>

</set>

</class>

*一般在多对多关系中,不存在级联删除的需求。在多对多中,千万不要加入cascade=delete,否则会是灾难性的。

2.查询

1)唯一标识OID的检索方式(重要)

Session.get(obj.class,OID)

2) 对象的导航方式(重要)

一对多查询时,利用里面包含的set

3)HQL的检索方式(重要)

Hibernate Query
Language  ——hibernate的查询语言

4)QBC的检索方式(重要)

Query By
Criteria  ——条件查询

5)SQL查询

3.HQL查询

* HQL是面向java对象的,和SQL有相似之处

*是hibernate中使用最广泛的检索方式

*hibernate负责解析HQL,然后根据ORM配置的映射关系,生成相应的SQL语句

*HQL操作的是类以及属性,而不是数据表和字段

4.延迟加载技术——在class标签上配置

1)延迟加载先获取到代理对象,当真正使用到该对象中的属性且缓存里没有值时,才会发送SQL语句,是hibernate框架提升性能的主要方式。

2)类级别的延迟加载

*Session对象的load方法默认就是延迟加载

*Customer c=session.load(Customer.class,1L),没有发送SQL语句,当使用该对象的属性时,才发送SQL语句

【实例】

/**

<class
name="edu.whu.swe.lxl.learn.hibernate.model.Customer"
table="customer" >

<id name="id"
column="id">

<generator
class="identity"/>

</id>

<property name="name"
column="name"/>

<property name="address"
column="address"/>

<property name="age"
column="age"/>

<property
name="registerDate" column="register_date"/>

</class>     */

public void testLoad(){

Customer customer =
session.load(Customer.class, 3);

log.trace(customer.getId().toString());//没有发送SQL,因为ID已经由代码提供了,此时开始变成持久态

log.trace("+++++++++++++++++");

log.trace(customer.getName());//发送SQL语句,因为此时缓存里没有name信息,必须要发送SQL从数据库中查询

}

*使类级别的延迟加载失效:

**在<class>标签上配置lazy=”false”

**Hibernate.initialize(Object proxy)

【实例】

/**

<class
name="edu.whu.swe.lxl.learn.hibernate.model.Customer"
table="customer" lazy="false">

<id name="id"
column="id">

<generator
class="identity"/>

</id>

<property name="name"
column="name"/>

<property name="address"
column="address"/>

<property name="age"
column="age"/>

<property name="registerDate"
column="register_date"/>

</class>

*/

@Test

public void testLoadNotLazy() {

Customer customer =
session.load(Customer.class, 3);

log.trace(customer.getId().toString());//没有发送SQL,因为ID已经由代码提供了,此时开始变成持久态

log.trace("+++++++++++++++++");

log.trace(customer.getName());//发送SQL语句,因为此时缓存里没有name信息,必须要发送SQL从数据库中查询

}

3)关联级别的延迟加载。

* CustCustomer
customer=session.get(CustCustomer.class,1L)不是延迟加载,但是它不会把代理类CustCustomer的关联类CstLinkman加载进来,当使用CstLinkman
linkmans=customer.getLinkmans()获取关联类对象的时候,因为没有用到CstLinkman的任何属性,也不需要知道有几个linkman,所以还是不会加载。直到使用了linkmans里的属性时,才会发送SQL加载关联类对象。

【实例】

/**

* <set name="linkMans"
cascade="delete-orphan" inverse="true">

<!--外键-->

<key
column="lkm_cust_id"/>

<!--对应关系-->

<one-to-many
class="edu.whu.swe.lxl.learn.hibernate.model.CstLinkman" />

</set>

*/

CustCustomer customer =
session.get(CustCustomer.class, 19L);//直接发送SQL查询CustCustomer,但不查询CstLinkman

log.trace(customer.getCustId().toString());//

log.trace("++++++++++++++++++++++++++");

Set linkmans=customer.getLinkMans();//还是不发送SQL,因为还没有必要查询CstLinkman的属性

log.trace("++++++++++++++++++++++++++");

log.trace(""+linkmans.size());//这个时候发送SQL,因为不发送,就不知道有几个linkman了。

5.延迟加载技术——在set标签上配置策略

1)在<set>标签上使用fetch和lazy属性

*fetch的取值       ——控制SQL语句的生成格式

** select       ——默认值,发送查询语句

**join            ——连接查询,发送的是一条左外链接查询,此时,关联表延迟加载失效(因为不需要再发起一次SQL查询关联表了,而是在一次外链接查询中完成了所有表的加载)

**subselect    ——子查询,发送一条子查询完成关联对象的查询。(需要使用list()方法进行测试,如Criteria.list()或者Query.list())

*lazy的取值        ——查询关联对象的时候是否采用延迟加载

**true         ——默认,延迟

**false         ——不延迟

**extra         ——极其懒惰,根据需要查询,而不是查询所有字段,比如用一写聚合函数,或者只查询某一个字段

一般都采用默认值即可

【示例】

*fetch=”join”

public void
testJoinSet(){

/**

<set name="linkMans"
cascade="delete-orphan" inverse="true" fetch="join>

<!--外键-->

<key column="lkm_cust_id"/>

<!--对应关系-->

<one-to-many
class="edu.whu.swe.lxl.learn.hibernate.model.CstLinkman" />

</set>

*/

CustCustomer customer =
session.get(CustCustomer.class, 19L);//直接发送join SQL 左外连接查询,一次性获取所有的数据

log.trace(customer.getCustId().toString());

log.trace("++++++++++++++++++++++++++");

}

*fetch=”select”
lazy=”extra”

@Test

public void testExtraLazy() {

/**

<set name="linkMans"
cascade="delete-orphan" inverse="true"
fetch="select" lazy="extra">

<!--外键-->

<key
column="lkm_cust_id"/>

<!--对应关系-->

<one-to-many
class="edu.whu.swe.lxl.learn.hibernate.model.CstLinkman" />

</set>

*/

CustCustomer customer =
session.get(CustCustomer.class, 19L);//直接发送SQL查询CustCustomer,但不查询CstLinkman

log.trace(customer.getCustId().toString());//

log.trace("++++++++++++++++++++++++++");

Set linkmans = customer.getLinkMans();//还是不发送SQL,因为还没有必要查询CstLinkman的属性

log.trace("++++++++++++++++++++++++++");

log.trace("" +
linkmans.size());//发送select count(lkm_id) form cst_linkman where lkm_cust_id=?,而不是查询所有字段

}

*fatch=”subselect”

public void testSubselectSet() {

/**

<set name="linkMans"
cascade="delete-orphan" inverse="true"
fetch="subselect">

<!--外键-->

<key
column="lkm_cust_id"/>

<!--对应关系-->

<one-to-many
class="edu.whu.swe.lxl.learn.hibernate.model.CstLinkman" />

</set>

*/

Query query =
session.createQuery("from CustCustomer ");

List<CustCustomer> customers =
query.list();//发送SQL查询CustCustomer,但不查询CstLinkman

log.trace("++++++++++++++++++++++++++++++++++");

for(CustCustomer customer:customers){

Set linkmans

= customer.getLinkMans();//不发送SQL

log.trace("++++++++++++++++++++++++++++++++++");

log.trace(""+linkmans.size());//在第一次循环时候,就发送子查询把List所有中所有用户的所有联系人都一次性查询出来,下次循环就不用发送SQL了。如果不适用subselect,那么循环一次,就发送一次SQL查询该客户的联系人

}

}

6.优化技术——在<many-to-one>标签中配置策略

1)在<many-to-one>标签上使用fetch和lazy属性

*fetch的取值                            ——控制SQL语句的格式

**select                   ——默认,发送基本的select语句查询

**join                            ——无效,所以fetch只能是select,所以不用设置fetch

*lazy的取值

**false                                   ——不采用延迟加载

**proxy                         ——默认值,是否延迟加载取决于一方set 标签的lazy取值,多方和一方的lazy值一样。

7.当fetch=select,lazy=true的时候,使用list时,对从表的查询是一次循环获取进行一次的,此时如果不想设置subselect进行子查询,那么可以设置set标签的batch-size=10,从而达到批量获取从表数据的目的。当设置batch-size=10时,hibernate会一次就取10个客户的联系人。具体工作原理这样的:

1)先获取所有的客户

2)再用select xxx
xxx xxx from cst_linkman where cst_linkman.lkm_cust_id in( 10个客户的id  )批量获取10个客户的联系人。

总结:session.load采取的是类级别的延迟加载,并且在class标签上配置当前类的延迟加载策略;session.get采取的是连接上的延迟加载,并且在set标签上配置加载策略,在many-to-one上也可以进行配置。

8.延迟加载策略的优缺点及适用范围:
1)有点

有应用程序决定要加载哪些对象,可以避免执行多余的SQL语句,避免加载不程序不会访问的对象,提高性能和空间利用率。

2)缺点

应用程序如果试图访问处于游离态的代理类实例,必须保证它在持久化状态是已经被初始化了。而延迟加载策略往往导致代理类实例相应的set没有值,从而需要把游离态对象通过session.update方法变成持久态,再去访问set中的对象从而加载对象。

3)适用范围

——一对多或者多对多

——应用程序不需要立即访问或者根本不需要访问的对象。

9.在配置文件中配置的加载策略影响全局,但是应用程序的需求可能是多样的,在不同的时候需要不同的加载策略,因此,hibernate提供了在应用程序中指定加载策略的方式,应用程序中指定的加载方式将覆盖配置文件中的加载方式(局部优先于整体原则)

10.一对一的加载默认是使用左外连接查询。

hibernate 学习笔记3的更多相关文章

  1. Hibernate学习笔记(二)

    2016/4/22 23:19:44 Hibernate学习笔记(二) 1.1 Hibernate的持久化类状态 1.1.1 Hibernate的持久化类状态 持久化:就是一个实体类与数据库表建立了映 ...

  2. Hibernate学习笔记(一)

    2016/4/18 19:58:58 Hibernate学习笔记(一) 1.Hibernate框架的概述: 就是一个持久层的ORM框架. ORM:对象关系映射.将Java中实体对象与关系型数据库中表建 ...

  3. Hibernate 学习笔记一

    Hibernate 学习笔记一 今天学习了hibernate的一点入门知识,主要是配置domain对象和表的关系映射,hibernate的一些常用的配置,以及对应的一个向数据库插入数据的小例子.期间碰 ...

  4. Hibernate学习笔记-Hibernate HQL查询

    Session是持久层操作的基础,相当于JDBC中的Connection,通过Session会话来保存.更新.查找数据.session是Hibernate运作的中心,对象的生命周期.事务的管理.数据库 ...

  5. Hibernate学习笔记

    一.Hibernate基础 1.Hibernate简介 Hibernate是一种对象关系映射(ORM)框架,是实现持久化存储的一种解决方案.Java包括Java类到数据库表的映射和数据查询及获取的方法 ...

  6. Hibernate学习笔记(四)

    我是从b站视频上学习的hibernate框架,其中有很多和当前版本不符合之处,我在笔记中进行了修改以下是b站视频地址:https://www.bilibili.com/video/av14626440 ...

  7. Hibernate学习笔记(三)

    我是从b站视频上学习的hibernate框架,其中有很多和当前版本不符合之处,我在笔记中进行了修改以下是b站视频地址:https://www.bilibili.com/video/av14626440 ...

  8. HIbernate学习笔记(一) 了解hibernate并搭建环境建立第一个hello world程序

    Hibernate是一个开放源代码的ORM(对象关系映射)框架,它对JDBC进行了轻量级的封装,Java程序员可以使用面向对象的编程思维来操纵数据库,它通过对象属性和数据库表字段之间的映射关系,将对象 ...

  9. Hibernate学习笔记-Hibernate关系映射

    1. 初识Hibernate——关系映射 http://blog.csdn.net/laner0515/article/details/12905711 2. Hibernate 笔记8 关系映射1( ...

  10. Hibernate学习笔记(1)Hibernate构造

    一 准备工作 首先,我们将创建一个简单的基于控制台(console-based)Hibernate应用. 我们所做的第一件事就是创建我们的开发文件夹.并把所有需要用到的Java件放进去.解压缩从Hib ...

随机推荐

  1. jQuery制作多表格固定表头、切换表头的特效

    做了好几天的固定表头特效,总算是搞定了.先说明一下基本功能:我们在一个网页上浏览很多份表格数据的时候,肯定会碰到很多分不清表头,也分不清表 格是哪个的情况,这个时候我们就希望能有一种功能,就是我们再下 ...

  2. 按照已有的模板输出<一>(如发票)

    按照已有的模板输出<一> 普通的发票基本上都是固定模式,所以我们一般写好固定的模板,把其中需要变动的地方,以特定符号来代替.每次打印发票的时候,只需将其中的特定符号转换成我们需要显示的数据 ...

  3. C++三种野指针及应对/内存泄露

    C++三种野指针及应对/内存泄露    野指针,也就是指向不可用内存区域的指针.如果对野指针进行操作,将会使程序发生不可预知的错误,甚至可能直接引起崩溃.         野指针不是NULL指针,是指 ...

  4. jquery call cross-domain webapi owin self-host

    <!DOCTYPE HTML> <html LANG="cn"> <head> <meta name="viewport&quo ...

  5. Windows系统下安装 CMake

    在安装caffe框架的时候需要用到cmake,特将cmake的安装总结如下: 1 什么是cmake CMake是一个跨平台的编译(Build)工具,可以用简单的语句来描述所有平台的编译过程.CMake ...

  6. 【bzoj4887】:[Tjoi2017]可乐 矩阵乘法,快速幂

    [bzoj4887]:[Tjoi2017]可乐 题目大意:一张无相连通图(n<=30),从1号点开始走,每秒可以走到相邻的点也可以自爆,求第t秒(t<=1e6)后所有的方案数是多少对201 ...

  7. animal与@keyframe

    .test1 { width: 90px; height: 60px; -webkit-animation-name: skyset; -webkit-animation-duration: 2000 ...

  8. 【UVA10816】Travel in Desert (最小瓶颈路+最短路)

    UVA10816 Travel in Desert 题目大意 沙漠中有一些道路,每个道路有一个温度和距离,要求s,t两点间的一条路径,满足温度最大值最小,并且长度最短 输入格式 输入包含多组数据. 每 ...

  9. C#-函数的传值与传址

    传值就是将实参的值传到所调用的函数里面,实参的值并没有发生变化,默认传值的有int型,浮点型,bool型,char字符型,结构体等等. 传址就是将地址传到所调用的函数里面操作,实参的值也会跟着变化,传 ...

  10. 机器学习中的范数规则化之 L0、L1与L2范数、核范数与规则项参数选择

    装载自:https://blog.csdn.net/u012467880/article/details/52852242 今天我们聊聊机器学习中出现的非常频繁的问题:过拟合与规则化.我们先简单的来理 ...