原则:
- 1.不浪费内存,只加载使用的数据
- 2.更高的查询效率,发送尽可能少的SQL语句
类级别检索策略
- 1.立即检索:立即加载检索方法指定对象
- 2.延迟检索:延迟加载检索方法指定对象
可以通过元素的lazy属性设置
建立一对多(持久化类)
一端(用户)
public class User {
private Integer uid;
private String name;
//声明集合类型是需要接口类型,应为在hibernate返回的是内置集合类型
//要初始化防止空指针
private Set houses=new HashSet<>();
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set getHouses() {
return houses;
}
public void setHouses(Set houses) {
this.houses = houses;
}
}
多端(房产)
public class House {
private Integer hid;
private String hName;
private User user;
public Integer getHid() {
return hid;
}
public void setHid(Integer hid) {
this.hid = hid;
}
public String gethName() {
return hName;
}
public void sethName(String hName) {
this.hName = hName;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((hid == null) ? 0 : hid.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
House other = (House) obj;
if (hid == null) {
if (other.hid != null)
return false;
} else if (!hid.equals(other.hid))
return false;
return true;
}
}
映射配置文件
用户:
房产:
lazy属性:只对load方法有效
- lazy="false"立即加载 lazy="true"延迟加载 默认是true
在什么情况使用:
1.程序加载一对象的目的是为了访问其属性,可以采用立即检索
2.程序加载持久化对象目的是仅仅为了获取它的引用,可以采用延迟检索,注意懒加载异常
3.lazy属性只对load方法有效
4.可以访问OID属性不会检索
步骤:
修改User 映射文件 class元素
调用
/**
* 测试lazy属性
* 1.lazy="false"立即加载 lazy="true"延迟加载 默认是true
* 在什么情况使用:
* 1.程序加载一对象的目的是为了访问其属性,可以采用立即检索
* 2.程序加载持久化对象目的是仅仅为了获取它的引用,可以采用延迟检索,注意懒加载异常
* 3.lazy属性只对load方法有效
* 4.可以访问OID属性不会检索
*/
public static void testOneToManyGet() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();// 配置文件configure()
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
User customer = session.load(User.class, 1);
System.out.println(customer.getClass());
System.out.println(customer.getUid());
transaction.commit();
session.close();
sessionFactory.close();
}
一对多 多对多的检索策略:set元素的属性
lazy属性
1.1-n或n-n的集合属性默认懒加载
2.通过设置set lazy属性修改检索策略 默认是true(懒加载)不建议改成false
3.lazy还可以设置为extra,增强的延迟加载,尽可能延续集合加载
4.初始化显示调用Hibernate.initialize() 可以直接初始化
修该映射文件集合set
调用
/**
* 测试lazy属性
*1.1-n或n-n的集合属性默认懒加载
*2.通过设置set lazy属性修改检索策略 默认是true(懒加载)不建议改成false
*3.lazy还可以设置为extra,增强的延迟加载,尽可能延续集合加载
*4.初始化显示调用Hibernate.initialize() 可以直接初始化
* */
public static void testSetLazy() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();// 配置文件configure()
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
//测试extra值
User customer = session.get(User.class, 1);
//获取集合长度
System.out.println(customer.getHouses().size());//不会查询 使用count语句
//集合是否包涵
//要重写持久化类hashCode()和equals()方法
House house=new House();
house.setHid(1);
System.out.println(customer.getHouses().contains(house));//不会初始化
transaction.commit();
session.close();
sessionFactory.close();
}
batch-size属性 批量个数
- 1.为立即 延迟检索设定批量检索的数量,批量检索能减少SELECT语句数目,提高性能
- 要一个个获取集合对应的数据时是一批一批获取
修该映射文件集合set
调用
/**
* 测试batch-size属性 批量个数
* 1.为立即 延迟检索设定批量检索的数量,批量检索能减少SELECT语句数目,提高性能
*
* */
public static void testSetBatchSize() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();// 配置文件configure()
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
List list=session.createQuery("FROM User").list();//查询所有用户
System.out.println("用户"+list.size());
for (User user : list) {//查询用户房产数
if(user.getHouses()!=null) {
System.out.println("用户房产"+user.getHouses().size());
}
}
transaction.commit();
session.close();
sessionFactory.close();
}
fetch属性:确定集合初始化的方式
修该映射文件集合set
调用
/**
* fetch属性:确定集合初始化的方式
* 1.fetch="select"默认值 正常方式初始化
*
* 2.fetch="subselect"通过子查询初始所有set集合,子查询
* 作为where子句的in的条件出现,子查询查询所有1的一端的ID,此时lazy有效
* batch-size无效
*
* 3.fetch="join"
*
* */
public static void testSetFetch() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();// 配置文件configure()
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
List list=session.createQuery("FROM User").list();//查询所有用户
System.out.println("用户"+list.size());
for (User user : list) {//查询用户房产数
if(user.getHouses()!=null) {
System.out.println("用户房产"+user.getHouses().size());
}
}
transaction.commit();
session.close();
sessionFactory.close();
}
多对一 一对一检索策略
1.lazy="false"立即检索 lazy="proxy"延迟检索 默认
2.fetch="join" 使用左外链接初始化n关联的1的一端属性
3.batch-size设置在1的那端class元素上 作用一次初始化1端这一段代理对象个数
映射文件配置
lazy属性
fetch属性
调用
/**
* 1.lazy="false"立即简述 lazy="proxy"延迟检索 默认
* 2.fetch="join" 使用左外链接初始化n关联的1的一端属性
* 3.batch-size设置在1的那端class元素上 作用一次初始化1端这一段代理对象个数
*
* */
public static void testSetOneLazy() {
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();// 配置文件configure()
SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
House house=session.get(House.class, 1);
System.out.println(house);
transaction.commit();
session.close();
sessionFactory.close();
}