更多资源分享就在【Java帮帮】微信公众号与QQ空间
Hibernate_day04总结
今日内容
l Hibernate的二级缓存
1.1 上次课内容回顾:
Hibernate的检索方式
* 对象导航的方式:customer.getOrders()
* OID检索方式:get/load
* HQL检索:
* 简单查询:from Customer
* 别名查询:from Customer as c
* 多态查询:from java.lang.Object
* 排序查询:from Customer order by age asc
* 分页查询:setFirstResult().setMaxResults();
* 条件查询:from Customer where cname like ? and age > ?
* 聚合函数:select count(*) from Customer
* 分组查询:select o.customer.cid,count(*) from Orders o group by o.customer.cid;
* 投影查询:select cname,age from Customer
* 连接查询:
* 内连接:
* from Customer c inner join c.orders;
* 外连接:
* left outer join
* right outer join
* QBC检索:
* 简单查询:session.createCriteria(Customer.class);
* 排序查询:criteria.addOrder(Order.asc(“age”));
* 分页查询:criteria.setFirstResult().setMaxResults();
* 条件查询:criteria.add();
* 离线条件查询:DetachedCriteria.
* SQL检索:
Hibernate的检索策略
* fetch和lazy:
* <set>标签上:
* fetch:
* select
* join
* subselect
* lazy:
* true
* false
* extra
* <many-to-one>
* fetch:
* select
* join
* lazy:
* proxy
* false
* no-proxy
* 批量抓取:
* batch-size=
Hibernate的事务管理
* 配置事务隔离级别:
* 解决写问题:
* 悲观锁
* 乐观锁
* 与线程绑定的session的使用.
1.2 Hibernate的二级缓存:
1.2.1 Hibernate的二级缓存:
什么是缓存:
计算机领域非常通用的概念。它介于应用程序和永久性数据存储源(如硬盘上的文件或者数据库)之间,其作用是降低应用程序直接读写永久性数据存储源的频率,从而提高应用的运行性能。缓存中的数据是数据存储源中数据的拷贝。缓存的物理介质通常是内存
Hibernate二级缓存:
Hibernate总共分成两个级别的缓存.一级缓存:与session生命周期相关的,称为是session的级别的缓存.二级缓存可以在多个session中共享数据.范围相当于sessionFactory的范围.二级缓存称为是sessionFactory级别的缓存.
Hibernate的一级缓存,自带的,不可卸载.Hibernate的二级缓存需要自己配置.默认没有开启的.
Hibernate的二级缓存的内部结构:
Class Cache Region :类缓存区
Collection Cache Region :集合缓存区
Query Cache Region :查询缓存区
Update timestamps :更新时间戳区
Hibernate的并发策略:
Transactional :事务型. 缓存支持事务,发生异常的时候,缓存也能够回滚
Read-write :读写型. 更新缓存的时候会锁定缓存中的数据
nonstrict-read-write:非严格读写型. 不锁定缓存中的数据
Read-only :只读型. 适用从来不会被修改的数据
Hibernate的二级缓存存放的数据:
适合放入二级缓存:
数据不经常修改.
偶尔允许出现并发问题.
不适合放入二级缓存:
经常变化数据.
财务上的数据.
与其他应该共享的数据.
Hibernate支持的二级缓存的提供商:
1.2.2 Hibernate的二级缓存的入门:
步骤一:创建一个java项目,搭建hibernate的开发环境.
步骤二:引入二级缓存需要使用的jar包.
采用EHCache作为Hibernate的二级缓存的插件:
引入EHCache的使用jar包:
步骤三:引入EHCache的配置文件:
在src下引入ehcache的配置文件.
步骤四:在Hibernate的核心配置文件中完成配置:
<!-- 开启Hibernate的二级缓存 -->
<propertyname="hibernate.cache.use_second_level_cache">true</property>
<!-- 配置二级缓存的提供商. -->
<propertyname="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
步骤五:配置哪些类需要使用二级缓存.
两种配置方式:
* 第一种配置方式:
* 在这个持久化类的映射中配置:
* 在<class>标签下使用<cache>标签:
<cache usage="read-write"/>
* 第二种配置方式:
* 在核心配置文件中进行统一配置:
<!-- 配置哪些类需要放入到二级缓存 -->
<class-cacheusage="read-write"class="cn.itcast.hibernate.demo1.Customer"/>
<class-cacheusage="read-write"class="cn.itcast.hibernate.demo1.Order"/>
<collection-cacheusage="read-write"collection="cn.itcast.hibernate.demo1.Customer.orders"/>
步骤六:使用二级缓存.
@Test
/**
* 配置二级缓存
*/
publicvoid demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer1 = (Customer) session.get(Customer.class, 1); // 发送一条SQL语句
System.out.println(customer1);
tx.commit();
session.close();
session = HibernateUtils.openSession();
tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 1); // 没有发送SQL语句
System.out.println(customer2);
tx.commit();
session.close();
}
1.2.3 Hibernate的二级缓存的类缓冲区的特点:
@Test
/**
* 配置二级缓存
*/
publicvoid demo2(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer1 = (Customer) session.get(Customer.class, 1); // 发送一条SQL语句
Customer customer2 = (Customer) session.get(Customer.class, 1); //
System.out.println(customer1 == customer2); // true. 一级缓存缓存是对象的地址.
tx.commit();
session.close();
session = HibernateUtils.openSession();
tx = session.beginTransaction();
Customer customer3 = (Customer) session.get(Customer.class, 1); // 没有发送SQL语句
Customer customer4 = (Customer) session.get(Customer.class, 1); //
System.out.println(customer3 == customer4); // true. 一级缓存缓存是对象的地址.
System.out.println(customer1 == customer3); // false. 二级缓存的类缓存区 缓存的不是对象的地址,缓存的是 对象的散装的数据.
tx.commit();
session.close();
}
1.2.4 Hibernate的二级缓存的集合缓冲区的特点:
集合缓冲区依赖类缓冲区,而且集合缓存区只会缓存对象的ID.
@Test
/**
* 二级缓存的集合缓冲区的特点:
*/
publicvoid demo3(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer = (Customer) session.get(Customer.class, 1);
for (Order order : customer.getOrders()) {
System.out.println(customer.getCname());
System.out.println(order);
}
tx.commit();
session.close();
session = HibernateUtils.openSession();
tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 1);
for (Order order : customer2.getOrders()) {
System.out.println(customer2.getCname());
System.out.println(order);
}
tx.commit();
session.close();
}
1.2.5 Hibernate的iterate方法和list方法的比较:
@SuppressWarnings("unchecked")
@Test
/**
* get/load方法可以向二级缓存存放数据,而且也会使用二级缓存中的数据.
* Query中list方法.这个方法只会向二级缓存中存入数据,但是不使用二级缓存的数据.
*/
publicvoid demo4(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
List<Customer> list = session.createQuery("from Customer").list();
for (Customer customer : list) {
System.out.println(customer);
}
tx.commit();
session.close();
session = HibernateUtils.openSession();
tx = session.beginTransaction();
/*List<Customer> list2 = session.createQuery("from Customer").list();
for (Customer customer : list2) {
System.out.println(customer);
}*/
Customer customer = (Customer) session.get(Customer.class, 1);
System.out.println(customer);
tx.commit();
session.close();
}
@SuppressWarnings("unchecked")
@Test
/**
* iterate和list方法:
* * 这两个方法都可以查询多条记录:
* * iterate方法向二级缓存存放数据,也会使用二级缓存的数据.
*/
publicvoid demo5(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
// iterate方法发送 N+1 语句.
Iterator<Customer> it = session.createQuery("from Customer").iterate();
while(it.hasNext()){
Customer customer = it.next();
System.out.println(customer);
}
tx.commit();
session.close();
session = HibernateUtils.openSession();
tx = session.beginTransaction();
// iterate方法发送 N+1 语句.
Iterator<Customer> it2 = session.createQuery("from Customer").iterate();
while(it2.hasNext()){
Customer customer = it2.next();
System.out.println(customer);
}
tx.commit();
session.close();
}
1.2.6 Hibernate的一级缓冲区的更新,同步到二级缓冲区:
@Test
/**
* 更新一级缓冲区的时候,同步更新二级缓冲区.
*/
publicvoid demo6(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer1 = (Customer) session.get(Customer.class, 1);
customer1.setCname("小马");
tx.commit();
session.close();
session = HibernateUtils.openSession();
tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 1);
System.out.println(customer2);
tx.commit();
session.close();
}
1.2.7 Hibernate的更新时间戳区:
@Test
/**
* 更新时间戳区域:
*/
publicvoid demo8(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
Customer customer1 = (Customer) session.get(Customer.class, 1);
System.out.println(customer1);
session.createQuery("update Customer set cname = '小马' where cid = 1").executeUpdate();
tx.commit();
session.close();
session = HibernateUtils.openSession();
tx = session.beginTransaction();
Customer customer2 = (Customer) session.get(Customer.class, 1);
System.out.println(customer2);
tx.commit();
session.close();
}
1.2.8 Hibernate的二级缓存的查询缓冲区:
查询缓存的概述
查询缓存比二级缓存更加强大.二级缓存缓存整个对象.不能缓存对象的部分属性.
select cname,age from Customer;查询缓存可以缓存对象的部分属性.
查询缓存需要在二级缓存的基础上使用.查询需要进行一个配置.(查询缓存默认不开启)
配置查询缓存
<!-- 开启查询缓存 -->
<propertyname="hibernate.cache.use_query_cache">true</property>
编写程序的时候调用一个方法:
query.setCacheable(true)
@SuppressWarnings("unchecked")
@Test
/**
* 查询缓冲区
*/
publicvoid demo9(){
Session session = HibernateUtils.openSession();
Transaction tx = session.beginTransaction();
List<Object[]> list = session.createQuery("select cname,age from Customer").setCacheable(true).list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
tx.commit();
session.close();
session = HibernateUtils.openSession();
tx = session.beginTransaction();
list = session.createQuery("select cname,age from Customer").setCacheable(true).list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
tx.commit();
session.close();
}
1.3 Struts2+Hibernate:完成一个一对多的CRUD的操作.
1.3.1 Struts2和Hibernate的整合
步骤一:创建一个WEB项目,引入相关的jar包.
引入struts2的jar包:
引入hibernate3的jar包:
步骤二:引入相关的配置文件:
Struts2框架:
* web.xml
<!-- 配置Struts2的核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
* struts.xml
Hibernate框架:
* hibernate.cfg.xml
* 映射文件:
* log4j.properties
步骤三:创建包结构:
步骤四:创建实体和映射:
客户和订单:
步骤五:显示所有客户信息.(customer_findAll.action)
编写Action Service DAO
Action的代码:
/**
* 查询所有的客户的执行的方法:
*/
public String findAll(){
// 调用业务层:
CustomerService customerService = new CustomerService();
List<Customer> list = customerService.findAll();
// 保存到值栈中.
ActionContext.getContext().getValueStack().set("list", list);
return"findAll";
}
步骤六:添加客户:
新建add.jsp
编写Action,Service,DAO
步骤六:修改客户:
在列表页面上点击修改:
提交到Action:
* 查询当前对象.
* 回显到页面.
在修改页面上输入信息:
* 点击确定.
* 提交到Action,修改到数据库.
* 页面列表页面.
步骤七:删除客户:
在列表页面上点击删除链接:
* 提交到Action:
* 先查询再删除.(级联删除)
* 页面跳转.
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有