不知不觉又到了hibernate的最后一篇了,只感觉时光飞逝~,岁月如梭~!

转眼之间,我们就···························,好吧,想装个X,结果装不下去了,还是直接开始吧·

前面我们已经把hibernate中添加、删改、修改和根据ID得到对象的方法都学习了,但如何才能查询出多条记录呢?比如我想查询所有姓黄的作者,查询标题包含“中”字的博客等。这一篇就来介绍查询。

hibernate有两种检索(查询)数据的方式,分别是HQL(Hibernate Query Language)和QBC(Query By Criteria)。官方推荐使用HQL的方式,不要问我为什么,因为············就算你很诚恳的询问我,我也不会告诉你。反正用过HQL的人都说好。

HQL提供的语法与SQL非常相似,支持动态参数绑定、投影查询、分页查询、连接查询、分组查询、内置聚集函数、子查询等,可以说是数据库中常用的查询功能,HQL都可以实现。

当然,HQL并不是只能查询,其实也可以用来执行insert、delete和update语句(使用HQL语法),只不过我们今天不讲,大家有兴趣自己练习一下就OK了。

HQL使用步骤:

  1. )获取Session对象

  2. )编写HQL语句

  3. )获得Query对象

  4. )动态绑定参数

  5. )调用执行方法

今天玩点花样,我们通过常用的查询功能来讲解每个语法吧。

一、查询所有的作者

1
2
3
4
5
6
7
8
9
10
11
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询所有作者
         String hql =  "from Author" ;
         Query query = session.createQuery(hql);
         List<Author> list = query.list();
         for  (Author author : list) {
             System.out.println( "姓名:" +author.getUsername());
         }
         HibernateSessionFactory.closeSession();
     }

注意:

1. 查询Author的所有属性时可以省略select部分

2. from后面的Author是Java中的实体类的类名,在HQL语句中 select或from之类的关键字不区别大小写,但类名、属性名必须和实体类大小写完全相同。

结果:

二、查询作者ID为2的所有博客

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询ID为2的作者的博客
         Author author = (Author)session.get(Author. class 2 );
         //把作者对象当作参数进行查询
         //String hql = "from Blog b where b.author=?";     //占位符方式
         String hql =  "from Blog b where b.author=:author" ;    //参数名方式
         Query query = session.createQuery(hql);
         //添加参数
         //query.setEntity(0, author);      //占位符方式
         query.setEntity( "author" , author);    //参数名方式
         //执行查询
         List<Blog> list = query.list();
         //遍历结果
         for  (Blog blog : list) {
             System.out.println( "标题:" +blog.getTitle());
         }
         HibernateSessionFactory.closeSession();
     }

注意:

这儿的条件,where后面的author是Blog实体类中的author属性,参数是什么类型就可以使用setxxx传对应的类型

参数有两种写法:一种是使用“?”,相当于占位符,另一种使用“:xxx”,相当于根据名字传值。

结果:

三、查询标题包含“中”字的所有博文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询标题包含“中”字的所有博文
         String hql =  "from Blog b where b.title like ?" ;
         Query query = session.createQuery(hql);
         //添加参数
         query.setString( 0 "%中%" );     //参数名方式
         //执行查询
         List<Blog> list = query.list();
         //遍历结果
         for  (Blog blog : list) {
             System.out.println( "标题:" +blog.getTitle());
         }
         HibernateSessionFactory.closeSession();
     }

注意:

like后面不能写成'%?%',这种写法是错误的。必须在外面拼接好前后的“%”,再作为参数传递给query对象。

结果:

四、按博文创建日期倒序排列所有博文

1
2
3
4
5
6
7
8
9
10
11
12
13
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //按日期倒序排列所有博文
         String hql =  "from Blog b order by b.createTime desc" ;
         Query query = session.createQuery(hql);
         //执行查询
         List<Blog> list = query.list();
         //遍历结果
         for  (Blog blog : list) {
             System.out.println( "时间:" +blog.getCreateTime()+ ",标题:" +blog.getTitle());
         }
         HibernateSessionFactory.closeSession();
     }

注意:

反复看了三遍,发现真的没有哪儿需要注意,我也很绝望啊!

结果:

五、假如每页显示3篇博文,在上一查询的基础上,查询第2页的博文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         int  pageNO =  2 ;        //页码
         int  pageCount =  3 ;     //每页数量
         //按日期倒序排列所有博文
         String hql =  "from Blog b order by b.createTime desc" ;
         Query query = session.createQuery(hql);
         query.setFirstResult((pageNO- 1 )*pageCount);         //起始位置
         query.setMaxResults(pageCount);                     //记录数量
         //执行查询
         List<Blog> list = query.list();
         //遍历结果
         for  (Blog blog : list) {
             System.out.println( "时间:" +blog.getCreateTime()+ ",标题:" +blog.getTitle());
         }
         HibernateSessionFactory.closeSession();
     }

注意:

setFirstResult表示查询的第一条记录的下标,setMaxResults表示查询几条记录,一般分页都是传递页码(第几页)过来。至于实际项目中的分页如何编写,等后面我们讲常用功能模块时再来说明吧。

结果:

六、根据手机号查询作者(确定最多只有一条记录)

1
2
3
4
5
6
7
8
9
10
11
12
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询手机号为13612349876的作者
         String hql =  "from Author a where a.phone=?" ;
         Query query = session.createQuery(hql);
         //添加参数
         query.setString( 0 "13612349876" );
         //执行查询
         Author author = (Author)query.uniqueResult();
         System.out.println( "姓名:" +author.getUsername()+ ",联系方式:" +author.getPhone());
         HibernateSessionFactory.closeSession();
     }

注意:

确定查询结果最多只有一条记录时,可以使用uniqueResult()方法。

结果:


单表查询并且返回所有属性的查询语法,到这儿就告一段落。

接下来进行部分属性的查询、分组查询、多表查询和子查询。


查询语法加上select子句后,返回的结果有以下几种接收方式。

  1. object[]数组

  2. List集合

  3. Map集合

  4. 自定义实体类

我们还是通过例子来学习吧:查询所有博文,只返回标题和内容。

1
2
3
4
5
6
7
8
9
10
11
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询所有博文,返回标题和内容
         String hql =  "select title,content from Blog" ;
         Query query = session.createQuery(hql);
         List<Blog> list = query.list();
         for  (Blog blog : list) {
             System.out.println( "标题:" +blog.getTitle());
             System.out.println( "\t内容:" +blog.getContent());
         }
     }

运行会发现出现以下异常:

大概意思就是不能把Object转换成Blog类型。

接下来,我们使用上面所说的四种方式来解决这个问题,结果就不再一一展示了。

1、Object[]数组方式

1
2
3
4
5
6
7
8
9
10
11
12
13
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询所有博文,返回标题和内容
         String hql =  "select title,content from Blog" ;
         Query query = session.createQuery(hql);
         //执行查询
         List<Object[]> list = query.list();
         for  (Object[] objects : list) {
             System.out.println( "标题:" +objects[ 0 ]);
             System.out.println( "\t内容:" +objects[ 1 ]);
         }
         HibernateSessionFactory.closeSession();
     }

注意:如果只查询一个属性时,返回的就不再在数组,而是单个Object。

 

2、List集合方式

1
2
3
4
5
6
7
8
9
10
11
12
13
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询所有博文,返回标题和内容
         String hql =  "select new List(title,content) from Blog" ;
         Query query = session.createQuery(hql);
         //执行查询
         List<List> list = query.list();
         for  (List lst : list) {
             System.out.println( "标题:" +lst.get( 0 ));
             System.out.println( "\t内容:" +lst.get( 1 ));
         }
         HibernateSessionFactory.closeSession();
     }

注意:HQL语句中的select后面,使用new List()的方式来接受数据。

3、Map集合方式

1
2
3
4
5
6
7
8
9
10
11
12
13
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询所有博文,返回标题和内容
         String hql =  "select new Map(title as t,content as c) from Blog" ;
         Query query = session.createQuery(hql);
         //执行查询
         List<Map> list = query.list();
         for  (Map map : list) {
             System.out.println( "标题:" +map.get( "t" ));
             System.out.println( "\t内容:" +map.get( "c" ));
         }
         HibernateSessionFactory.closeSession();
     }

注意:如果new Map()中的属性没有取别名,则在for循环中通过get("下标")的形式来读取数据,特别注意,这儿是字符串"下标",而不是整数。

4、自定义实体类

4.1)在Blog实体类中添加包含标题和内容的构造方法

1
2
3
4
5
     //新增构造方法
     public  Blog(String title, String content){
         this .title = title;
         this .content = content;
     }

4.2)测试类中的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询所有博文,返回标题和内容
         String hql =  "select new Blog(title,content) from Blog" ;
         Query query = session.createQuery(hql);
         //执行查询
         List<Blog> list = query.list();
         for  (Blog blog : list) {
             System.out.println( "标题:" +blog.getTitle());
             System.out.println( "\t内容:" +blog.getContent());
         }
         HibernateSessionFactory.closeSession();
     }

注意:HQL语句中查询几个属性,则在对应的实体类中必须的对应的构造方法。

四种方式到这儿就介绍完毕,至于哪种好哪种差,那就看个人习惯了。

继续后面的案例:

七、查询每个作者的博文数量(分组查询)

1
2
3
4
5
6
7
8
9
10
11
12
13
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询每个作者的博文数
         String hql =  "select author, count(b) from Blog b group by b.author" ;
         Query query = session.createQuery(hql);
         //执行查询
         List<Object[]> list = query.list();
         for  (Object[] objects : list) {
             System.out.print( "作者:" +((Author)objects[ 0 ]).getUsername());
             System.out.println( ",博文数:" +objects[ 1 ]);
         }
         HibernateSessionFactory.closeSession();
     }

注意:分组之后的统计数据没办法保存到实体类,所以只能使用前三种方式来接受数据。

结果:

八、查询所有的博文和作者(作者账号已经注销的不查(也就是博文表中作者ID为null的不查),多表联合查询)

1
2
3
4
5
6
7
8
9
10
11
12
13
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询所有博文,包括作者信息
         String hql =  "from Blog b inner join b.author a" ;
         Query query = session.createQuery(hql);
         //执行查询
         List<Object[]> list = query.list();
         for  (Object[] objs : list) {
             System.out.println( "标题:" +((Blog)objs[ 0 ]).getTitle());
             System.out.println( "\t作者:" +((Author)objs[ 1 ]).getUsername());
         }
         HibernateSessionFactory.closeSession();
     }

注意:inner join后面的是Blog类中的author属性,Ojbect[]数组中保存的是两个对象。左连接的功能,大家自己尝试吧。

结果:

 

九、最后一个,查询博文数是2的所有作者(子查询)

1
2
3
4
5
6
7
8
9
10
11
12
     public  static  void  main(String[] args) {
         Session session = HibernateSessionFactory.getSession();
         //查询所有博文,包括作者信息
         String hql =  "from Author a where (select count(b) from a.blogs b)=2" ;
         Query query = session.createQuery(hql);
         //执行查询
         List<Author> list = query.list();
         for  (Author author : list) {
             System.out.println( "作者:" +author.getUsername());
         }
         HibernateSessionFactory.closeSession();
     }

结果:

呼~~~~~~,想不到我也能写出这么长的文章。

破了我30多年来的历史记录啊!!!激动得要了。

恳请大大给我加个推荐吧~~

“软件思维”博客地址:51CTO博客园,感兴趣的小伙伴可以去看相关的其它博文。

《Java从入门到放弃》入门篇:hibernate查询——HQL相关推荐

  1. flink入门_Flink从入门到放弃-入门篇

    大数据成神之路: 点我去成神之路系列目录^_^ Java高级特性增强-集合 Java高级特性增强-多线程 Java高级特性增强-Synchronized Java高级特性增强-volatile Jav ...

  2. 391、Java框架46 -【Hibernate - 查询HQL、查询Criteria、查询标准SQL】 2020.10.19

    0.目录 1.HQL 2.使用HQL,根据name进行模糊查询 3.查询Criteria 4.使用Criteria,根据name进行模糊查询 5.查询-标准SQL 6.使用标准SQL,根据name进行 ...

  3. Hibernate查询——HQL,包括分页查询

    hibernate查询 概述:数据查询与检索是Hibernate中的一个亮点.相对其他ORM实现而言,Hibernate提供了灵活多样的查询机制. HQL --(Hibernate Query Lan ...

  4. mvc php 代码审计,代码审计从入门到放弃系列篇一之代码审计学习思路

    学习代码审计要熟悉三种技术,分四部分走 一:编程语言 1:前端语言 html/javascript/dom元素使用 主要是为了挖掘xss漏洞 jquery 主要写一些涉及到CSRF脚本使用的或者DOM ...

  5. 计算机网络从入门到放弃,自由讨论 | KBQA从入门到放弃—入门篇

    ➊ KBQA 的定义/概念/应用前景是什么? 知识库问答(knowledge base question answering, KB-QA)即给定自然语言问题,通过对问题进行语义理解和解析,进而利用知 ...

  6. 【java】vertx从入门到放弃——入门(四)Codec

    什么是Codec?概念这个玩意我是真不想说,毕竟我没有找到具体的概念,我自己大致的理解就是,用EventBus传输类的时候,对这个类进行序列化和反序列化的东西,因为vertx使用json进行传输,所以 ...

  7. 操作系统(3) 多处理器编程:从入门到放弃

    操作系统(3) 多处理器编程:从入门到放弃 入门:理解多线程 三个放弃:原子性.有序性.可见性 并发:介绍 进程与线程的区别: 进程:正在运行的程序,系统分配资源和调度的基本单位,内存中可以同时加载多 ...

  8. Hibernate查询以及优化策略

    文章目录 回顾 今天任务 教学目标 Hibernate查询 Hibernate优化策略 ==一. HQL查询== 1. HQL单表查询 1.1 准备项目 1.2 HQL单表基本查询 2. HQL多表查 ...

  9. 《Java从入门到放弃》框架入门篇:hibernate基本配置

    hibernate是个什么玩意呢?简单点说,就是别人写好的一套访问数据库的东东,底层其实就是JDBC. 使用JDBC就像以前没有电饭煲,我们要自己根据经验,多少人煮多少米,放多少水,用多大的火,煮多长 ...

最新文章

  1. 基于深度学习的位姿估计方法
  2. 产品经理,如何建立自己独特的产品观?(转)
  3. 《死亡笔记》与绵球方块先生
  4. GLTF格式——关系描述
  5. HDOJ 1160 FatMouse's Speed
  6. 微信公众开放平台开发08---纯java 实现微信开发:编写自定义菜单
  7. Harbor快速部署到Kubernetes集群及登录问题解决
  8. Kali Linux 更新了1.0.9a,第一时间分享
  9. Go基础-go语言的编码规范
  10. 邮件服务器最常见的安全问题及解决办法
  11. 大麦无线路由器改装打印服务器,大麦domywifi DW33D路由器固件openwrt重分区版
  12. 16个精美的 HTML5 作品集网站设计案例
  13. 【20220627】【信号处理】自相关函数的定义、计算方法及应用
  14. ps—图层、(移动工具中)对齐
  15. SQL Server 2008 误删除数据的恢复
  16. php容器下安装gd库
  17. 《菜鸟教程》丨2D骨骼动画工具DragonBones的使用教程
  18. Log4j的基本应用
  19. Unity台北場優化分享 达哥 讲 Unity优化
  20. C#.NET使用TTS引擎实现文语转换

热门文章

  1. 处理浏览器兼容所遇到的问题总结(一)
  2. [百瑞莲]diy巧克力盒
  3. Android 隐藏LinearLayout
  4. 远视眼并不是老花眼,远视并不是这么简单!
  5. 蓝光视频转换工具AnyMP4 Blu-ray Ripper Mac
  6. 送给所有还未买房的技术朋友们——住房按揭贷款计算器
  7. SLI®(速力™)多操作系统(MULTI-OS)
  8. linux添加组播路由命令,linux – 使用ip route add将组播路由添加到多个接口
  9. Linux下串口编程(C语言版本)
  10. validationGroup和Page_ClientValidate()