Hibernate中HQL语句
2017-10-15 14:49
381 查看
HQL: Hibernate Query Language, 一个纯面向对象的查询语言. 其语法中对语法关键字大小写不敏感, 这种特性与SQL语言类似.其整体结构也与SQL语言类似.
基本规则
1. HQL语法类似于SQL,也是一种select from结构的语句。但是他后面跟的不是表名和字段名,而是类名和属性名。
2. HQL基本查询语法跟SQL很类似
3. HQL大小写不敏感。但是,设计java类名、包名、属性名时大小写敏感。
4. 包名的使用情况。比如:如果注册的实体类Emp只有一个唯一的类,那么查询时可以不加包名,hibernate会自动检索到Emp类。但是如果注册多个实体类,名字都叫Emp。此时就要增加包名来区别多个实体类。
下面一些简单的案例来使用简单HQL语法
根据id查询学生-返回的是一个学生对象
查询学生总人数-返回的是一条数据
查询已成年的女学生-带条件
查询学生的名字和年龄-返回的集合为list
可以封装返回的属性
需要提供相应的构造方法
还要注意参数顺序
采用占用符?
查询条件为18-30之间的学生
命名参数
:名称
命名参数
:名称
可以把参数存放进Map中
聚合函数
查询学生的总人数,平均年龄 最大年龄
根据学生的性别分组,显示 :性别,人数
返回的是一个集合,需要使用List
查询就读java班级的学生
数据分页
一页显示5条数据
/**
* 连接查询
* 内连接:2张表中所有满足条件的数据
* SQL:select * from A a,B b where a.id=b.id;
* select * from A a join B b on a.id=b.id;
* 外连接:
* 左外连接:查询左表中所有符合条件的数据,右表中没有则返回null
* SQL:select * from A a left join B b on a.id=b.id;
* 右外连接:和左外连接相反
* 全连接
*/
全连接
左外连接
右外链接
注意:在进行双向通信时,两个对象的toString方法不能互相返回对方的集合对象
xml文件中配置:
//外部命名查询(hql语句在任何一个有效的映射文件中定义,并给定名称,应用通过给定名称查询
基本规则
1. HQL语法类似于SQL,也是一种select from结构的语句。但是他后面跟的不是表名和字段名,而是类名和属性名。
2. HQL基本查询语法跟SQL很类似
3. HQL大小写不敏感。但是,设计java类名、包名、属性名时大小写敏感。
4. 包名的使用情况。比如:如果注册的实体类Emp只有一个唯一的类,那么查询时可以不加包名,hibernate会自动检索到Emp类。但是如果注册多个实体类,名字都叫Emp。此时就要增加包名来区别多个实体类。
下面一些简单的案例来使用简单HQL语法
@Test public void test() { /** * 采用HQL语句,后面写的是对象名 * sql : select * from tb_student; * hql : from Student; * 注意: * 类名和属性名区分大小写 * 语法结构和sql类似 */ //编写HQL语句 String hql = "from Student"; //创建query对象 Query query = session.createQuery(hql); //执行查询 System.out.println("使用List集合查询"); List<Student> list = query.list(); for (Student student : list) { System.out.println(student); } /* * list方法和iterate方法的区别 * list发出一条sql语句,查询全部数据 * iterate发出一条sql语句,查询符合条件的id * 当使用到对象就根据id查询此对象,发出另一条sql语句 * list会把数据存储到缓存中,但它不会利用缓存,每次都从数据库中查询 * iterate则会利用缓存(先查询符合条件的id,再根据id去缓存中查找对象,如果缓存中有此对象,则直接从缓存中取出此对象) * * 应用场景: * list:数据量较小,数据是财务或实时数据 * 相反则使用iterate */ System.out.println("使用Iterate迭代器查询"); Iterator iterate = query.iterate(); while(iterate.hasNext()){ Student stu = (Student) iterate.next(); System.out.println(stu); } }
根据id查询学生-返回的是一个学生对象
@Test public void getStudentById(){ String hql = "from Student where sid=1"; Query query = session.createQuery(hql); Student stu = (Student) query.uniqueResult(); System.out.println(stu); }
查询学生总人数-返回的是一条数据
@Test public void getStudentCount(){ String hql = "select count(s) from Student s"; Query query = session.createQuery(hql); long stu = (long) query.uniqueResult(); System.out.println(stu); }
查询已成年的女学生-带条件
@Test public void getStudentByWhere(){ String hql = "select count(s) from Student s where age>=16 and gender='女'"; Query query = session.createQuery(hql); long stu = (long) query.uniqueResult(); System.out.println(stu); }
查询学生的名字和年龄-返回的集合为list
@Test public void getStudentByPro(){ String hql = "select sname,age,birthday from Student"; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] object : list) { System.out.println("姓名:"+object[0]+"---年龄:"+object[1]+"---生日:"+object[2]); } hql = "select sname from Student"; query = session.createQuery(hql); List<Object> list2 = query.list(); for (Object object : list2) { System.out.println("姓名:"+object); } }
可以封装返回的属性
需要提供相应的构造方法
还要注意参数顺序
@Test public void getStudentByPro2(){ String hql = "select new Student(sname,age,birthday) from Student"; Query query = session.createQuery(hql); List<Student> list = query.list(); for (Student stu : list) { System.out.println(stu); } }
采用占用符?
查询条件为18-30之间的学生
@Test public void getStudentByPro3(){ String hql = "select new Student(sname,age) from Student where age between ? and ?"; Query query = session.createQuery(hql); //设置参数,从0开始。允许链式编程 query.setInteger(-0, 18).setInteger(1, 30); //当不清楚设置的属性类型时,可以用setParameter query.setParameter(0, 18).setParameter(1, 30); List<Student> list = query.list(); for (Student stu : list) { System.out.println(stu); } }
命名参数
:名称
@Test public void getStudentByPro4(){ String hql = "from Student where (age between :minage and :maxage) and sname like :ben"; Query query = session.createQuery(hql); //当不清楚设置的属性类型时,可以用setParameter query.setParameter("minage", 18).setParameter("maxage", 30).setParameter("ben", "ben%"); List<Student> list = query.list(); for (Student stu : list) { System.out.println(stu); } }
命名参数
:名称
可以把参数存放进Map中
@Test public void getStudentByFlag1(){ String hql = "from Student where (age between :minage and :maxage) and sname like :ben"; Query query = session.createQuery(hql); Map<String,Object> map = new HashMap<>(); map.put("minage", 18); map.put("maxage", 30); map.put("ben", "ben%"); query.setProperties(map); List<Student> list = query.list(); for (Student stu : list) { System.out.println(stu); } }
聚合函数
查询学生的总人数,平均年龄 最大年龄
@Test public void getFun(){ String hql = "select count(s),avg(age),max(age) from Student s"; Query query = session.createQuery(hql); Object[] object = (Object[]) query.uniqueResult(); System.out.println("总人数:"+object[0]+"---平均年龄:"+object[1]+"---最大年龄:"+object[2]); }
根据学生的性别分组,显示 :性别,人数
返回的是一个集合,需要使用List
@Test public void getFun2(){ String hql = "select gender,count(*) from Student group by gender"; Query query = session.createQuery(hql); List<Object[]> list = (List<Object[]>) query.list(); for (Object[] object : list) { System.out.println("性别:"+object[0]+"---人数:"+object[1]); } }
查询就读java班级的学生
@Test public void getFun3(){ String hql = "select s from Student s,Course c where c.cid=s.sid and c.cname='java'"; Query query = session.createQuery(hql); List<Student> list = query.list(); for (Student stu : list) { System.out.println(stu.toString()); } }
数据分页
一页显示5条数据
@Test public void listPage(){ String hql = "from Student"; Query query = session.createQuery(hql); /* * mysql中使用limit 0,5 * oracle中使用rownum伪列 * 设置分页的参数:setFirstResult开始行 * setMaxResults查询数量 */ query.setFirstResult(0); query.setMaxResults(5); List<Student> list = query.list(); for (Student student : list) { System.out.println(student); } }
/**
* 连接查询
* 内连接:2张表中所有满足条件的数据
* SQL:select * from A a,B b where a.id=b.id;
* select * from A a join B b on a.id=b.id;
* 外连接:
* 左外连接:查询左表中所有符合条件的数据,右表中没有则返回null
* SQL:select * from A a left join B b on a.id=b.id;
* 右外连接:和左外连接相反
* 全连接
*/
全连接
@Test public void getTables(){ String hql = "select s.sname,c.cname from Student s join s.courseset c"; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] student : list) { System.out.println(student[0]+"---"+student[1]); } }
左外连接
@Test public void getTables2(){ String hql = "select s.sname,c.cname from Student s left join s.courseset c"; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] student : list) { System.out.println(student[0]+"---"+student[1]); } }
右外链接
@Test public void getTables3(){ String hql = "select s.sname,c.cname from Student s right join s.courseset c"; Query query = session.createQuery(hql); List<Object[]> list = query.list(); for (Object[] student : list) { System.out.println(student[0]+"---"+student[1]); } }
注意:在进行双向通信时,两个对象的toString方法不能互相返回对方的集合对象
xml文件中配置:
</class> <!-- 定义HQL --> <query name="queryall"> from Student </query> </hibernate-mapping>
//外部命名查询(hql语句在任何一个有效的映射文件中定义,并给定名称,应用通过给定名称查询
@Test public void getStudentByHbm(){ Query query = session.getNamedQuery("queryall"); List<Student> list = query.list(); for (Student student : list) { System.out.println(student); } }
相关文章推荐
- Java的Hibernate框架中用于操作数据库的HQL语句讲解
- Exception:hibernate HQL不充分支持 case when语句?
- Hibernate HQL查询语句总结
- hibernate执行hql语句进行查询时,如果实体类有子类不仅会查询该类而且也会查询子类(子类在hbm中进行了配置)
- Hibernate使用hql语句查询
- hibernate--HQL查询语句-----分组、排序--多条件排序
- [Hibernate框架]Hql语句in中带参数的写法
- hibernate--HQL查询语句(1)
- Hibernate 中HQL语句
- 当hibernate的hql语句报错的应对方法
- hibernate -- HQL语句总结
- Hibernate对象状态、缓存、快照、hql语句、criteria语句、sql语句
- hibernate的hql查询语句总结
- hibernate--HQL查询语句(二)-----分组、排序
- Hibernate中使用HQL语句删除数据
- MySql函数 FIND_IN_SET 在Hibernate HQL语句中的使用
- Hibernate3学习笔记(4)——Hibernate查询技术之HQL语句
- hibernate--HQL查询语句(1)
- Hibernate中HQL语句的使用
- (HQL)Hibernate Query Lanaguage常用的语句