1、day35hibernate查询连接池Hibernate第三天:1. 对象状态2. session缓存3. lazy懒加载4. 映射 一对一对映射 组件/继承映射目标: 一、hibernate查询 二、hibernate对连接池的支持 三、二级缓存 四、Hibernate与Struts小案例(项目中session的管理方式)一、hibernate查询1. 查询概述1) Get/load主键查询2) 对象导航查询3) HQL查询, Hibernate Query language hibernate 提供的面向对象的查询语言。4) Criteria 查询, 完全面向对象的查询(Query By
2、Criteria ,QBC)5) SQLQuery, 本地SQL查询缺点:不能跨数据库平台: 如果该了数据库,sql语句有肯能要改使用场景: 对于复杂sql,hql实现不了的情况,可以使用本地sql查询。HQL查询public class App private static SessionFactory sf; static sf = new Configuration() .configure() .addClass(Dept.class) .addClass(Employee.class) / 测试时候使用 .buildSessionFactory(); /* * 1) Get/load
3、主键查询 2) 对象导航查询 3) HQL查询, Hibernate Query language hibernate 提供的面向对象的查询语言。 4) Criteria 查询, 完全面向对象的查询(Query By Criteria ,QBC) 5) SQLQuery, 本地SQL查询 */ Test public void all() Session session = sf.openSession(); session.beginTransaction(); /1) 主键查询/ Dept dept = (Dept) session.get(Dept.class, 12);/ Dept d
4、ept = (Dept) session.load(Dept.class, 12); /2) 对象导航查询/ Dept dept = (Dept) session.get(Dept.class, 12);/ System.out.println(dept.getDeptName();/ System.out.println(dept.getEmps(); / 3) HQL查询 / 注意:使用hql查询的时候 auto-import=true 要设置true, / 如果是false,写hql的时候,要指定类的全名/ Query q = session.createQuery(from Dept)
5、;/ System.out.println(q.list(); / a. 查询全部列/ Query q = session.createQuery(from Dept); /OK/ Query q = session.createQuery(select * from Dept); /NOK, 错误,不支持*/ Query q = session.createQuery(select d from Dept d); / OK/ System.out.println(q.list(); / b. 查询指定的列 【返回对象数据Object 】/ Query q = session.createQu
6、ery(select d.deptId,d.deptName from Dept d); / System.out.println(q.list(); / c. 查询指定的列, 自动封装为对象 【必须要提供带参数构造器】/ Query q = session.createQuery(select new Dept(d.deptId,d.deptName) from Dept d); / System.out.println(q.list(); / d. 条件查询: 一个条件/多个条件and or/between and/模糊查询 / 条件查询: 占位符/ Query q = session.c
7、reateQuery(from Dept d where deptName=?);/ q.setString(0, 财务部);/ q.setParameter(0, 财务部);/ System.out.println(q.list(); / 条件查询: 命名参数/ Query q = session.createQuery(from Dept d where deptId=:myId or deptName=:name);/ q.setParameter(myId, 12);/ q.setParameter(name, 财务部);/ System.out.println(q.list(); /
8、 范围/ Query q = session.createQuery(from Dept d where deptId between ? and ?);/ q.setParameter(0, 1);/ q.setParameter(1, 20);/ System.out.println(q.list(); / 模糊/ Query q = session.createQuery(from Dept d where deptName like ?);/ q.setString(0, %部%);/ System.out.println(q.list(); / e. 聚合函数统计/ Query q
9、= session.createQuery(select count(*) from Dept);/ Long num = (Long) q.uniqueResult();/ System.out.println(num); / f. 分组查询 /- 统计t_employee表中,每个部门的人数 /数据库写法:SELECT dept_id,COUNT(*) FROM t_employee GROUP BY dept_id; / HQL写法/ Query q = session.createQuery(select e.dept, count(*) from Employee e group b
10、y e.dept);/ System.out.println(q.list(); session.getTransaction().commit(); session.close(); / g. 连接查询 Test public void join() Session session = sf.openSession(); session.beginTransaction(); /1) 内连接 【映射已经配置好了关系,关联的时候,直接写对象的属性即可】/ Query q = session.createQuery(from Dept d inner join d.emps); /2) 左外连接
11、/ Query q = session.createQuery(from Dept d left join d.emps); /3) 右外连接 Query q = session.createQuery(from Employee e right join e.dept); q.list(); session.getTransaction().commit(); session.close(); / g. 连接查询 - 迫切连接 Test public void fetch() Session session = sf.openSession(); session.beginTransacti
12、on(); /1) 迫切内连接 【使用fetch, 会把右表的数据,填充到左表对象中!】/ Query q = session.createQuery(from Dept d inner join fetch d.emps);/ q.list(); /2) 迫切左外连接 Query q = session.createQuery(from Dept d left join fetch d.emps); q.list(); session.getTransaction().commit(); session.close(); / HQL查询优化 Test public void hql_othe
13、r() Session session = sf.openSession(); session.beginTransaction(); / HQL写死/ Query q = session.createQuery(from Dept d where deptId 10 ); / HQL 放到映射文件中 Query q = session.getNamedQuery(getAllDept); q.setParameter(0, 10); System.out.println(q.list(); session.getTransaction().commit(); session.close();
14、 Criteria 查询/4) Criteria 查询, Test public void criteria() Session session = sf.openSession(); session.beginTransaction(); Criteria criteria = session.createCriteria(Employee.class); / 构建条件 criteria.add(Restrictions.eq(empId, 12);/ criteria.add(Restrictions.idEq(12); / 主键查询 System.out.println(criteria
15、.list(); session.getTransaction().commit(); session.close(); SQLQuery, 本地SQL查询/ 5) SQLQuery, 本地SQL查询 / 不能跨数据库平台: 如果该了数据库,sql语句有肯能要改。 Test public void sql() Session session = sf.openSession(); session.beginTransaction(); SQLQuery q = session.createSQLQuery(SELECT * FROM t_Dept limit 5;) .addEntity(De
16、pt.class); / 也可以自动封装 System.out.println(q.list(); session.getTransaction().commit(); session.close(); 2. 分页查询分页SQL: 先查询总记录数,再分页查询。/ 分页查询 Test public void all() Session session = sf.openSession(); session.beginTransaction(); Query q = session.createQuery(from Employee); / 从记录数 ScrollableResults scrol
17、l = q.scroll(); / 得到滚动的结果集 scroll.last(); / 滚动到最后一行 int totalCount = scroll.getRowNumber() + 1;/ 得到滚到的记录数,即总记录数 / 设置分页参数 q.setFirstResult(0); q.setMaxResults(3); / 查询 System.out.println(q.list(); System.out.println(总记录数: + totalCount); session.getTransaction().commit(); session.close(); 二、hibernate对
18、连接池的支持连接池, 作用: 管理连接;提升连接的利用效率! 常用的连接池: C3P0连接池Hibernate 自带的也有一个连接池,且对C3P0连接池也有支持!Hbm 自带连接池: 只维护一个连接,比较简陋。 可以查看hibernate.properties文件查看连接池详细配置:# Hibernate Connection Pool # #hibernate.connection.pool_size 1 【Hbm 自带连接池: 只有一个连接】# C3P0 Connection Pool# 【Hbm对C3P0连接池支持】#hibernate.c3p0.max_size 2 最大连接数#hib
19、ernate.c3p0.min_size 2 最小连接数#hibernate.c3p0.timeout 5000 超时时间#hibernate.c3p0.max_statements 100 最大执行的命令的个数#hibernate.c3p0.idle_test_period 3000 空闲测试时间#hibernate.c3p0.acquire_increment 2 连接不够用的时候, 每次增加的连接数#hibernate.c3p0.validate false【Hbm对C3P0连接池支持, 核心类】 告诉hib使用的是哪一个连接池技术。#hibernate.connection.provi
20、der_class org.hibernate.connection.C3P0ConnectionProviderHibernate.cfg.xml 中增加连接池相关配置: org.hibernate.connection.C3P0ConnectionProvider 2 4 5000 10 30000 2三、二级缓存Hibernate提供的缓存 有一级缓存、二级缓存。 目的是为了减少对数据库的访问次数,提升程序执行效率!一级缓存: 基于Session的缓存,缓存内容只在当前session有效,session关闭,缓存内容失效! 特点: 作用范围较小! 缓存的事件短。 缓存效果不明显。概述二级
21、缓存: Hibernate提供了基于应用程序级别的缓存, 可以跨多个session,即不同的session都可以访问缓存数据。 这个换存也叫二级缓存。 Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可; 不想用,直接移除,不影响代码。 如果用户觉得hibernate提供的框架框架不好用,自己可以换其他的缓存框架或自己实现缓存框架都可以。 使用二级缓存查看hibernate.properties配置文件,二级缓存如何配置?# Second-level Cache #hibernate.cache.u
22、se_second_level_cache false【二级缓存默认不开启,需要手动开启】#hibernate.cache.use_query_cache true 【开启查询缓存】# choose a cache implementation 【二级缓存框架的实现】#hibernate.cache.provider_class org.hibernate.cache.EhCacheProvider#hibernate.cache.provider_class org.hibernate.cache.EmptyCacheProviderhibernate.cache.provider_clas
23、s org.hibernate.cache.HashtableCacheProvider 默认实现#hibernate.cache.provider_class org.hibernate.cache.TreeCacheProvider#hibernate.cache.provider_class org.hibernate.cache.OSCacheProvider#hibernate.cache.provider_class org.hibernate.cache.SwarmCacheProvider二级缓存,使用步骤1) 开启二级缓存2)指定缓存框架3)指定那些类加入二级缓存4)测试 测
24、试二级缓存!缓存策略 放入二级缓存的对象,只读; 非严格的读写 读写; 放入二级缓存的对象可以读、写; (基于事务的策略)集合缓存 查询缓存list() 默认情况只会放入缓存,不会从一级缓存中取! 使用查询缓存,可以让list()查询从二级缓存中取!完整案例:Hibernate.cfg.xml true org.hibernate.cache.HashtableCacheProvider true App 测试类public class App private static SessionFactory sf; static sf = new Configuration() .configure() .addClass(Dept.class) .addClass(Employee.class) / 测试时候使用 .buildSessionFactory(); / 1. 测试二级缓存的使用 / 没有/有用 二级缓存
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1