hibernate学习系列-----(4)hibernate基本查询上篇:HQL基本查询
紧接着上一篇,今天继续hibernate的学习总结,来聊一聊hibernate的基本查询方法,先说说HQL(hibernate Query Language):它是官方推荐的查询语言。在开始写代码之前,看看需要做哪些准备工作吧,首先,在我们的学生类中新增一个属性“clazz”,其实不加也可以,接着,我们需要重写Student.java类中的toString()方法,代码如下:
/**
* 重写toString方法
*/
@Override
public String toString() {
return "Student [age=" + age + ", id=" + id + ", stuName=" + name+ ",clazz="+clazz+"]";
}
再往后,我们需要把关于开启事务、关闭事务、打开session、关闭session之类动作进行封装,为此,在src目录下新建一个包com.joe.util,并在该包下新建一个HibernateUtils.java文件,统一封装如下代码:
package com.joe.util; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry; /**
*
* @author Joe
* 工具类
*/
public class HibernateUtils { private static SessionFactory sessionFactory;
private static Session session; static{
Configuration cfg=new Configuration().configure(); StandardServiceRegistryBuilder ssrb=new StandardServiceRegistryBuilder().applySettings(cfg.getProperties());
ServiceRegistry service=ssrb.build();
sessionFactory=cfg.buildSessionFactory(service); } /**
* 无参的构造函数
*/
private HibernateUtils(){ } /**
* 获取session对象
*/
public static Session getSession(){
return sessionFactory.openSession();
}
/**
* 关闭session对象
*/
public static void closeSession(){
if(session!=null&&session.isOpen()){
session.close();
}
} /**
* 重载关闭session对象方法
* @param session Session对象
*/
public static void closeSession(Session session){
if(session!=null&&session.isOpen()){
session.close();
}
} }
最后,在项目中新建一个HQLTest.java文件,开始我们的查询HQL查询之旅。
Query接口
Query是Hibernate专门用来执行HQL语句的查询接口,使用方式:
Query query = session.createQuery("HQL语句");
query.setParameter(...);
List resultList = query.list();
1、查询所有实例对象:
/**
* 查询所有实例对象
*/
@Test
public void selectAll() {
Transaction tx = null;
Session session = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
String hql = " from Student";
Query query = session.createQuery(hql);
@SuppressWarnings("unchecked")
List<Student> list = (List<Student>) query.list();
for (Student stu : list) {
System.out.println(stu);
}
tx.commit();
} catch (HibernateException he) {
// TODO: handle exception
if (tx != null) {
tx.rollback();
}
he.printStackTrace();
} finally {
HibernateUtils.closeSession(session);
}
}
这里的String hql = " from Student";,这里的Student就是我们的实体类名,当然,也可以这样写:
String hql = " select stu from Student as stu"; //as也可以省略,直接写成
//String hql = " select stu from Student stu";
2、查询单个实体对象:
/**
* 查询单个实例对象
*/
@Test
public void selectSingle() {
Transaction tx = null;
Session session = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
String hql = " from Student";
Student stu = (Student) session.createQuery(hql).setMaxResults(1).uniqueResult();
System.out.println(stu);
tx.commit();
} catch (HibernateException he) {
// TODO: handle exception
if (tx != null) {
tx.rollback();
}
he.printStackTrace();
} finally {
HibernateUtils.closeSession(session);
}
}
其实和上面的方法大同小异,没有什么大问题
3、投影查询:
/**
* 投影查询
*/
@Test
public void selectProjection() {
Transaction tx = null;
Session session = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
String hql = "select stu.id, stu.name,stu.age from Student stu";
Query query = session.createQuery(hql);
@SuppressWarnings("unchecked")
List<Object[]> objList = query.list();
for (Object objs[] : objList) {
for (Object obj : objs) {
System.out.println(obj);
}
System.out.println("------学生信息------");
}
tx.commit();
} catch (HibernateException he) {
// TODO: handle exception
if (tx != null) {
tx.rollback();
}
he.printStackTrace();
} finally {
HibernateUtils.closeSession(session);
}
}
不难发现,这里的HQL语句和SQL语句很相似,只是要注意一点,查询得到的结果是一个Object类型的数组,这样就不爽了,不能转化成我们的Student的对象,为此,就有了下面的方法。
4、实例化的投影查询:
/**
* 实例化的投影查询
*/
@Test
public void selectProjectionInstantiated() {
Transaction tx = null;
Session session = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
String hql = "select new Student(stu.name,stu.age) from Student stu";
Query query = session.createQuery(hql);
@SuppressWarnings("unchecked")
List<Student> list = (List<Student>) query.list();
for (Student stu : list) {
System.out.println(stu);
}
tx.commit();
} catch (HibernateException he) {
// TODO: handle exception
if (tx != null) {
tx.rollback();
}
he.printStackTrace();
} finally {
HibernateUtils.closeSession(session);
}
}
为了实现功能,我们需要为Student类添加一个包含两个参数(name和age)的构造方法:
/**
* 构造方法
* @param name
* @param age
*/
public Student(String name,int age){
this.name=name;
this.age=age;
}
5、where条件查询:
/**
* 条件查询
*/
@Test
public void selectByCondition() {
Transaction tx = null;
Session session = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
String hql = "select stu from Student stu where stu.name='zhangsan'";
Query query = session.createQuery(hql);
@SuppressWarnings("unchecked")
List<Student> list = (List<Student>) query.list();
for (Student stu : list) {
System.out.println(stu);
}
tx.commit();
} catch (HibernateException he) {
// TODO: handle exception
if (tx != null) {
tx.rollback();
}
he.printStackTrace();
} finally {
HibernateUtils.closeSession(session);
}
}
这和SQL语句真的就很相同了,你想怎么写就怎么写吧,where查询条件有很多,就简单列举一点吧:
在where子句中可以指定
.号
比较运算符:
=、>、>=、<、<=、<> 、is null 、is not null
范围运算符:
in (值1, 值2 …) : 等于列表中的某一个值
not in(值1, 值2 …) : 不等于列表中的任意一个值
between 值1 and 值2 : 在值1到值2的范围内(包括值1和值2)
not between 值1 and 值2 : 不在值1到值2的范围内
字符串模式匹配: like '字符串模式'
字符串模式中可用“%”代表任意长度的字符串,“_”代表任意单个字符。
逻辑运算: and (与)、 or (或)、not (非)
用于集合的运算符:is empty、is not empty
6、HQL函数查询:
/**
* HQL函数查询
*/
@Test
public void selectByHQLFunc() {
Transaction tx = null;
Session session = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
String hql = "select new Student(upper(stu.name),lower(stu.clazz)) from Student stu ";
Query query = session.createQuery(hql);
@SuppressWarnings("unchecked")
List<Student> list = (List<Student>) query.list();
for (Student stu : list) {
System.out.println(stu);
}
tx.commit();
} catch (HibernateException he) {
// TODO: handle exception
if (tx != null) {
tx.rollback();
}
he.printStackTrace();
} finally {
HibernateUtils.closeSession(session);
}
}
这只是简单的一个例子,hibernate为我们提供了很多强大而方便的函数,简单地列举一点吧:
1.字符串相关
upper(s) 、lower(s) 、
concat(s1, s2) 、substring(s,offset,length) 、 length(s)、
trim([[both|leading|trailing] char [from]] s)、locate(search, s, offset)
2.数字
abs(n) 、sqrt(n)、mod(dividend, divisor)
3.集合
size(c) 返回集合中元素的个数
4.日期时间
current_date()、current_time()、current_timestamp()
返回数据库系统的日期、时间、时间戳
year(d)、month(d)、day(d)、hour(d)、minute(d)、second(d)
从指定的参数中提取相应的值、
7、动态参数绑定查询:
/**
* 按照参数位置动态绑定查询
*/
@Test
public void selectByParamLocation() {
Transaction tx = null;
Session session = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
String hql = "select stu from Student stu where stu.name=? and stu.age=?";
Query query = session.createQuery(hql);
query.setInteger(1, 22);
query.setString(0, "wangwu");
@SuppressWarnings("unchecked")
List<Student> list = (List<Student>) query.list();
for (Student stu : list) {
System.out.println(stu);
}
tx.commit();
} catch (HibernateException he) {
// TODO: handle exception
if (tx != null) {
tx.rollback();
}
he.printStackTrace();
} finally {
HibernateUtils.closeSession(session);
}
}
有没有发现,这和jdbc的查询方式很相似,我们知道hibernate对jdbc底层API进行了封装,这就体现出来了,除此外,还可以按照参数的名称进行查询,将上面的代码做如下修改:
String hql = "select stu from Student stu where stu.name=:name and stu.age=:age";
Query query = session.createQuery(hql);
query.setInteger("age", 22);
query.setString("name", "wangwu");
效果完全一样。
8、HQL去掉重复记录:
/**
* HQL去掉重复记录
*/
@Test
public void selectDistinct() {
Transaction tx = null;
Session session = null;
try {
session = HibernateUtils.getSession();
tx = session.beginTransaction();
String hql = "select distinct stu.age,stu.name from Student stu"; Query query = session.createQuery(hql); @SuppressWarnings("unchecked")
List<Object[]> list = query.list();
for (Object objs[] : list) {
System.out.println(objs[0]);
System.out.println(objs[1]);
System.out.println("-----学生信息-----");
} tx.commit();
} catch (HibernateException he) {
if (tx != null) {
tx.rollback();
}
he.printStackTrace();
} finally {
HibernateUtils.closeSession(session);
} }
这里要注意了,这里的去重是指多条完全一样的记录,可以看看我们数据库表中现在已存在的数据:

有两条一模一样的数据,运行上面的方法,看看结果:

可以发现只有4条记录被查询出来。除此之外,我们还可以发现这个方法查询的结果也是一个Object型的数组。或者说,只要不是查询的实体类的所有属性并且不通过实体类的对应的构造方法进行转化的HQL查询得到的结果都是Object型的数组。
好吧,今天写的有点完了,明天继续!
hibernate学习系列-----(4)hibernate基本查询上篇:HQL基本查询的更多相关文章
- hibernate学习系列-----(5)hibernate基本查询下篇:hibernate聚合函数、分组查询及命名查询
在上一篇中,大致学习了hibernate的基本查询:HQL基本查询,今天,继续昨天的步伐,继续学习hibernate的基本查询..... 1.hql聚合函数,先大致列一下hql的聚合函数有哪些吧: 在 ...
- hibernate学习系列-----(2)hibernate核心接口和工作机制
在上一篇文章hibernate学习系列-----(1)开发环境搭建中,大致总结了hibernate的开发环境的搭建步骤,今天,我们继续了解有关hibernate的知识,先说说这篇文章的主要内容吧: C ...
- Hibernate学习一:Hibernate注解CascadeType
http://zy19982004.iteye.com/blog/1721846 ———————————————————————————————————————————————————————— Hi ...
- [原创]java WEB学习笔记93:Hibernate学习之路---Hibernate 缓存介绍,缓存级别,使用二级缓存的情况,二级缓存的架构集合缓存,二级缓存的并发策略,实现步骤,集合缓存,查询缓存,时间戳缓存
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- hibernate学习系列-----(9)hibernate对集合属性的操作之Map集合篇
照旧,先新建一个StudentMap.java实体类,将hobby属性使用map集合接口来存放: package com.joe.entity; import java.util.Map; publi ...
- hibernate学习系列-----(7)hibernate对集合属性的操作之List集合篇
今天要写的内容其实不多,本打算将hibernate对集合的操作的内容直接归结为一篇的,但想一想,还是分开写的比较好,毕竟前面的已经发布出去来了,废话不多说,开始吧! 依旧新建一个StudentList ...
- hibernate学习系列-----(1)开发环境搭建
其实一两个月前就在了解hibernate方面的知识了,但一直以来,都没有好好的总结,而且一直使用的是myeclipse,感觉有些傻瓜式的操作就可以搭建起hibernate的开发环境,但这样一点都不好, ...
- [原创]java WEB学习笔记89:Hibernate学习之路-- -Hibernate检索方式(5种),HQL介绍,实现功能,实现步骤,
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- [原创]java WEB学习笔记80:Hibernate学习之路--- hibernate配置文件:JDBC 连接属性,C3P0 数据库连接池属性等
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
随机推荐
- OpenCV 2.4.9 学习笔记(4)—— 像素类型与Templates的限制使用
限制使用templates C++中的Templates使得接口机制非常好用,高效而且能够保证数据与算法的安全.但是过多地使用templates可能会增加计算时间和代码长度,有时候还能难区分接口和实现 ...
- 5.DataFrame(基本概念)
- 学习SPRING BOOT, SPRING CLOUD之Eureka和security
有意思,明天去杨浦报名了一个SPRING CLOUD沙龙, 今天再抓紧看看哈哈哈. Eureka服务端: EurekaApplication.java package com.packtpub.Eur ...
- .ner core InvalidOperationException: Cannot find compilation library location for package 'xxx' 和 SqlException: 'OFFSET' 附近有语法错误。 在 FETCH 语句中选项 NEXT 的用法无效。问题
原文地址:传送门 1.InvalidOperationException: Cannot find compilation library location for package 'xxx'问题: ...
- 微信小程序 使用swiper制作一个滑动导航
最近在做一个导航的时候,发现使用overflow-x: auto来做多内容滑动导航效果很不好,思索是不是可以使用swiper来做一个,研究了下其实发现原理基本相同 这里说下,要用swiper做导航菜单 ...
- hadoop之深入浅出
分布式文件系统与HDFS lHDFS体系结构与基本概念*** l数据量越来越多,在一个操作系统管辖的范围存不下了,那么就分配到更多的操作系统管理的磁盘中,但是不方便管理和维护,因此迫切需要一种系统来管 ...
- POJ 3735 Training little cats(矩阵乘法)
[题目链接] http://poj.org/problem?id=3735 [题目大意] 有一排小猫,给出一系列操作,包括给一只猫一颗花生, 让某只猫吃完所有的花生以及交换两只猫的花生, 求完成m次操 ...
- 【CodeForces 788B】奇妙的一笔画问题
[pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=61845295 题目大意 给定n个点m条边的无向图 ...
- 八. 输入输出(IO)操作6.文件与目录管理
目录是管理文件的特殊机制,同类文件保存在同一个目录下不仅可以简化文件管理,而且还可以提高工作效率.Java 语言在 java.io 包中定义了一个 File 类专门用来管理磁盘文件和目录. 每个 Fi ...
- 六. 异常处理6.try语句的嵌套
Try语句可以被嵌套.也就是说,一个try语句可以在另一个try块内部.每次进入try语句,异常的前后关系都会被推入堆栈.如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个t ...