类级别的检索策略:
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 重新生效
批量检索:
相关推荐
NULL 博文链接:https://sxpujs.iteye.com/blog/370855
NULL 博文链接:https://chinrui.iteye.com/blog/1859820
NULL 博文链接:https://mvplee.iteye.com/blog/2186414
http://sourceforge.net/projects/hibernate/files/hibernate3/--3.XX版本 http://sourceforge.net/projects/hibernate/files/hibernate4/--4.XX版本 IBATS下载地址:...
版本差异太难搞了,找半天才找到错误,主要是包冲突 NoSuchMethodError: org.jboss....NoClassDefFoundError: org/hibernate/cache/spi/RegionFactory org.hibernate.cache.spi.RegionFactory 记录下来,以备不时
NULL 博文链接:https://mvplee.iteye.com/blog/2239488
NULL 博文链接:https://mvplee.iteye.com/blog/2186102
NULL 博文链接:https://mvplee.iteye.com/blog/2186235
博文链接:https://ag-bruce.iteye.com/blog/213436
NULL 博文链接:https://mvplee.iteye.com/blog/2186283
NULL 博文链接:https://364232252.iteye.com/blog/2368725
一、 项目名称:S2316S411H436 项目原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6 ...http://softlayer-sng.dl.sourceforge.net/project/hibernate/hibernate4/4.3.6.Final/hibernate-release-4.3.6.Final.zip
NULL 博文链接:https://wfq5154.iteye.com/blog/1714952
hibernate.dialect = org.hibernate.dialect.MySQLDialect //指定数据库使用的sql方言(oracle、mysql) hibernate.connection.driver_class=com.mysql.jdbc.Driver //指定数据库的驱动程序 hibernate.connection....
代码使用技术包含SpringSecurity4.2.3、Hibernate5.x、Lucene5.5.4、SpringMVC & Spring4.3.9、Bootstrap3.3.7、HTML5、JDK7+、MySQL、Maven 适用于个人练习,企业二次开发。 之前提供的两个版本忘记附上数据库账号...
NULL 博文链接:https://quicker.iteye.com/blog/660498
NULL 博文链接:https://364232252.iteye.com/blog/2368583