当前位置: 代码迷 >> SQL >> Hibernate的对象检索计策 (一) SQL左外连接检索策略
  详细解决方案

Hibernate的对象检索计策 (一) SQL左外连接检索策略

热度:22   发布时间:2016-05-05 11:54:22.0
Hibernate的对象检索策略 (一) SQL左外连接检索策略
首先是测试表的结构:



先通过hibernate将数据放入数据库,如下:
		Session session = HibernateUtil.openSession();				Transaction tx=session.beginTransaction();				User u1=new User(1,"Tom",19);		User u2=new User(2,"Mike",19);		User u3=new User(3,"Jack",19);		User u4=new User(4,"Linda",19);				Order o1=new Order(1,"Tom_Order001",u1);		Order o2=new Order(2,"Tom_Order002",u1);		Order o3=new Order(3,"Mike_Order001",u2);		Order o4=new Order(4,"Jack_Order001",u3);		Order o5=new Order(5,"Linda_Order001",u4);				u1.setOrders(ArraysHelper.asSet(o1,o2));		u2.setOrders(ArraysHelper.asSet(o3));		u3.setOrders(ArraysHelper.asSet(o4));		u4.setOrders(ArraysHelper.asSet(o5));				session.save(u1); 		session.save(u2); 		session.save(u3); 		session.save(u4);						tx.commit();


====================================================
数据加入之后, 看一下检索的方法。

第一种是:
List userList=session.createQuery("from User as u").list();for(User u:userList){			System.out.println(u.getOrders().iterator().next().getName());		}


-运行以上方法时,Hibernate将先查询User表中的所有记录,然后根据每条记录的ID,到Order表中查询有关的记录,Hibernate将以此执行以下select语句:

select * from User;
select * from Order where customer_id=1;
select * from Order where customer_id=2;
select * from Order where customer_id=3;
select * from Order where customer_id=4;

上述方法的缺点:
-select语句的数目太多,需要频繁的访问数据库,会影响检索性能。如果需要查询n个User对象,那么必须执行n+1次select查询语句。这种检索策略没有利用SQL的链接查询功能。

SQL左外连接检索策略
一.通过配置文件指定自动左外连接检索

例如以上5条select语句完全可以通过以下1挑select语句来完成:
select * from User left outer join Order on User.id = Order.Customer_id



-以上select语句使用了SQL的左外连接查询功能,能够在一条select语句中查询出User表的所有记录,以及匹配的Order表的记录。

在Hibernate中, 多对一的关联配置文件中可以配置使用左外连接检索策略。
把Order.hbm.xml文件的<many-to-one>元素的outer-join属性设置为true,程序执行时就会自动使用左外连接检索策略。
运行结果如下:



通过此方法, 当运行下面的代码时:
Order order=(Order) session.get(Order.class, 1);				System.out.println(order.getName());				System.out.println(order.getUser().getName());


就只会像数据库发送一条左外连接的select语句,大大降低了数据库开销。
输出结果:
Hibernate: select order0_.id as id1_1_1_, order0_.test_name as test2_1_1_, order0_.customer_id as customer3_1_1_, user1_.id as id1_3_0_, user1_.test_name as test2_3_0_, user1_.test_age as test3_3_0_ from test_order order0_ left outer join test_user user1_ on order0_.customer_id=user1_.id where order0_.id=?
Tom_Order001
Tom




二. 在程序中显式指定左外连接策略检索
- 以下Session的方法都用于检索OID为1的User对象。
session.createQuery("from User as u where u.id=1");
session.createQuery("from User as u left join fetch u.orders where u.id=1");

在执行第一个方法时,Hibernate会使用映射文件配置的检索策略。
在执行第二个方法时,在HQL语句中显式指定左外连接检索关联的Order对象,因此会覆盖映射文件配置的检索策略。不管在User.hbm.xml文件中<set>元素的lazy属性是true还是false,Hibernate都会执行以下select语句:

select * from User left outer join Order on User.id = Order.customer_id where User.id=1;


  相关解决方案