day35hibernate查询连接池.docx
《day35hibernate查询连接池.docx》由会员分享,可在线阅读,更多相关《day35hibernate查询连接池.docx(17页珍藏版)》请在冰豆网上搜索。
![day35hibernate查询连接池.docx](https://file1.bdocx.com/fileroot1/2023-4/2/020e71b1-8aae-44ce-b4a1-7f1243952f7d/020e71b1-8aae-44ce-b4a1-7f1243952f7d1.gif)
day35hibernate查询连接池
Hibernate第三天:
1.对象状态
2.session缓存
3.lazy懒加载
4.映射
一对一对映射
组件/继承映射
目标:
一、hibernate查询
二、hibernate对连接池的支持
三、二级缓存
四、Hibernate与Struts小案例(项目中session的管理方式)
一、hibernate查询
1.查询概述
1)Get/load主键查询
2)对象导航查询
3)HQL查询,HibernateQuerylanguagehibernate提供的面向对象的查询语言。
4)Criteria查询,完全面向对象的查询(QueryByCriteria,QBC)
5)SQLQuery,本地SQL查询
缺点:
不能跨数据库平台:
如果该了数据库,sql语句有肯能要改
使用场景:
对于复杂sql,hql实现不了的情况,可以使用本地sql查询。
HQL查询
publicclassApp{
privatestaticSessionFactorysf;
static{
sf=newConfiguration()
.configure()
.addClass(Dept.class)
.addClass(Employee.class)//测试时候使用
.buildSessionFactory();
}
/*
*1)Get/load主键查询
2)对象导航查询
3)HQL查询,HibernateQuerylanguagehibernate提供的面向对象的查询语言。
4)Criteria查询,完全面向对象的查询(QueryByCriteria,QBC)
5)SQLQuery,本地SQL查询
*/
@Test
publicvoidall(){
Sessionsession=sf.openSession();
session.beginTransaction();
//1)主键查询
//Deptdept=(Dept)session.get(Dept.class,12);
//Deptdept=(Dept)session.load(Dept.class,12);
//2)对象导航查询
//Deptdept=(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的时候,要指定类的全名
//Queryq=session.createQuery("fromDept");
//System.out.println(q.list());
//a.查询全部列
//Queryq=session.createQuery("fromDept");//OK
//Queryq=session.createQuery("select*fromDept");//NOK,错误,不支持*
//Queryq=session.createQuery("selectdfromDeptd");//OK
//System.out.println(q.list());
//b.查询指定的列【返回对象数据Object[]】
//Queryq=session.createQuery("selectd.deptId,d.deptNamefromDeptd");
//System.out.println(q.list());
//c.查询指定的列,自动封装为对象【必须要提供带参数构造器】
//Queryq=session.createQuery("selectnewDept(d.deptId,d.deptName)fromDeptd");
//System.out.println(q.list());
//d.条件查询:
一个条件/多个条件andor/betweenand/模糊查询
//条件查询:
占位符
//Queryq=session.createQuery("fromDeptdwheredeptName=?
");
//q.setString(0,"财务部");
//q.setParameter(0,"财务部");
//System.out.println(q.list());
//条件查询:
命名参数
//Queryq=session.createQuery("fromDeptdwheredeptId=:
myIdordeptName=:
name");
//q.setParameter("myId",12);
//q.setParameter("name","财务部");
//System.out.println(q.list());
//范围
//Queryq=session.createQuery("fromDeptdwheredeptIdbetween?
and?
");
//q.setParameter(0,1);
//q.setParameter(1,20);
//System.out.println(q.list());
//模糊
//Queryq=session.createQuery("fromDeptdwheredeptNamelike?
");
//q.setString(0,"%部%");
//System.out.println(q.list());
//e.聚合函数统计
//Queryq=session.createQuery("selectcount(*)fromDept");
//Longnum=(Long)q.uniqueResult();
//System.out.println(num);
//f.分组查询
//--统计t_employee表中,每个部门的人数
//数据库写法:
SELECTdept_id,COUNT(*)FROMt_employeeGROUPBYdept_id;
//HQL写法
//Queryq=session.createQuery("selecte.dept,count(*)fromEmployeeegroupbye.dept");
//System.out.println(q.list());
session.getTransaction().commit();
session.close();
}
//g.连接查询
@Test
publicvoidjoin(){
Sessionsession=sf.openSession();
session.beginTransaction();
//1)内连接【映射已经配置好了关系,关联的时候,直接写对象的属性即可】
//Queryq=session.createQuery("fromDeptdinnerjoind.emps");
//2)左外连接
//Queryq=session.createQuery("fromDeptdleftjoind.emps");
//3)右外连接
Queryq=session.createQuery("fromEmployeeerightjoine.dept");
q.list();
session.getTransaction().commit();
session.close();
}
//g.连接查询-迫切连接
@Test
publicvoidfetch(){
Sessionsession=sf.openSession();
session.beginTransaction();
//1)迫切内连接【使用fetch,会把右表的数据,填充到左表对象中!
】
//Queryq=session.createQuery("fromDeptdinnerjoinfetchd.emps");
//q.list();
//2)迫切左外连接
Queryq=session.createQuery("fromDeptdleftjoinfetchd.emps");
q.list();
session.getTransaction().commit();
session.close();
}
//HQL查询优化
@Test
publicvoidhql_other(){
Sessionsession=sf.openSession();
session.beginTransaction();
//HQL写死
//Queryq=session.createQuery("fromDeptdwheredeptId<10");
//HQL放到映射文件中
Queryq=session.getNamedQuery("getAllDept");
q.setParameter(0,10);
System.out.println(q.list());
session.getTransaction().commit();
session.close();
}
}
Criteria查询
//4)Criteria查询,
@Test
publicvoidcriteria(){
Sessionsession=sf.openSession();
session.beginTransaction();
Criteriacriteria=session.createCriteria(Employee.class);
//构建条件
criteria.add(Restrictions.eq("empId",12));
//criteria.add(Restrictions.idEq(12));//主键查询
System.out.println(criteria.list());
session.getTransaction().commit();
session.close();
}
SQLQuery,本地SQL查询
//5)SQLQuery,本地SQL查询
//不能跨数据库平台:
如果该了数据库,sql语句有肯能要改。
@Test
publicvoidsql(){
Sessionsession=sf.openSession();
session.beginTransaction();
SQLQueryq=session.createSQLQuery("SELECT*FROMt_Deptlimit5;")
.addEntity(Dept.class);//也可以自动封装
System.out.println(q.list());
session.getTransaction().commit();
session.close();
}
2.分页查询
分页SQL:
先查询总记录数,再分页查询。
//分页查询
@Test
publicvoidall(){
Sessionsession=sf.openSession();
session.beginTransaction();
Queryq=session.createQuery("fromEmployee");
//从记录数
ScrollableResultsscroll=q.scroll();//得到滚动的结果集
scroll.last();//滚动到最后一行
inttotalCount=scroll.getRowNumber()+1;//得到滚到的记录数,即总记录数
//设置分页参数
q.setFirstResult(0);
q.setMaxResults(3);
//查询
System.out.println(q.list());
System.out.println("总记录数:
"+totalCount);
session.getTransaction().commit();
session.close();
}
二、hibernate对连接池的支持
连接池,
作用:
管理连接;提升连接的利用效率!
常用的连接池:
C3P0连接池
Hibernate自带的也有一个连接池,且对C3P0连接池也有支持!
Hbm自带连接池:
只维护一个连接,比较简陋。
可以查看hibernate.properties文件查看连接池详细配置:
#################################
###HibernateConnectionPool###
#################################
hibernate.connection.pool_size1【Hbm自带连接池:
只有一个连接】
###########################
###C3P0ConnectionPool###【Hbm对C3P0连接池支持】
###########################
#hibernate.c3p0.max_size2最大连接数
#hibernate.c3p0.min_size2最小连接数
#hibernate.c3p0.timeout5000超时时间
#hibernate.c3p0.max_statements100最大执行的命令的个数
#hibernate.c3p0.idle_test_period3000空闲测试时间
#hibernate.c3p0.acquire_increment2连接不够用的时候,每次增加的连接数
#hibernate.c3p0.validatefalse
【Hbm对C3P0连接池支持,核心类】
告诉hib使用的是哪一个连接池技术。
#hibernate.connection.provider_classorg.hibernate.connection.C3P0ConnectionProvider
Hibernate.cfg.xml中增加连接池相关配置:
--【连接池配置】-->
--配置连接驱动管理类-->
org.hibernate.connection.C3P0ConnectionProvider
--配置连接池参数信息-->
2
4
5000
10
30000
2
三、二级缓存
Hibernate提供的缓存
有一级缓存、二级缓存。
目的是为了减少对数据库的访问次数,提升程序执行效率!
一级缓存:
基于Session的缓存,缓存内容只在当前session有效,session关闭,缓存内容失效!
特点:
作用范围较小!
缓存的事件短。
缓存效果不明显。
概述
二级缓存:
Hibernate提供了基于应用程序级别的缓存,可以跨多个session,即不同的session都可以访问缓存数据。
这个换存也叫二级缓存。
Hibernate提供的二级缓存有默认的实现,且是一种可插配的缓存框架!
如果用户想用二级缓存,只需要在hibernate.cfg.xml中配置即可;不想用,直接移除,不影响代码。
如果用户觉得hibernate提供的框架框架不好用,自己可以换其他的缓存框架或自己实现缓存框架都可以。
使用二级缓存
查看hibernate.properties配置文件,二级缓存如何配置?
##########################
###Second-levelCache###
##########################
#hibernate.cache.use_second_level_cachefalse【二级缓存默认不开启,需要手动开启】
#hibernate.cache.use_query_cachetrue【开启查询缓存】
##chooseacacheimplementation【二级缓存框架的实现】
#hibernate.cache.provider_classorg.hibernate.cache.EhCacheProvider
#hibernate.cache.provider_classorg.hibernate.cache.EmptyCacheProvider
hibernate.cache.provider_classorg.hibernate.cache.HashtableCacheProvider默认实现
#hibernate.cache.provider_classorg.hibernate.cache.TreeCacheProvider
#hibernate.cache.provider_classorg.hibernate.cache.OSCacheProvider
#hibernate.cache.provider_classorg.hibernate.cache.SwarmCacheProvider
二级缓存,使用步骤
1)开启二级缓存
2)指定缓存框架
3)指定那些类加入二级缓存
4)测试
测试二级缓存!
缓存策略
放入二级缓存的对象,只读;
非严格的读写
读写;放入二级缓存的对象可以读、写;
(基于事务的策略)
集合缓存
--集合缓存[集合缓存的元素对象,也加加入二级缓存]-->
usage="read-write"collection="cn.itcast.b_second_cache.Dept.emps"/>
查询缓存
list()默认情况只会放入缓存,不会从一级缓存中取!
使用查询缓存,可以让list()查询从二级缓存中取!
完整案例:
Hibernate.cfg.xml
--******************【二级缓存配置】******************-->
--a.开启二级缓存-->
true
--b.指定使用哪一个缓存框架(默认提供的)-->
org.hibernate.cache.HashtableCacheProvider
--开启查询缓存-->
true
--c.指定哪一些类,需要加入二级缓存-->
--集合缓存[集合缓存的元素对象,也加加入二级缓存]-->
App测试类
publicclassApp{
privatestaticSessionFactorysf;
static{
sf=newConfiguration()
.configure()
.addClass(Dept.class)
.addClass(Employee.class)//测试时候使用
.buildSessionFactory();
}
//1.测试二级缓存的使用
//没有/有用二级缓存