hibernate的hql查询
HQL(Hibernate Query Language),提供更加丰富灵活、更为强大的查询能力;HQL更接近SQL语句查询语法。查询的表(Table)名称是类的名称
,表的字段是对象的属性
,有多个类的话,可以使用类的全限定名来指定,比如现在有一个类,它位于a/aa/bb/cc/User.java。对应hql写法可以是,from a.aa.bb.cc.User
,这一写法主要是区分有两个不同包下出现了相同的类名称才会这样指定他的全限定名称
本篇文章的示例代码下载地址
https://download.csdn.net/download/qq_29001539/12277983
HQL查询方式
// 1.查询所有
// 2.条件查询(where、模糊匹配)
// 3.范围查询(OR、IN、AND、NOT、>、<、<=、>=、<>、BETWEEN … AND …)
// 4.排序查询(order by)
// 5.分页查询
// 6.投影查询(只获取部分字段的结果)
// 7.聚集函数使用(聚合函数)(count、sum、avg、max、min等)
// 8.TOP N查询(返回n条记录)
// 9.命名查询
sql查询语句示例参考
- 常用的DML语句
https://www.cnblogs.com/qiuxirufeng/p/10802396.html
https://blog.csdn.net/L835311324/article/details/86761095
https://www.pianshen.com/article/5059342909
1、查询所有
查询的方式:from 对象名称
// 1.查询全部:获取所用用户信息
@Test
public void testList() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from User");
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
2、条件查询
条件查询中,关于参数绑定
的方式有两种,一种是通过占位符?,另外一种是给参数其名称,类似where user = :aliasName;
条件查询中,关于参数传递
的方式有两种,一种是指定类型传参数,另外一种是可以接受任意类型的参数
1)指定类型有以下几种形式:
- setString(int position, String val);
- setCharacter(int position, char val);
- setBoolean(int position, boolean val);
- setByte(int position, byte val);
- setShort(int position, short val);
- setInteger(int position, int val);
- setLong(int position, long val);
- setFloat(int position, float val)
- setDouble(int position, double val)
- setBinary(int position, byte[] val);
- setText(int position, String val);
- setDate(int position, Date date);
- setTime(int position, Date date);
- setTimestamp(int position, Date date);
还有其他的类型在这里并没有罗列出来,如有需要的可以参考org.hibernate.Query
这个接口类定义的setXXX(int position, xxx value)这样的方法。像上面罗列出来的方法是指定占位符出现的位置,默认位置从0开始,参考示例如下:
String hql = "from User where name = ? and age = ?";
query.setString(0,"123");// 设置name=123
query.setInteger(1, 10);// 设置age=10
如果不是采用占位符?的方式来指定查询的条件,而是采用给参数命名的方式来指定查询的条件,可以找setXXX(String name,xxx value)这样的方法,举例如下:
// abcAge这个参数名称没有实际意义,可以任意命名但是不要有相同的名称,这个只是用来识别参数条件要放入的位置
String hql = "from User where name = :abcName and age = :abcAge";
query.setString("abcName","123");// 设置name=123
query.setInteger("abcAge", 10);// 设置age=10
2)对类型没有要求,可以接受任意类型的参数条件:
setParameter(int position, Object val); // position为占位符?出现的位置,val是参数条件值
setParameter(String name, Object val); // name为你取名字的那个参数名称,val是参数条件值
代码查询示例
// 2.1条件查询:通过id查询对象(按占位符?出现的位置来绑定条件参数)
@Test
public void testGetById() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// from 对象 where 对象.属性=?
Query query = session.createQuery("from User where sid = ?");
// setInteger,绑定指定类型的参数,类型同对象的属性类型
// setParameter,绑定任意的类型的参数
query.setParameter(0, 1);// 设置sid为1(位置从零开始) ===> 等同于 query.setInteger(0, 1);
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 2.2条件查询:查询指定班级的信息(按名称进行绑定参数)
@Test
public void testGetByClazz() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from User where clazz = :parClazz");
/*
* 设置参数名称为parClazz的值是s1t84 ===> 等同于 query.setParameter("parClazz", "s1t84");
*/
query.setString("parClazz", "s1t84");
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 2.3条件查询:查询性别是女并且成绩是100的对象信息
@Test
public void testGetScorePass() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// from 对象 where 对象.属性=?
Query query = session.createQuery("from User where gender = ? and score = ?");
// setInteger,绑定指定类型的参数,类型同对象的属性类型
// setParameter,绑定任意的类型的参数
query.setParameter(0, "女");// 设置性别(gender)=女 ===> 等同于 query.setString(0,"女");
query.setParameter(1, 100);// 设置成绩(score)=100 ===> 等同于 query.setInteger(0,100);
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 2.4条件查询:查询name含有“金”的对象信息
@Test
public void testLikeName() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from User where name like ?");
query.setParameter(0, "%金%");// 设置name中含有金的
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
3、范围查询
// 3.1范围查询:查找用户的密码是123456或者asdfghjkl这两种
@Test
public void testScopeOrPwd() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select sid,name,pwd from User where pwd = :pwdone or pwd = :pwdtwo");
query.setParameter("pwdone", "123456");
query.setParameter("pwdtwo", "asdfghjkl");
List<Object[]> lis = query.list();
for (Object[] objects : lis) {
System.out.println("sid:" + objects[0] + "|name:" + objects[1] + "|pwd:" + objects[2]);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 3.2范围查询:查找用户的密码有123456、010101、555555、999999等范围
@Test
public void testScopeInPwd() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select sid,name,pwd from User where pwd in(?,?,?,?)");
query.setParameter(0, "87654321");
query.setParameter(1, "010101");
query.setParameter(2, "555555");
query.setParameter(3, "999999");
List<Object[]> lis = query.list();
for (Object[] objects : lis) {
System.out.println("sid:" + objects[0] + "|name:" + objects[1] + "|pwd:" + objects[2]);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 3.3范围查询:查找班级不是s1t86、s1t87的
@Test
public void testScopeNotClass() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from User where clazz NOT IN (?,?)");
query.setParameter(0, "s1t86");
query.setParameter(1, "s1t87");
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 3.4范围查询:查找成绩为60分以上的(不含60分)
@Test
public void testScopeGtScore() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from User where score > ?");
query.setParameter(0, 60);
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 3.5范围查询:查找生日不等于“2016-10-11”的对象信息
@Test
public void testScopeNotEqualBirth() throws ParseException {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from User where birth <> ?");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
query.setParameter(0, sdf.parse("2016-10-11"));
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 3.6范围查询:查找生日不等于“1950-1-1”到“1980-12-31”的对象信息
@Test
public void testScopeBetweenBirth() throws ParseException {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from User where birth between ? and ?");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
query.setParameter(0, sdf.parse("1950-1-1"));
query.setParameter(1, sdf.parse("1980-12-31"));
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
4、排序查询
// 4.排序查询:获取排序后的对象信息
@Test
public void testGetOrderList() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// asc:升序,desc:降序
Query query = session.createQuery("from User order by sid desc");
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
5、分页查询
// 5.分页查询
@Test
public void testPaging() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from User");
// 0,5为mysql的第一页数据
// 5,5为mysql的第二页数据
// 10,5为mysql的第三页数据
query.setFirstResult(5);// 设置起始位置
query.setMaxResults(5);// 设置结果显示条数
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
6、投影查询
投影查询,比如说一个对象里有好多个属性,但是我现在不想要看那么多的属性内容,想隐藏部分数据
,或者来说只看那些对我有用的数据,这里就叫做投影查询
注意
:使用中如果hql=“select new User(sid,name,gender) from User”;
则必须让User类提供sid,name,gender的有参构造方法和一个默认的无参构造方法,否则会抛出一个类似下面这样的异常内容:
org.hibernate.hql.internal.ast.QuerySyntaxException: Unable to locate appropriate constructor on class [bean.User]. Expected arguments are: int, java.lang.String, java.lang.String [select new User(sid,name,gender) from bean.User]
// 6.1投影查询:用于指定获取对象的某一个或某几个属性(返回数组)
@Test
public void testGetAppoint1() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select sid,name,gender from User");
List<Object[]> lis = query.list();
for (Object[] object : lis) {
System.out.println("[sid:" + object[0] + ",name:" + object[1] + ",gender:" + object[2] + "]");
}
tx.commit();
session.close();
sessionFactory.close();
}
// 6.2投影查询:用于指定获取对象的某一个或某几个属性(返回对象)
@Test
public void testGetAppoint2() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// 这一写法,需要User对象提供sid,name,gender的构造参数方法和无参的构造方法
Query query = session.createQuery("select new User(sid,name,gender) from User");
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 6.3投影查询:查询所有的班级(去重复的值)
@Test
public void testGetClazzs() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// distinct:该关键字是用来去掉重复值(只保留不同的内容)
Query query = session.createQuery("select distinct clazz from User");
List<String> lis = query.list();
for (String object : lis) {
System.out.println("clazz:" + object);
}
tx.commit();
session.close();
sessionFactory.close();
}
7、聚合函数
// 7.1聚合函数的使用:count统计总数据量
@Test
public void testCount() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select count(*) from User");
Object count = query.uniqueResult();// 获取唯一的结果
int c = new Long((Long) count).intValue();
System.out.println("总数据量:" + c);
tx.commit();
session.close();
sessionFactory.close();
}
// 7.2聚合函数的使用:sum统计性别男、女的总人数
@Test
public void testSum() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select gender,sum(gender) from User group by gender");
List<Object[]> person = query.list();// 获取唯一的结果
for (Object[] obj : person) {
System.out.println("性别:" + obj[0] + "-----对应的总人数为:" + obj[1]);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 7.3聚合函数的使用:avg获取平均的分数
@Test
public void testAvgScore() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select avg(score) from User");
Object avgScore = query.uniqueResult();
System.out.println("平均成绩:" + avgScore);
tx.commit();
session.close();
sessionFactory.close();
}
// 7.4聚合函数的使用:max获取最高的分数
@Test
public void testMaxScore() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select max(score) from User");
Object maxScore = query.uniqueResult();
System.out.println("最高的分数:" + maxScore);
tx.commit();
session.close();
sessionFactory.close();
}
// 7.5聚合函数的使用:min获取最低的分数
@Test
public void testMinScore() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("select min(score) from bean.User");
Object minScore = query.uniqueResult();
System.out.println("最低的分数:" + minScore);
tx.commit();
session.close();
sessionFactory.close();
}
8、TOP N查询
// 8.TOP N查询:返回s1t87班级中前五位分数最高的用户信息
@Test
public void testGetTopN() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from bean.User where clazz = ? order by score desc");
query.setParameter(0, "s1t87");// 设置班级为s1t87
query.setFirstResult(0);// 结果从第一条开始
query.setMaxResults(5);// 只保留五条数据
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
9、命名查询
hibernate支持在映射文件中定义字符串形式的查询语句,这样的查询语句称为命名查询语句
。
编写这样的映射文件并在hibernate.cfg.xml使用<mapping resource="bean/sql_and_hql.xml">
来引入sql配置文件。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<!-- sql-query写的是普通的sql语句(原生态sql语句) -->
<sql-query name="findAllBySQL">
<return class="bean.User" /><!-- 指定返回的数据类型 -->
select * from t_0300
</sql-query>
<!-- query节点写的是hql语句 -->
<query name="findAllByHQL">
from User
</query>
</hibernate-mapping>
// 9.1命名查询:原生态sql查询
@Test
public void testSqlQuery() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.getNamedQuery("findAllBySQL");
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}
// 9.2命名查询:hibernate的hql查询
@Test
public void testHqlQuery() {
Configuration cfg = new Configuration().configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
Query query = session.getNamedQuery("findAllByHQL");
List<User> lis = query.list();
for (User user : lis) {
System.out.println(user);
}
tx.commit();
session.close();
sessionFactory.close();
}