one-to-one many-to-one 的检索策略介绍 package com.macower.hibernate.strategy; import java.util.Iterator; import java.util.List; import junit.framework.TestCase; import org.hibernate.Session; public class OrderManyOneTest extends TestCase { public void testLazyFetchGet() throws Exception { Session session = HibernateUtils.getSession(); /* * get方法采用的是立即检索的策略 当Order.hbm.xml 中的<many-to-one name="customer" * class="com.macower.hibernate.strategy.Customer" lazy="false" * fetch="join"></many-to-one> 如果Customer中采用的lazy=true那么 * 的fetch采用的join那么此时进行的是迫切的左外连接策略,并且支持的是延迟加载的策略。 * */ session.get(Order.class, 1); } /** * 但是如果在Customer中采用的是lazy=false的方式,那么,在进行fetch后还会对Customer进行关联查询发出相应的SQL语句 * 但是我们需要注意的是假设采用list()方法那么将会忽略fetch属性。 在Order.hbm.xml中 <many-to-one * name="customer" class="com.macower.hibernate.strategy.Customer" * fetch="join"/> 在Customer.hbm.xml中 <set name="orders" cascade="all" * inverse="true" lazy="true" > 在第一行就会发出SQL语句查询到对应的Order的对象 由于<set>上设置了lazy=true所以在第五行才会发出SQL语句查询相应的customer * */ @SuppressWarnings("unchecked") public void testFetchJoinList() throws Exception { Session session = HibernateUtils.getSession(); List<Order> orders = session.createQuery("from Order o").list();// 第一行 Iterator<Order> iter = orders.iterator();// 第2行 Order o1 = iter.next();// 第3行 Customer customer = o1.getCustomer();// 第4行 String cusName = customer.getName();// //第5行 } /** * 在<many-to-one name="customer" * class="com.macower.hibernate.strategy.Customer" lazy="proxy">的情况下 * * @throws Exception */ public void testProxy() throws Exception { Session session = HibernateUtils.getSession(); /* * 第一行发出SQL查询出来Order对象 */ Order o1 = (Order) session.get(Order.class, 1);// 第1行 Customer customer = o1.getCustomer();// 第2行 int id = customer.getId();// 3 /* * 在第四行发出SQL查询customer对象 */ String cusName = customer.getName();// //第4行 } /** * 在<many-to-one name="customer" * class="com.macower.hibernate.strategy.Customer" lazy="no-proxy">的情况下 * * @throws Exception */ public void testNoProxy() throws Exception { Session session = HibernateUtils.getSession(); /* * 第一行发出SQL查询出来Order对象 */ Order o1 = (Order) session.get(Order.class, 1);// 第1行 Customer customer = o1.getCustomer();// 第2行 int id = customer.getId();// 3 /* * 在第四行发出SQL查询customer对象 */ String cusName = customer.getName();// //第4行 } //不设置批量查询 public void testBatch() throws Exception { Session session = HibernateUtils.getSession(); /** * 发出SQL查询Order */ List<Order> orders = session.createQuery("from Order as c").list(); Iterator<Order> iter = orders.iterator(); Order o1 = iter.next(); Order o2 = iter.next(); Order o3 = iter.next(); Order o4 = iter.next(); // 不发出SQL Customer c1 = o1.getCustomer(); if (c1 != null) { // 发出SQL查询Customer c1.getName(); } // 不发出SQL Customer c2 = o2.getCustomer(); if (c2 != null) { // 不发出SQL,原因在于此时的Order的对象所指向的c2所引用的对象已经指向了c1,c1和c2共用一个Customer,所以不会发出SQL c2.getName(); } // 不发出SQL Customer c3 = o3.getCustomer(); if (c3 != null) { // 发出SQL查询Customer c3.getName(); } // 不发出SQL Customer c4 = o4.getCustomer(); if (c4 != null) { // 发出SQL查询Customer c4.getName(); } } //在Customer.hbm.xml的设置<class name="com.macower.hibernate.strategy.Customer" batch-size="2" public void testBatchSize() throws Exception { Session session = HibernateUtils.getSession(); /** * 发出SQL查询Order */ List<Order> orders = session.createQuery("from Order as c").list(); Iterator<Order> iter = orders.iterator(); Order o1 = iter.next(); Order o2 = iter.next(); Order o3 = iter.next(); Order o4 = iter.next(); // 不发出SQL Customer c1 = o1.getCustomer(); if (c1 != null) { // 发出SQL查询Customer c1.getName(); } // 不发出SQL Customer c2 = o2.getCustomer(); if (c2 != null) { // 不发出SQL,原因在于此时的Order的对象所指向的c2所引用的对象已经指向了c1,c1和c2共用一个Customer,所以不会发出SQL c2.getName(); } // 不发出SQL Customer c3 = o3.getCustomer(); if (c3 != null) { // 不发出SQL ,此时已经进行了批量查询(设置了batch-size="2"),在session已经存在所以只在缓存中取出来,而不发出具体的SQL c3.getName(); } // 不发出SQL Customer c4 = o4.getCustomer(); if (c4 != null) { // 发出SQL查询Customer c4.getName(); } } }