Hibernate学习笔记9
学习课程:
简单属性查询 |
SimplePropertyQueryTest |
实体对象查询 |
SimleObjectQueryTest |
条件查询 |
ConditionQueryTest |
原生SQL查询 |
ConditionQueryTest |
外置命名查询 |
NameQueryTest |
查询过滤器 |
FilterQueryTest |
分页查询 |
PageQueryTest |
对象导航查询 |
ObjectNavigationQueryTest |
连接查询 |
JoinQueryTest |
统计查询 |
StatisticsQueryTest |
DML查询 |
DMLQueryTest |
HQL简介
数据查询与检索是Hibernate中的一个亮点,相对其他ORM实现而言,Hibernate 提供了灵活多样的查询机制。 HQL(Hibernate Query Language):它是完全面向对象的查询语句,查询功能非常 强大,具备多态,关联等操作, HQL用面向对象的方式生成SQL *以类和属性来代替表和数据列 *支持多态 *支持各种关联 *减少了SQL的冗余 HQL支持所有的关系数据库操作 *连接(joins,包括Inner/Oouter/full joins) ,笛卡尔积(cartesion products) *投影(projection) *聚合(Aggregation,max,avg)和分组(group) *排序(Ordering) *子查询(Subqueries) *SQL函数(SQL function calls) HQL查询对象,不会直接查表,关键字不区分大小写,但是属性和类名区分大小写 中立的一套语言 准备工作: 在Student中加入createTime,对时间进行查询 |
1.简单属性查询
testQuery1
单一属性查询,返回结果皆属性列表,元素类型和实体类型的属性类型一致 |
|
-
-
List<String> list = session.createQuery( "select name from Student" ).list(); for ( String s : list ){System.out.println( s );}
|
testQuery2
多个属性查询——返回类型对象数组(Object[]) |
|
-
-
List list = session.createQuery( "select name , id from Student" ).list();for ( Iterator iter = list.iterator();iter.hasNext(); ){Object[] obj = (Object[]) iter.next();System.out.println( obj[0] + " : " + obj[1] );}
|
testQuery3
多个属性查询——返回实体类型 采用HQL动态实例化,此时list中为Student对象集合 为Student提供构造函数 首先提供一个空的构造函数 在提供一个带参数的构造函数 提供的参数为查询的字段 |
|
-
-
List list = session.createQuery( "select new Student(id , name )from Student" ).list();for ( Iterator iter = list.iterator();iter.hasNext(); ){Student student = (Student)iter.next(); System.out.println( student.getId() + " , " + student.getName() );}
|
testQuery4
|
-
-
List list = session.createQuery( "select s.id , s.name from Student s" ).list();
|
testQuery5
|
-
-
List list = session.createQuery( "select student.id , student.name from Student as student" ).list();
|
2.实体对象查询
testQuery1
查询实体,返回实体类型Set<Student> 省略select 与以前进行的查询一样 from Student |
|
-
-
List list = session.createQuery( "from Student" ).list();for ( Iterator iter = list.iterator();iter.hasNext();){Student student = (Student)iter.next(); System.out.println( student.getId() + " , " + student.getName() );}
|
testQuery2
|
-
-
List list = session.createQuery( "from Student s" ).list();
|
testQuery3
可以使用as 命名别名from Student as s |
|
-
-
List list = session.createQuery( "from Student as s" ).list();
|
testQuery4
加入select 关键字,查询实体对象必须采用别名 select s from Student s |
|
-
-
List list = session.createQuery( "select s from Student s" ).list();
|
testQuery5
不支持select * from Student 进行查询出错 采用count(*) |
|
-
-
List list = session.createQuery( "select * from Student" ).list();
|
testQuery6
采用iterate进行查询需要修改连接数据库URL,添加 SelectMethod=cursor,否则报错 |
|
-
-
Iterator iter = session.createQuery("from Student").iterate();while(iter.hasNext()) {Student student = (Student)iter.next(); System.out.println(student.getName());}
出现N+1问题, 1:先发出查询id列表的sql, N:再依次发出根据id查询Student对象的Sql 资源浪费非常的严重 在默认情况下,使用query.iterate查询,有可能出现N+1问题 第一条查询语句 查询表中所有的id,然后通过id一条一条进行查询,迭代接口使用缓存 采用iterate查询 |
|
testQuery7
先调用list, 再调用Iterator 不会出现N+1问题,因为list操作已经将已经将对象放到一级缓存中,在此使用iterate 操作的时候,首先发出一条查询Id列表的语句,根据id在缓存中取数据,只有当缓存中 找不到的相应数据的时候,才发出sql到数据中进行查询 |
|
-
-
List students = session.createQuery("from Student").list();for (Iterator iter=students.iterator(); iter.hasNext();) {Student student = (Student)iter.next();System.out.println(student.getName());}System.out.println("---------------------");Iterator iter = session.createQuery("from Student").iterate();while(iter.hasNext()) {Student student = (Student)iter.next();System.out.println(student.getName());}
|
testQuery8
执行两次list,将会发出两次查询语句 虽然在一级缓存中已经有了对象数据,但list在默认情况下不只用缓存,它只向缓存中放 入数据,除非配置查询缓存 |
|
-
-
List students = session.createQuery("from Student").list();for(Iterator iter=students.iterator(); iter.hasNext();) {Student student = (Student)iter.next();System.out.println(student.getName());}System.out.println("---------------------");students=session.createQuery("from Student").list();for (Iterator iter=students.iterator(); iter.hasNext();) {Student student = (Student)iter.next();System.out.println(student.getName());}
|
3.条件查询
testQuery1
|
-
-
List list = session.createQuery( "select s.id , s.name from Student as s where s.name like '%1%'").list();
|
testQuery2
2.占位符的方式进行查询 可以使用?方式传递参数,参数的索引从0开始,传递的值不用单引号引起来 |
|
-
-
Query query = session.createQuery("select s.id , s.name from Student as s where s.name like ?");query.setParameter(0, "%1%");List list = query.list();
|
testQuery3
|
-
-
List list = session.createQuery("select s.id , s.name from Student as s where s.name like ?").setParameter(0, "%1%").list();
|
testQuery4
3.使用 (:+参数名称)的方式传递参数值,进行查询 |
|
-
-
List list = session.createQuery("select s.id , s.name from Student as s where s.name like :myname").setParameter("myname", "%1%").list();
|
testQuery5
|
-
-
List list = session.createQuery("select s.id , s.name from Student as s "+ "where s.name like :myname"+ " and s.id = :myid").setParameter("myname", "%1%").setParameter("myid", 12).list();
|
testQuery6
5.支持in,需要使用setParameterList进行参数传递 |
|
-
-
List list = session.createQuery("select s.id , s.name from Student as s where s.name in(:myname)").setParameterList("myname",new Object[] { "学生1", "学生2", "学生3" }).list();
|
testQuery7
6.查询某个月的学生,可以使用与数据库相关的系统函数 |
|
不会使用,教程中使用的是MySQL数据库,本机的是SQL Server 2000,还有我的数据库知识欠缺 |
testQuery8
7.查询日期段的学生 2008-01-2 —— 2008-05-3 |
|
-
-
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");List list = session.createQuery("select s.id , s.name from Student as s where s.createTime between ? and ? ").setParameter(0, sdf.parseObject("2008-01-02 00:00:00") )
|
testQuery9
|
-
-
List list = session.createSQLQuery( "select * from t_student" ).list();
|
4.外置命名查询
将HQL放到外置文件中,降低耦合度 |
-
-
<query name="search"><![CDATA[ SELECT s FROM Student s where s.id<?]]></query>List list = session.getNamedQuery( "search" ).setParameter( 0 , 10 ).list();
|
5.查询过滤器
步骤:
在映射文件中定义过滤器的参数 在类映射文件中使用定义的参数 在程序中启用过滤器 |
作用域:
当定义完查询的时候,session没有关闭,执行的所有HQl,都会加上这个条件 |
配置文件,加入标签
-
-
<filter-def name="filterTest"><filter-param name="myid" type="integer"/></filter-def>
|
在class标签内加入
-
-
<filter name="filterTest" condition="name_id < :myid" />
|
调用方法
-
-
session.enableFilter( "filterTest" ).setParameter( "myid", 20 );
|
|
6.分页查询【重要】
-
-
List list = session.createQuery( "from Student" ) .setFirstResult( 3 )
|
7.对象导航查询,在HQL中采用 "."进行导航,进行查询【重要】
-
-
//只检索一个字段,返回类型为 Object, List list = session.createQuery( "select s.name from Student s where s.classes.name like '%1%'" ).list();
|
8.连接查询【重要】
连接分为: 内连 外连(左连接,右连接) |
testQuery1
|
-
-
//只检索一个字段,返回类型为 Object, List list = session.createQuery( "select c.name , s.name from Student s join s.classes c" ).list();for ( Iterator iter = list.iterator(); iter.hasNext();){Object[] obj = (Object[]) iter.next();//类型转换必须一致,否则会报出[Ljava.lang.Object错误 System.out.println( obj[0] + " : " + obj[1] );}
|
testQuery2
|
-
-
List list = session.createQuery( "select c.name , s.name from Classes c left join c.students s " ).list();
|
testQuery3
|
-
-
List list = session.createQuery( "select c.name , s.name from Classes c right join c.students s" ).list();
|
9.统计查询【重要】
testQuery1
|
-
-
//只检索一个字段,返回类型为 Object, List list = session.createQuery("select count(*) from Student") .list();Long count = (Long) list.get(0);System.out.println("统计学生人数:" + count);
|
testQuery2
|
-
-
Long count = (Long) session.createQuery("select count(*) from Student").uniqueResult();System.out.println("统计学生人数:" + count);
|
10.DML风格的操作
//批量更新 //建议少用因为和缓存不同步 |
-
-
session.createQuery("update Student s set s.name=? where s.id < ?") .setParameter(0, "张林") .setParameter(1, 10) .executeUpdate();List list = session.createQuery( "select s.id , s.name from Student s where s.id < 10").list();
|
文章来源: blog.csdn.net,作者:fengda2870,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/fengda2870/article/details/3301283
【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
评论(0)