加载策略(优化查询)
- 策略种类:
- 延迟加载:等到使用的时候才会加载
- 立即加载:不管使不使用,都会立即将数据加载
- 策略的应用:
- 类级别的加载策略:
- get/load方法
- get:立即查询数据库,将数据初始化
- load:hbm文件中class元素的lazy属性中对类级别的load方法的加载策略
- true:先返回一个代理对象,使用代理对象的属性时,才会去查询数据库。
- false:与get方法一致,会立即加载数据
- 关联级别的加载策略:在查询有关联关系的数据时,加载一方是否需要将另一方立即查询出。
- 默认:与我关联的数据,在使用时才会加载
- 集合:
- 在set元素中lazy属性:是否对set元素的数据采用懒加载
- true:对集合使用懒加载(默认)
- false:集合将会立即加载
- extra:及其懒惰,如果使用集合时,之调用size方法查询数量, Hibernate会发送count语句,只查询数量.不加载集合内数据.
- 在set元素中fetch属性:决定加载集合使用的sql语句种类
- select:(默认值)普通select查询
- join:使用表连接语句查询集合数据
- subselect:使用子查询加载集合数据
fetch | lazy | 结论 |
---|
select | true | 默认值, 会在使用集合时加载,普通select语句 |
select | false | 立刻使用select语句加载集合数据 |
select | extra | 会在使用集合时加载,普通select语句,如果只是获得集合的长度,会发送Count语句查询长度. |
join | true | 查询集合时使用表链接查询,会立刻加载集合数据 |
join | false | 查询集合时使用表链接查询,会立刻加载集合数据 |
join | extra | 查询集合时使用表链接查询,会立刻加载集合数据 |
subselect | true | 会在使用集合时加载,子查询语句 |
subselect | false | 会在查询用户时,立即使用子查询加载客户的订单数据 |
subselect | extra | 会在使用集合时加载,子查询语句,如果只是获得集合的长度,会发送Count语句查询长度. |
public class Demo2 {
@Test
public void fun1(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Customer c = (Customer) session.get(Customer.class, 1);
for(Order o : c.getOrders()){
System.out.println(o.getName());
}
session.getTransaction().commit();
session.close();
}
@Test
public void fun2(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Customer c = (Customer) session.get(Customer.class, 1);
for(Order o : c.getOrders()){
System.out.println(o.getName());
}
session.getTransaction().commit();
session.close();
}
@Test
public void fun3(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Customer c = (Customer) session.get(Customer.class, 1);
for(Order o : c.getOrders()){
System.out.println(o.getName());
}
session.getTransaction().commit();
session.close();
}
@Test
public void fun4(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
List<Customer> list = session.createQuery("from Customer").list();
for(Customer c:list){
System.out.println(c.getName()+"下单数量:"+c.getOrders().size());
}
session.getTransaction().commit();
session.close();
}
@Test
public void fun5(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
List<Customer> list = session.createQuery("from Customer").list();
for(Customer c:list){
System.out.println(c.getName()+"下单数量:"+c.getOrders().size());
}
session.getTransaction().commit();
session.close();
}
@Test
public void fun6(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Customer c = (Customer) session.get(Customer.class, 1);
System.out.println(c.getOrders().size());
for(Order o : c.getOrders()){
System.out.println(o.getName());
}
session.getTransaction().commit();
session.close();
}
@SuppressWarnings("unchecked")
@Test
public void fun7(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
List<Customer> list = session.createQuery("from Customer").list();
for(Customer c:list){
System.out.println(c.getName()+"下单数量:"+c.getOrders().size());
}
for(Customer c:list){
for(Order o : c.getOrders()){
System.out.println(c.getName()+"下单名称:"+o.getName());
}
}
session.getTransaction().commit();
session.close();
}
}
- 多对一加载策略
- lazy:many-to-one元素中的lazy属性:
- false:加载订单时,会立即加载客户
- proxy :看客户对象的类加载策略来决定
- no-proxy :不做研究.
- fetch:
- select : (默认值)使用普通select加载
- join : 使用表链接加载数据
fetch | lazy | 结果 |
---|
select | false | 加载订单时,立即加载客户数据.普通select语句加载客户. |
select | proxy | class元素:lazy=false :同上 |
select | proxy | class元素:lazy=true:加载订单时,先不加载客户数据.使用客户数据时才加载 |
join | false | 使用表链接查询订单以及对应客户信息.lazy属性无效 |
join | proxy | 使用表链接查询订单以及对应客户信息.proxy属性无效 |
public class Demo3 {
@Test
public void fun1(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Order o = (Order) session.get(Order.class, 2);
System.out.println(o.getCustomer().getName());
session.getTransaction().commit();
session.close();
}
@Test
public void fun2(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Order o = (Order) session.get(Order.class, 2);
System.out.println(o.getCustomer().getName());
session.getTransaction().commit();
session.close();
}
@Test
public void fun3(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Order o = (Order) session.get(Order.class, 2);
System.out.println(o.getCustomer().getName());
session.getTransaction().commit();
session.close();
}
@Test
public void fun4(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Order o = (Order) session.get(Order.class, 2);
System.out.println(o.getCustomer().getName());
session.getTransaction().commit();
session.close();
}
}
- 批量加载
- 当客户关联查询订单,给每一个客户生产一个select语句查询订单。批量查询使用in语句减少查询订单语句个数。
- set元素:
- batch-size:决定一次加载几个对象的集合数据. in 条件加载多个用户的订单.
public class Demo4 {
@SuppressWarnings("unchecked")
@Test
public void fun1(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
List<Customer> list = session.createQuery("from Customer").list();
for(Customer c:list){
System.out.println(c.getOrders().size());
}
session.getTransaction().commit();
session.close();
}
@Test
public void fun2(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Order o = (Order) session.get(Order.class, 2);
System.out.println(o.getCustomer().getName());
session.getTransaction().commit();
session.close();
}
@Test
public void fun3(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Order o = (Order) session.get(Order.class, 2);
System.out.println(o.getCustomer().getName());
session.getTransaction().commit();
session.close();
}
@Test
public void fun4(){
Session session = HibernateUtils.openSession();
session.beginTransaction();
Order o = (Order) session.get(Order.class, 2);
System.out.println(o.getCustomer().getName());
session.getTransaction().commit();
session.close();
}
}
总结
果然框架就是为了提高效率的,更加便捷的为人服务的。