首先是测试表的结构:
先通过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;