title: Hibernate中抓取策略的fecth和lazy - 2

date: 2018-2-17 15:51:32

categories: Hibernate

tags: Hibernate


xl_echo编辑整理

Hibernate中抓取策略的fecth和lazy - 2

主要作用就是在一对多中,在一的一方如何获取多的一方

测试Java代码

package com.echo.hibernate.SetFetchTest;

import org.hibernate.Session;
import org.hibernate.annotations.LazyToOne;
import org.hibernate.annotations.LazyToOneOption;
import org.junit.Test;

import com.echo.hibernate.domain.Customer;
import com.echo.hibernate.domain.Orders;
import com.echo.hibernate.utils.HibernateUtils;
/**
* 在多的一方设置fetch和lazy
* @author XL-sorry
*
*/
public class OneFetchTest {

@Test
/**
* fetch设置为默认值(select)、@LazyToOne(LazyToOneOption.proxy)。同时需要在Customer类上面设置@proxy(lazy=false)
* 结果:发送简单的sql语句,不延迟加载,之后使用客户信息会直接在获取的信息中获取
*/
public void Test1(){

Session session = HibernateUtils.getSession();
session.beginTransaction();

Orders orders = session.get(Orders.class, 1);

Customer c = orders.getC();

System.out.println(c.getName());

session.beginTransaction().commit();
session.close();
}

@Test
/**
* fetch设置为默认值(select)、@LazyToOne(LazyToOneOption.proxy)。同时需要在Customer类上面设置@proxy(lazy=true)
* 结果:发送简单的sql语句,查询订单信息时不会查询客户信息,只有真正用到客户信息时才会发送sql语句
*/
public void Test2(){

Session session = HibernateUtils.getSession();
session.beginTransaction();

Orders orders = session.get(Orders.class, 1);

Customer c = orders.getC();

System.out.println(c.getName());

session.beginTransaction().commit();
session.close();
}

@Test
/**
* fetch设置为默认值(select)、@LazyToOne(LazyToOneOption.FALSE)。同时需要在Customer类上面设置@proxy(lazy=true)
* 结果:查询订单信息时,及时查询客户信息
*/
public void Test3(){

Session session = HibernateUtils.getSession();
session.beginTransaction();

Orders orders = session.get(Orders.class, 1);

Customer c = orders.getC();

System.out.println(c.getName());

session.beginTransaction().commit();
session.close();
}

@Test
/**
* fetch设置为(join)、@LazyToOne(LazyToOneOption.FALSE)。同时需要在Customer类上面设置@proxy(lazy=true)
* 结果:fetch设置为join那么lazy就会失效
*/
public void Test4(){

Session session = HibernateUtils.getSession();
session.beginTransaction();

Orders orders = session.get(Orders.class, 1);

Customer c = orders.getC();

System.out.println(c.getName());

session.beginTransaction().commit();
session.close();
}

@Test
/**
* 查询所有的客户信息,并将所有客户的信息查询
* 需要配合注解,在customer的orders上面设置@BatchSize(size=3)
* 如果是查询订单,在查询所有客户,需要在customer的上面设置@BatchSize(size=3)
*/
public void Test5(){
Session session = HibernateUtils.getSession();
session.beginTransaction();

List<Customer> list = session.createQuery("from Customer").list();

for(Customer c : list){
System.out.println(c.getOrders().size());
}

session.beginTransaction().commit();
session.close();
}

}

实体类

package com.echo.hibernate.domain;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.annotations.Proxy;
/**
* 客户类,注解开发一对多
* @author XL-sorry
* catalog可以省略,默认直接从核心配置文件中加载
*/
@Entity
@Table(name="t_customer",catalog="myxlsorry")
/*@NamedQuery(name="myhql",query="from Customer")*/
@Proxy(lazy=true)//这个代表的是类级别检索时,类的延迟加载。也可以在映射配置文件中Class的位置设置lazy=true,
///默认值为true。如果将这个设置为false,那么session.load(),就和session.get一样了
public class Customer {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;//主键
private String name;//客户姓名

/**
* 在关系属性上使用OnetoMany,代表的就是该类对另外一个类是一对多的映射关系
* targetEntity=Orders.class声明多的那个类是哪一个
* mappedBy="c",在orders中的属性,定义属于那个客户就是c,所以配置它,代表着由orders维护外键
*/
@OneToMany(targetEntity=Orders.class,mappedBy="c",orphanRemoval=true)
/*@Cascade(CascadeType.SAVE_UPDATE)*/
/**
* fetch可以使用的值有
* select:多条简单的sql(默认值)
* join:采用迫切左外连接
* subselect:将生成子查询的sql
* lazycollection可以使用的值有
* true:延迟检索(默认值)
* false:立即检索
* extra:加强延迟检索(及其懒惰)
*/
@Fetch(FetchMode.SELECT)
@LazyCollection(LazyCollectionOption.TRUE)
private Set<Orders> orders = new HashSet<>();

public Customer() {
super();
}
public Customer(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Orders> getOrders() {
return orders;
}
public void setOrders(Set<Orders> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "Customer [id=" + id + ", name=" + name + "]";
}

}


package com.echo.hibernate.domain;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
import org.hibernate.annotations.LazyToOne;
import org.hibernate.annotations.LazyToOneOption;
import org.hibernate.annotations.NamedQuery;

/**
* 订单类,注解开发多对一
* @author XL-sorry
*
*/
@Entity
@Table(name="t_orders",catalog="myxlsorry")
@NamedQuery(name="findOrdersByCustomer",query="from Orders where c = :c")
public class Orders {

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;//订单编号
private String address;//收货地址
private Double money;//订单金额

/**
* 指定关联哪一个类
*/
@ManyToOne(targetEntity=Customer.class)
//指定级联
// @Cascade(CascadeType.SAVE_UPDATE)
//生成外键的名字叫什么
@JoinColumn(name = "c_customer_id")
@Cascade(CascadeType.ALL)
/**
* fetch可取值有两个
* select:代表发送一条或者多条简单的select语句。(默认值)
* join:发送一条迫切左外连接
* LazyToOne可取值有三个
* false:不采用延迟加载
* proxy:是否采用延迟,需要另一方的类级别延迟策略来决定
* no-proxy:不推荐研究
*/
@Fetch(FetchMode.SELECT)
@LazyToOne(LazyToOneOption.FALSE)
private Customer c;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
public Customer getC() {
return c;
}
public void setC(Customer c) {
this.c = c;
}
@Override
public String toString() {
return "Orders [id=" + id + ", address=" + address + ", money=" + money + ", c=" + c + "]";
}
}