Hibernate--day04
非本人总结的笔记,抄点笔记复习复习。感谢传智博客及黑马程序猿
记笔记啊记笔记
Inverse属性
Inverse属性是Hibernate中的一种优化方式
有一对多关系,之前做法,是在双向维护外键关系,但是造成浪费。让一的那一方放弃关系维护,把关系维护都交给多的那一方操作。
//查询id=3的订单
Orders order = (Orders) session.get(Orders.class, 3);
//cid=2的用户
Customer customer = (Customer) session.get(Customer.class, 2);
//用户里面有订单
customer.getOrders().add(order);
//订单里面有用户
order.setCustomer(customer);
对外键的修改,修改了两次,因为双向维护外键
<!-- inverse="false" 不放弃维护
inverse="true" 放弃维护-->
<set name="setOrders" inverse="true"></set>
Inverse属性默认属性值是false
最终只是发送一条修改语句,修改数据
本地session的管理
线程与进程
使用session和本地线程绑定在一起。
可以使用sessionFactory里面的方法得到这个与本地线程绑定的session
第一步
在核心文件里面配置与本地线程绑定的session
<property name="hibernate.current_session_context_class">thread</property>
第二步
使用sessionFactory获取到与本地线程绑定的session
public static Session getCurrentSession() {
Session session = sessionFactory.getCurrentSession();
return session;
}
操作之后,session不需要手动关闭了,线程结束之后,session自动关闭
org.hibernate.SessionException:Session was already closed
Hibernate的二级缓存
什么是二级缓存
Hibernate有两个级别的缓存
一级缓存:默认是打开的,是session范围的缓存,session一旦关闭,一级缓存也就没有了
二级缓存: 默认不是打开的,手动配置,二级缓存使用需要依赖第三方插件(供应商)。二级缓存的范围是sessionFactory范围的缓存。二级缓存可以被多个session共享。
如图二级缓存存储结构
二级缓存存储结构类缓存区:查询之后返回对象的值
集合缓存区:查询之后返回的set集合
查询缓存区:查询的对象中部分的属性值
更新时间戳区:判断二级缓存数据是否是最新数据
二级缓存的存放数据
二级缓存可以被多个session共享
适合放数据 | 不适合放的数据 |
---|---|
不重要的数据 | 财务数据 |
不经常修改的数据 | 经常修改的数据 |
二级缓存的配置
第一步
导入供应商(插件)的jar包,把插件配置文件放到src下面
第一步第二步
在核心配置文件中开启二级缓存
<!-- 打开Hibernate的二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
第三步
配置使用哪一个供应商(插件)
<!-- 配置二级缓存供应商 -->
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
第四步
配置哪些数据进行二级缓存
配置方式
第一种
在实体类映射文件中配置
第二种
在核心配置文件中配置哪些实体类数据要进行二级缓存
<!-- 配置实体类进行二级缓存 -->
<class-cache usage="read-write" class="cn.xxx.Customer"></class-cache>
<class-cache usage="read-write" class="cn.xxx.Orders"></class-cache>
测试二级缓存
创建第一个session,在这个session根据oid查询记录
创建第二个session,在这个session里面查询和第一个session相同的记录
//发送sql语句查询数据库
Customer c1 = (Customer) session.get(Customer.class, 1);
System.out.println(c1);
session.close();
//创建第二个session
session1 = HibernateUtils.getSession();
//没有发送sql语句
Customer c2 = (Customer) session1.get(Customer.class, 1);
System.out.println(c2);
session1.close();
类缓存区
类缓存区缓存数据查询之后返回的对象值,在类缓存区里面存的不是整个对象,存的是对象的零散的数据。必须存完整数据
类缓存区集合缓存区
缓存是set集合内容。集合缓存区里面存储的是set集合里面每个对象的oid值。
首先,进行配置,集合缓存区依赖于类缓存区
<!-- 配置实体类进行二级缓存配置 -->
<class-cache usage="read-write" class="cn.xx.Customer"/>
<class-cache usage="read-write" class="cn.xx.Orders"/>
<!-- 配置集合缓存区 -->
<collection-cache usage="read-write" collection="cn.xx.Customer.setOrder"/>
演示集合缓存区
第一个session里面,先根据cid查询用户,在查询用户的所有订单
第二个session里面,根据cid查询用户,在查询用户的所有的订单
//创建第一个session
Session session1 = HibernateUtils.getSession();
//查询用户
Customer c1 = (Customer) session1.get(Customr.class, 2);
//查询用户的所有订单
Set<Orders> setOrders = c1.getSetOrders();
System.out.println(setOrders.size());
session1.close();
//创建第二个session
session1 = HibernateUtils.getSession();
//查询用户
Customer c2 = (Customer) session1.get(Customr.class, 2);
//查询用户的所有订单
Set<Orders> setOrders2 = c2.getSetOrders();
System.out.println(setOrders2.size());
一级缓存更新数据会同步到二级缓存
Session session1 = HibernateUtils.getSession();
Transaction tx = session1.beginTransaction();
//查询用户
Customer c1 = (Customer) session1.get(Customer.class, 4);
System.out.println(c1);
c1.setName("Lucy");
tx.commit();
session1.close();
session1 = HibernateUtils.getSession();
Transaction tx2 = session1.beginTransaction();
Customer c2 = (Customer) session1.get(Customer.class, 4);
System.out.println(c2);
tx2.commit();
session1.close();
更新时间戳区
判断缓存中的数据是否是最新的数据
时间戳区查询缓存区
可以缓存部分属性
第一步
配置打开查询缓存区
<!-- 打开查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
第二步
查询数据的时候,调用方法
//查询用户
Query query = session1.createQuery("select cname from Customer");
//调用方法
List list = query.setCacheable(true).list();
System.out.println(list);
tx.commit();
session1.close();
//创建第二个session
session1 = HibernateUtils.getSession();
Transaction t = session1.beginTransaction();
//查询用户
Query q = session1.createQuery("select cname from Customer");
//调用方法
List l = q.setCacheable(true).list();
System.out.println(l);