*一)hibernate的检索方式【HQL查询】
(1)已学过的查询方式及其特点
A)根据id查询客户订单信息,分别使用get()和load()二种方式
get:
1)如果找到了,返回该对象;如果找不到,返回null
2)session.get(Customer.class,1)
3)有产生SQL,即立刻检索
4)返回的对象是一个真实对象,即该对象中的每个属性都有值
load:
1)如果找到了,返回该对象;如果找不到,抛出异常,ObjectNotFoundException
2)session.load(Customer.class,1)
3)无产生SQL,延迟检索
4)返回的对象是一个代理对象,即该对象中除id之外,都无值,
该id值,不是查询数据库得到的,而是hibernate为其分配的OID值。
只有当查询非ID属性时,才会返回真实对象
B)通过对象导航方式查询所需要的对象
Customer c = get();
for(Order o : c.getOrders){
.. .. ..
}
(2)HQL与SQL的区别
HQL:(Hibernate专用查询语言):在Java程序员,使用HQL语句,发送到hibernate框架,框架再根据你配置的
方言,将其自动转成与底层数据库一致的SQL,从而间接操作数据库。
select id,name from Customer where name like '小%';
HQL只能出现属性名,类名,以及条件
SQL:(结构化查询语言),只争对关系型数据库而言,通过SQL,能够在数据库中查询出你需要一切内容
select id,name from customers where name like '小%';
SQL只能出现字段名,表名,以及条件
(3)使有HQL
A)查询姓名为“XX”的客户订单信息
public void test2() { Session session = sessionFactory.openSession(); String hql = "from Customer where name='小雪'"; Query query = session.createQuery(hql); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer.getName() + "的订单"); for (Order order : customer.getOrders()) { System.out.println(order.getOrderno() + ":" + order.getPrice()); } } }
B)使用别名,查询姓名为“XX”的客户订单信息
public void test3() { Session session = sessionFactory.openSession(); String hql = "from Customer c where c.name='小雪'"; Query query = session.createQuery(hql); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer.getName() + "的订单"); for (Order order : customer.getOrders()) { System.out.println(order.getOrderno() + ":" + order.getPrice()); } } }
C)共有几个对象,共有几个客户,共有几个订单,多态查询(是指查询出当前类或所有子类的实例)
public void test4() { Session session = sessionFactory.openSession(); String hql = "from java.lang.Object"; Query query = session.createQuery(hql); List<Object> objlist = query.list(); System.out.println(objlist.size()); }
D)查询所有订单,按价格降序排列[ASC,DESC]
public void test5() { Session session = sessionFactory.openSession(); String hql = "from Order as o order by o.price asc"; Query query = session.createQuery(hql); List<Order> list = query.list(); for (Order order : list) { System.out.println(order.getOrderno() + ":" + order.getPrice()); } }
E)分页查询订单,每页显示X条记录【动手练习】
@Test public void test6() { Session session = sessionFactory.openSession(); String hql = "from Order as o order by o.price asc"; Query query = session.createQuery(hql); query.setFirstResult(0); query.setMaxResults(3); List<Order> list = query.list(); for (Order order : list) { System.out.println(order.getOrderno() + ":" + order.getPrice()); } }
F)查询价格最贵的一个订单
public void test7() { Session session = sessionFactory.openSession(); String hql = "from Order as o order by o.price desc"; Query query = session.createQuery(hql); query.setMaxResults(1); Order order = (Order) query.uniqueResult(); System.out.println(order.getOrderno() + ":" + order.getPrice()); }
G)动态绑定参数,方式一:通过名字绑定,名字以:开头
public void test8() { Session session = sessionFactory.openSession(); String hql = "from Customer c where c.name=:cname"; Query query = session.createQuery(hql); query.setString("cname", "小民"); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer.getName() + ":" + customer.getDes()); } }
H)动态绑定参数,方式二:通过占位符绑定,下标多0开始
public void test9() { Session session = sessionFactory.openSession(); String hql = "from Customer c where c.name=?"; Query query = session.createQuery(hql); query.setString(0, "小民"); List<Customer> list = query.list(); for (Customer customer : list) { System.out.println(customer.getName() + ":" + customer.getDes()); } }
I)在映射文件中定义命名HQL查询语句
J)查询姓"X"的,且年龄不介于20-30岁之间的客户
K)使用投影查询,查询“XX”客户姓名,年龄,描述
L)查询订单总数,订单总价格,最便宜订单,最昂贵订单,订单平均价格
M)按客户分组,查询订单总价【后面oracle重点】
SQL:
select sum(price)
from orders
group by customers_id;
HQL:
select sum(o.price) from Order o group by o.customer.id
N)使用主查询/子查询,查询姓名为“XX”客户的订单【后面oracle重点】
SQL:
select orderno,price
from orders
where customers_id = (select id from customers where name='司马懿');
HQL:
select o.orderno,o.price
from Order o
where o.customer.id = (select c.id from Customer c where c.name='司马懿');
... ...
(4)总结常用API
A)获取Query的方法:
Query query = session.createQuery()
Query query = session.getNamedQuery("findCustomerByDes");
B)Query常用的方法,以及返回值:
query.list(),返回List
query.uniqueResult(),返回Object
*二)hibernate最常用的检索策略【立刻检索 vs 延迟检索,只争对load()方法】
(1)根据id查询客户----get()有产生SQL 【默认检索策略是立即检索】
(2)根据id查询客户----hql()有产生SQL 【默认检索策略是立即检索】
(3)根据id查询客户----load()无产生SQL 【默认检索策略是延迟检索】
当使用load()方法时,查询id属性,也没有直正查询数据库
当使用load()方法时,查询非id属性,这才直正查询数据库
注意:get()/hql()只能立刻检索
load()才有延迟检索
项目中,多用load()方法
(4)当get()/hql()
A)使用<class lazy="false"/>检索策略是:立刻检索
B)使用<class lazy="true(默认值)"/>检索策略是:立刻检索
(5)当load(),测试并填表
参见<<load()类策略.JPG>>
参见<<load()集合策略.JPG>>
(6)立即检索 vs 延迟检索
参见<<PPT第30页>>
(7)什么情况下使用立即检索,什么情况下使用延迟检索
A)类:
>>当你只需查询某个对象的引用变量,或id值的时候,其它属性暂不需要:延迟检索
>>当你需查询某个对象的引用变量,或id值的时候,或其它非id属性:延迟检索立即检索
B)集合:采用延迟检索,特点是:一对多,多对多。
三)hibernate管理session一级缓存的方式
(1)传统方式下,从SessionFactory中取出的Session,每次都不一样
(2)session关闭后,不能再用该session操作数据库了,只能再次获取新的session对象
(3)hibernate委托当前线程管理session对象的好处
这样,同一条线程,只能操作惟一的一个session对象,可以节约session,提高session的利用率。
(4)如何让hibernate委托当前线程管理session对象
current_session_context_class=thread
(5)如何在代码中获取当前线程所管理的session对象
sessionFactory.getCurrentSession()
(6) 一旦事务提交,sessionFactory.getCurrentSession()会获取新的session对象
注意:一个方法,只做一件事;在这个方法中,只获取一个session对象即可。
*四)hibernate管理sessionFactory二级缓存的方式
(1)在默认情况下,session.get(),每执行一次,都要查询数据库,效率低
(2)启用sessionFactory二级缓存,使其能存对象,以及二级缓存的结构图
参见<<sessionFactory结构图.JPG>>
在默认情况下,sessionFactory二级缓存只能存储配置文件和映射文件的相关信息,
不能存对象
hibernate.cache.provider_class=org.hibernate.cache.HashtableCacheProvider
(3)将Customer类存入二级缓存
Customer.hbm.xml文件
<class name="Customer" table="CUSTOMERS">
<cache usage="read-only(只读,属性值变化)或read-write(读写,属性值常变化)"/>
</class>
(4)将Customer类和Order集合存入二级缓存
Customer.hbml.xml文件
<set name="ordetSet" table="ORDERS">
<cache usage="read-only"/>
</set>
Order.hbm.xml文件
<class name="Order" table="ORDERS">
<cache usage="read-only"/>
</class>
(5)get()/load()使用二级缓存中的普通缓存区
(6)HQL使用查询缓存区,即list()/uniqueResult()使用二级缓存中的查询缓存区
hibernate.cache.use_query_cache=true
session.createQuery("FROM Customer c WHERE c.id=1").setCacheable(true).list();
session.createQuery("FROM Customer c WHERE c.id=1").setCacheable(true).uniqueResult();
(7)session.update()也会同步更新二级缓存,必须让SessionFactory中存的对象,具有write权限
目的:用空间,去换时间,提高效率
五)hibernate使用C3P0连接池
(1)在默认情况下,hibernate使用内置连接池,无第三方连接池使用,可以能过log4j.properties运行时显示信息查看
Using Hibernate built-in connection pool (not for production use!)
(2)如何使用第三方连接池C3P0呢
hibernate.connection.provider_class=org.hibernate.connection.C3P0ConnectionProvider
hibernate.c3p0.max_size=100,这里的连接是Connection对象
hibernate.c3p0.min_size=10
当连接池中的某个连接处于空闲状态的时间超过了timeout秒指定的时间,就会从连接池中清除
hibernate.c3p0.timeout=5000
hibernate.c3p0.max_statements=30,最多创建30个Statement对象
每1000秒检查所有连接池中的空闲连接
hibernate.c3p0.idle_test_period=1000
hibernate.c3p0.acquire_increment=5,每次找数据库要5个连接对象
(3)当使用C3P0连接池后,hibernate就不再使用自定义的内置连接池上
六)hibernate使用事务
(1)事务的ACID特点
A:原子性,子操作是一个不可分割的整体,例如:转帐
C:一致性,转帐前后,总额是一样的
I:隔离性
D:持久性
(2)违背隔离性后,三个缺点
A)脏读
B)不可重复读
C)幻读
(3)设置事件隔离级别
hibernate.connection.isolation=4
(4)hibernate中隔离级别的设置,最终需要底层数据库的支持
如果hibernate框架中,没有设置隔离级别,那么hibernate会采用数据库本身默认的隔离级别
MySQL:repeatable read
Oracle:read committed
七)动手练习
【需求】
基于hibernate框架,写一个WEB版本的分页应用
以Customer-Order为例
第二天讲答案
提示:
//从第几条记录-1开始显示
query.setFirstResult(2);//写成变量
//设置【最多】显示几条记录
query.setMaxResults(2);
对象导航的时候如果是多对一查找的话需要设置立即检索
相关推荐
《深入理解Hibernate:基于MySQL数据库的应用实践》 Hibernate,作为Java领域中一款广泛使用的对象关系映射(ORM)框架,极大地简化了数据访问层的开发工作。它将Java类与数据库表之间的映射关系自动化处理,使得...
hibernate_day04笔记
- "最经典的hibernate教程,从入门到精通,CSTP-Hibernate04(第四篇,共四篇).ppt":作为系列的最后一部分,通常会涉及更复杂的使用场景、最佳实践,甚至可能包括一些进阶话题如Hibernate与其他技术的整合。 - "经典...
在本视频教程“Spring MVC + Spring + Hibernate 全注解整合开发视频教程 04”中,我们将深入探讨Java企业级开发中的三大核心技术——Spring、Spring MVC和Hibernate的集成与应用,尤其是通过注解实现的简化配置。...
- "04-2018-7-8-Hibernate-functiongtest.pptx"可能是关于函数测试和Hibernate的结合,讲解如何使用Hibernate进行功能测试。 - "2018-7-26-Hibernate-加载策略.pptx"可能涉及了Hibernate的对象状态管理,包括延迟...
【标题】"传智博客Hibernate框架2016版笔记资料day03~04" 涵盖了Hibernate框架的深入学习内容,这是一份针对2016年版本的教程,旨在帮助开发者理解并掌握这个强大的Java持久化框架。在Hibernate中,数据库操作被封装...
【传智播客-hibernate框架开发视频第day01-day04资料】 在这个课程中,传智播客为我们深入讲解了Hibernate框架的开发知识,涵盖了从基础到进阶的多个方面。Hibernate是一款强大的对象关系映射(ORM)框架,它为Java...
本资源“Hibernate基础学习源码”提供了五个不同阶段的学习示例,分别命名为Hibernate_01至Hibernate_04以及Hibernate_M2M,涵盖了Hibernate的基本概念、配置、实体映射、CRUD操作以及多对多关系的处理。 1. **...
在Hibernate Day 04的学习中,我们深入探讨了如何利用Hibernate进行查询操作以及它的抓取策略,这些是理解并有效使用Hibernate的关键部分。 首先,让我们来详细了解一下Hibernate的查询方式。Hibernate提供了一个...
04 04Hibernate_Composite : 复合主键的使用,在开发中很少用到,一般良好的设计都会为一个表添加一个自动增长的主键标识列。其中重点配置方法和Hibernate中普遍采用的方法链编程的使用。还需注意可以将组合主键构建...
hibernate框架开发2016版视频 day01 hibernate框架开发2016版视频 day02 hibernate框架开发2016版视频 day03 hibernate框架开发2016版视频 day04
- "hibernate04"和"hibernate05"的多个版本可能分别讲解了查询操作,包括HQL(Hibernate Query Language)和Criteria API,以及如何执行CRUD(创建、读取、更新和删除)操作。 - "bm_spring"和"bm"可能涉及到Spring...
标题中的“day36 04-Hibernate检索方式:多表连接查询”表明这是一个关于Hibernate框架的教程,重点讲解如何在Hibernate中进行多表连接查询。在这个主题中,我们将深入探讨Hibernate的ORM(对象关系映射)机制以及...
Hibernate入门.part04
在“hibernatetest04”这个项目中,我们可能会看到以下几个关键部分: 1. **配置文件(hibernate.cfg.xml)**:这是Hibernate的主配置文件,包含数据库连接信息,如URL、用户名、密码、驱动类等。同时,它也可能...
今天,我们将聚焦于Hibernate的学习,通过一系列的学习资料,包括“day01”、“day02”、“day03”和“day04”,逐步探索Hibernate的奥秘。 一、Hibernate基础 Hibernate是一个开放源代码的对象关系映射框架,它对...
在这个"Struts2+Hibernate+Spring整合开发深入剖析与范例应用04"的主题中,我们将探讨这三大框架的集成过程、关键概念以及实际应用。 首先,Struts2是基于MVC(Model-View-Controller)设计模式的Web框架,它负责...
在`hibernate_day04`这个压缩包中,应该包含了上述各种元素的示例代码。通过分析这些代码,你可以更深入地理解如何在实际项目中使用hibernate进行数据操作。同时,还可能涉及事务管理、缓存机制、一对多、多对一、多...
day36_hibernate04 day37_spring01 day38_spring02 day39_spring03 day40_巩固知识之SSH编码实战演练 day41_巩固知识之SSH编码实战演练 day42_巩固知识之SSH编码实战演练 day43_巩固知识之SSH编码实战演练 ...