类级别的检索策略:
Customer c=(Customer)session.load(Customer.class, 1);
session的方法直接检索Customer对象,对Customer对象到底采用立即检索,还是延迟检索方式,通过class元素的lazy属性设定
get():默认立即检索
load():默认延迟检索
public void loadCustomertrueProxy(){ Session session=sessionFacoty.openSession(); Transaction tx=session.beginTransaction(); //此时查询到的c对象是一个代理对象 Customer c=(Customer)session.load(Customer.class, 1); System.out.println(c.getClass()); //代理对象 c.getClass(); //hibernate不会执行select语句 c.getId(); //hibernate不会执行select语句 c.getAge(); //该行hibernate会执行select语句 tx.commit(); session.close(); }
Hiberante提供了一个工具类,可以在load()延迟加载的情况下手动加载
public void loadCustomertrueProxyInit(){ Session session=sessionFacoty.openSession(); Transaction tx=session.beginTransaction(); //此时查询到的c对象是一个代理对象 Customer c=(Customer)session.load(Customer.class, 1); System.out.println(c.getClass()); //代理对象 //判断代理对象是否被初始化 对集合对象也适用 if(!Hibernate.isInitialized(c)){ System.out.println(c.getClass()); //代理对象 System.out.println("没有被初始化"); //方法一 c.getAge();//会查询select语句 //初始化代理对象的方法,hibernate执行select查询,方法二 Hibernate.initialize(c); } tx.commit(); session.close(); }
get/load在Hibernate part 4中已经详细的解释过了
通过修改配置文件,load()可以实现立即检索
<class name="rock.lee.bean.Customer" table="customer" catalog="test" lazy="false">
此时load()检索方式和get()一样,不会生成代理对象,立即查询Customer对象
无 论 <class> 元素的 lazy 属性是 true 还是 false, Session 的 get() 方法及 Query 的 list() 方法在类级别总是使用立即检索策略;若 <class> 元素的 lazy 属性为 true 或取默认值, Session 的 load() 方法不会执行查询数据表的 SELECT 语句
关联级别检索策略:
在映射文件中, 用 <set> 元素来配置一对多关联及多对多关联关系,<set> 元素有 lazy 和 fetch 属性
lazy: 主要决定 orders 集合被初始化的时机. 即到底是在加载 Customer 对象时就被初始化, 还是在程序访问 orders 集合时被初始化
fetch: 取值为 “select” 或 “subselect” 时, 决定初始化 orders 的查询语句的形式; 若把 fetch 设置为 “join”, lazy 属性将被忽略
建立测试数据:
mysql> select * from orders; +----+---------------+-------+-------------+ | id | address | money | customer_id | +----+---------------+-------+-------------+ | 1 | 林允儿...一环 | 11 | 1 | | 2 | 林允儿...一环 | 11 | 1 | | 3 | 林允儿...一环 | 11 | 1 | | 4 | 林允儿...一环 | 11 | 1 | | 5 | 林允儿...一环 | 11 | 1 | | 6 | 林允儿...一环 | 11 | 1 | | 7 | 孙艺珍...一环 | 11 | 2 | | 8 | 孙艺珍...一环 | 11 | 2 | | 9 | 孙艺珍...一环 | 11 | 2 | | 10 | 孙艺珍...一环 | 11 | 2 | | 11 | 孙艺珍...一环 | 11 | 2 | | 12 | 孙艺珍...一环 | 11 | 2 | +----+---------------+-------+-------------+ 12 rows in set (0.00 sec) mysql> select * from customer; +----+--------+------+ | id | name | city | +----+--------+------+ | 1 | 林允儿 | SH | | 2 | 孙艺珍 | BJ | +----+--------+------+ 2 rows in set (0.00 sec)
修改配置文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="rock.lee.bean.Customer" table="customer" catalog="test" > <id name="id" column="id" type="int"> <generator class="native"></generator> </id> <set name="orders" cascade="save-update,delete,delete-orphan" inverse="true" fetch="join"> <!-- customer表order是中所生成的外键列 --> <key column="customer_id"></key> <one-to-many class="rock.lee.bean.Order" /> </set> <property name="name" column="name" type="java.lang.String"></property> <property name="city" column="city" type="java.lang.String"></property> </class> </hibernate-mapping>
查询ID为1的Custoemr数据
@Test public void test02() { Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); Customer c1 = (Customer) session.get(Customer.class,1); transaction.commit(); session.close(); }
由于使用的是关联查询,所以lazy属性被忽略,立刻查询
Hibernate: select customer0_.id as id0_1_, customer0_.name as name0_1_, customer0_.city as city0_1_, orders1_.customer_id as customer4_0_3_, orders1_.id as id3_, orders1_.id as id1_0_, orders1_.address as address1_0_, orders1_.money as money1_0_, orders1_.customer_id as customer4_1_0_ from test.customer customer0_ left outer join test.orders orders1_ on customer0_.id=orders1_.customer_id where customer0_.id=?
案例二:fetch="select" 多条简单SQL
lazy="false" 立即检索
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="rock.lee.bean.Customer" table="customer" catalog="test" > <id name="id" column="id" type="int"> <generator class="native"></generator> </id> <set name="orders" cascade="save-update,delete,delete-orphan" inverse="true" fetch="select" lazy="false"> <!-- customer表order是中所生成的外键列 --> <key column="customer_id"></key> <one-to-many class="rock.lee.bean.Order" /> </set> <property name="name" column="name" type="java.lang.String"></property> <property name="city" column="city" type="java.lang.String"></property> </class> </hibernate-mapping>先查customer,在查orders,使用的都是简单查询语句
Hibernate: select customer0_.id as id0_0_, customer0_.name as name0_0_, customer0_.city as city0_0_ from test.customer customer0_ where customer0_.id=? Hibernate: select orders0_.customer_id as customer4_0_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.address as address1_0_, orders0_.money as money1_0_, orders0_.customer_id as customer4_1_0_ from test.orders orders0_ where orders0_.customer_id=?
lazy="true" 延迟检索
<set name="orders" cascade="save-update,delete,delete-orphan" inverse="true" fetch="select" lazy="true">
也是两条简单SQL语句,但因为是延迟检索,所以获取order数据是才会查询orders表
lazy="extra" 极其懒惰 (比延迟更加延迟) 增强延迟检索
<set name="orders" cascade="save-update,delete,delete-orphan" inverse="true" fetch="select" lazy="extra">
@Test public void test02() { Session session = HibernateUtils.openSession(); Transaction transaction = session.beginTransaction(); Customer c1 = (Customer) session.get(Customer.class,1); System.out.println(c1.getOrders().size()); System.out.println(c1.getOrders().iterator().next().getAddress()); transaction.commit(); session.close(); }只要不查看order中的数据,就不会发出查询语句
--Hibernate: Customer c1 = (Customer) session.get(Customer.class,1); select customer0_.id as id0_0_, customer0_.name as name0_0_, customer0_.city as city0_0_ from test.customer customer0_ where customer0_.id=? --Hibernate: System.out.println(c1.getOrders().size()); select count(id) from test.orders where customer_id =? --Hibernate: System.out.println(c1.getOrders().iterator().next().getAddress()); select orders0_.customer_id as customer4_0_1_, orders0_.id as id1_, orders0_.id as id1_0_, orders0_.address as address1_0_, orders0_.money as money1_0_, orders0_.customer_id as customer4_1_0_ from test.orders orders0_ where orders0_.customer_id=?
lazy="false" 立即检索
lazy="true" 延迟检索
lazy="extra" 极其懒惰 (增强延迟检索)
SQL的查询型式是子查询
- 当设置 <set> lazy="true" 第一次调用 集合 size()、 iterator() 、isEmpty() 、contains() 都会调用Hibernate.initialize() 对延迟集合初始化
- 当设置 <set> lazy="extra" 调用集合 iterator()导致集合初始化, 调用 size() 、isEmpty() 、contains() 不会对集合初始化
- 使用get/load 查询customer时,配置fetch="join" 采用迫切左外连接查询,order会被查询, 采用立即检索 lazy被忽略,如果使用Query的list方法查询,根据HQL生成SQL语句,fetch="join" 会被忽略 , lazy 重新生效
批量检索:
相关推荐
Part11:实战应用与优化 1. **性能调优**:分析影响Hibernate性能的因素,如批处理、缓存策略、连接池等,并给出优化建议。 2. **事务管理**:介绍Hibernate事务处理机制,包括编程式事务管理和声明式事务管理,...
16.3 一对多和多对多关联的检索策略 16.3.1 立即检索(lazy属性为“false”) 16.3.2 延迟检索(lazy属性为默认值“true”) 16.3.3 增强延迟检索(lazy属性为“extra”) 16.3.4 批量延迟检索和批量立即...
16.3 一对多和多对多关联的检索策略 16.3.1 立即检索(lazy属性为“false”) 16.3.2 延迟检索(lazy属性为默认值“true”) 16.3.3 增强延迟检索(lazy属性为“extra”) 16.3.4 批量延迟检索和批量立即...
16.3 一对多和多对多关联的检索策略 16.3.1 立即检索(lazy属性为“false”) 16.3.2 延迟检索(lazy属性为默认值“true”) 16.3.3 增强延迟检索(lazy属性为“extra”) 16.3.4 批量延迟检索和批量立即...
16.3 一对多和多对多关联的检索策略 16.3.1 立即检索(lazy属性为“false”) 16.3.2 延迟检索(lazy属性为默认值“true”) 16.3.3 增强延迟检索(lazy属性为“extra”) 16.3.4 批量延迟检索和批量立即...
- **多对多关联**:介绍如何在Hibernate中实现多对多关联,并给出具体的配置示例。 - **继承映射**:探讨如何使用单表、多表和联合表继承模式来映射具有层次结构的实体。 6. **事务管理** - **本地事务**:讨论...
jbpm-starters-kit-3.1.2.part1_part2 是一个分卷压缩包,它包含了jbpm-starters-kit的3.1.2版本。jbpm(Business Process Management)是开源的工作流管理系统,用于实现业务流程自动化。这个压缩包很可能包含源...
- **文件命名策略**:为了避免文件名冲突,需要设计合理的文件命名策略,例如使用时间戳或UUID。 - **文件大小限制**:为了防止DoS攻击,需要设定上传文件的大小限制。 - **安全性**:确保上传的文件类型安全,...
在这个部分(part2),我们将探讨更多与类库、代码管理、文件上传下载以及电子邮件发送等相关的内容。 首先,类库在JavaWeb开发中扮演着至关重要的角色。它们提供预封装的功能,使开发者能够快速实现特定任务,如...
本项目利用SSH(Spring、Struts2和Hibernate)框架实现上传图片并即时显示的功能,这为我们提供了一个理解Web应用程序开发中文件上传处理的实例。 首先,Spring框架作为核心的依赖注入(DI)和面向切面编程(AOP)...
3. **框架和库**:Spring、Hibernate等框架的jar文件,Spring可以用来管理应用的组件和流程,而Hibernate则可简化数据库操作。 4. **数据验证**:如javax.validation-api.jar,用于对用户输入进行验证,确保投票的...