Hibernate学习笔记9

举报
wh_bn 发表于 2021/12/16 01:05:15 2021/12/16
【摘要】   Hibernate学习笔记9 学习课程: 简单属性查询 SimplePropertyQueryTest 实体对象查询 SimleObjectQueryTest 条件查询 ConditionQueryTe...

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

单一属性查询,返回结果皆属性列表,元素类型和实体类型的属性类型一致

  1. List<String> list = session.createQuery"select name from Student" ).list(); for ( String s : list ){System.out.println( s );}

 

testQuery2

多个属性查询——返回类型对象数组(Object[])

 

  1. 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提供构造函数

首先提供一个空的构造函数

在提供一个带参数的构造函数

提供的参数为查询的字段

 

  1. 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

使用别名进行查询

  1. List list = session.createQuery( "select s.id , s.name from Student s" ).list();

 

testQuery5

使用as命名别名进行查询

  1. List list = session.createQuery( "select student.id , student.name from Student as student" ).list();

 

 

2.实体对象查询

testQuery1

查询实体,返回实体类型Set<Student>   省略select 与以前进行的查询一样 from Student

 

  1. 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

使用别名进行查询from Student s

 

  1. List list = session.createQuery( "from Student s" ).list();

 

testQuery3

可以使用as 命名别名from Student as s

  1. List list = session.createQuery( "from Student as s" ).list();

 

testQuery4

加入select 关键字,查询实体对象必须采用别名 select s 

from Student s

 

  1. List list = session.createQuery( "select s from Student s" ).list();

 

testQuery5

不支持select * from Student 进行查询出错 采用count(*)

 

  1. List list = session.createQuery( "select * from Student" ).list();

 

testQuery6

采用iterate进行查询需要修改连接数据库URL,添加

SelectMethod=cursor,否则报错

 

  1. 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到数据中进行查询

  1. 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在默认情况下不只用缓存,它只向缓存中放

入数据,除非配置查询缓存

  1. 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

1.支持where语句,支持模糊查询

 

  1. List list = session.createQuery( "select s.id , s.name from Student as s where s.name like '%1%'").list();

 

testQuery2

2.占位符的方式进行查询

可以使用?方式传递参数,参数的索引从0开始,传递的值不用单引号引起来

 

  1. 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

Hibernate支持一种编程风格:方法链编程

 

  1. List list = session.createQuery("select s.id , s.name from Student as s where s.name like ?").setParameter(0"%1%").list();

 

testQuery4

3.使用 (:+参数名称)的方式传递参数值,进行查询

 

  1. List list = session.createQuery("select s.id , s.name from Student as s where s.name like :myname").setParameter("myname""%1%").list();

 

testQuery5

4.多参数查询

 

  1. 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进行参数传递

  1. 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

 

  1. 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") )//必须为Date类型 .setParameter(1, sdf.parseObject("2008-05-03 23:59:59") )//所以对字符串进行需要格式化 .list();

 

testQuery9

使用原生查询,即使用SQL语句进行查询

  1. List list = session.createSQLQuery( "select * from t_student" ).list();

 

4.外置命名查询

将HQL放到外置文件中,降低耦合度

 

  1. <!--query标签与class平行,可以放到任何的映射文件中都可以,但是注意 name属性值不要重复--><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,都会加上这个条件

配置文件,加入标签

 

  1. <filter-def name="filterTest"><filter-param name="myid" type="integer"/></filter-def>

 

在class标签内加入

  1. <filter name="filterTest" condition="name_id < :myid" />

调用方法 

  1. session.enableFilter"filterTest" ).setParameter( "myid"20 );

6.分页查询【重要】

  1. List list = session.createQuery( "from Student" )   .setFirstResult( 3 ) //设置第一行检索    .setMaxResults( 20 ) //设置每页最多的数据条目    .list();

7.对象导航查询,在HQL中采用 "."进行导航,进行查询【重要】

  1. //只检索一个字段,返回类型为 Object, List list = session.createQuery( "select s.name from Student s where s.classes.name like '%1%'" ).list();

8.连接查询【重要】

连接分为:

内连

外连(左连接,右连接)

testQuery1

1.查询学生的名字以及所在班级的名字

内连接

  1. //只检索一个字段,返回类型为 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

2.显示无学生班级

左连接

  1. List list = session.createQuery( "select c.name , s.name from Classes c left join c.students s " ).list();

testQuery3

3.显示无业游民

右连接

 

  1. List list = session.createQuery( "select c.name , s.name from Classes c right join c.students s" ).list();

 

9.统计查询【重要】

testQuery1

统计学生人数

 

  1. //只检索一个字段,返回类型为 Object, List list = session.createQuery("select count(*) from Student") .list();Long count = (Long) list.get(0);System.out.println("统计学生人数:" + count);

 

testQuery2

设置返回单一值,而不是返回List类型

 

  1. Long count = (Long) session.createQuery("select count(*) from Student").uniqueResult();System.out.println("统计学生人数:" + count);

 

10.DML风格的操作

//批量更新

//建议少用因为和缓存不同步

 

  1. session.createQuery("update Student s set s.name=? where s.id < ?")        .setParameter(0"张林")        .setParameter(110)        .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

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。