HQL:Hibernate Query Language

  • 提供更加丰富灵活、更为强大的查询能力
  • HQL更接近SQL语句查询语法
  • 面向对象的查询
    • "from Children where cid<?"  :这里Children指的是类不是children表;cid指的是Children类中的对象而不是children表中的字段

HQL查询(单表)

以一对多关系映射为例(parent[1]<——>children[n])

简单查询

实体类

1.Parent.java

 package com.qf.entity;

 import java.util.HashSet;
import java.util.Set; public class Parent { private Long pid;
private String pname;
private Integer age;
private Set<Children> childs = new HashSet<>(); @Override
public String toString() {
return "Parent [pid=" + pid + ", pname=" + pname + ", age=" + age + "]";
} public Long getPid() {
return pid;
}
public void setPid(Long pid) {
this.pid = pid;
}
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Set<Children> getChilds() {
return childs;
}
public void setChilds(Set<Children> childs) {
this.childs = childs;
} }

2.Children.java

 package com.qf.entity;

 public class Children {

     private Long cid;
private String cname;
private Character sex;
private Parent p; @Override
public String toString() {
return "Children [cid=" + cid + ", cname=" + cname + ", sex=" + sex + ", p=" + p + "]";
} public Long getCid() {
return cid;
}
public void setCid(Long cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Character getSex() {
return sex;
}
public void setSex(Character sex) {
this.sex = sex;
}
public Parent getP() {
return p;
}
public void setP(Parent p) {
this.p = p;
}
}

注:两个实体类的toString()方法重写时

  • Parent类的toString()方法如果包含Set<Children>的属性,那么Children类的toString()方法就不能包含Parent的属性,否则查询输出对象信息时会陷入死循环,导致StackOverflowError
package com.qf.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration; public class HibernateUtils { private static Configuration cfg ;
private static SessionFactory factory; static {
cfg = new Configuration().configure();
factory = cfg.buildSessionFactory();
} public static Session getCurrentSession() {
return factory.getCurrentSession();
}
}
@Test
/**
* HQL简单查询
*/
public void queryByHQL() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Query query = session.createQuery("from Children");
List<Children> list = query.list(); for (Children children : list) {
System.out.println(children);
} tx.commit();
}

别名查询

String hql = "select c from Children c order by cid desc";

HQL中支持数据库的带有别名的查询

@Test
/**
* HQL别名查询
*/
public void queryByHQL02() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); // String hql = "select c from Children c";
String hql = "select c from Children c order by cid desc";
Query query = session.createQuery(hql);
List<Children> list = query.list(); for (Children children : list) {
System.out.println(children);
} tx.commit();
}

条件查询

参数绑定

  • 位置绑定

    String hql = "select c from Children c where cid<? and cname like ?";
    Query query = session.createQuery(hql);
    query.setParameter(0, 20L);
    query.setParameter(1, "%张%");
    • hql中参数以"?"代替
    • 索引从0开始
  • 名称绑定
    String hql = "select c from Children c where cid<:aaa and cname like :bbb";
    Query query = session.createQuery(hql);
    query.setParameter("aaa", 20L);
    query.setParameter("bbb", "%张%");
    • hql中参数以 ":自定义名称"的形式代替
    • 不使用索引,使用(名称,值)的形式
@Test
/**
* HQL条件查询
*/
public void queryByHQL03() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); /*//一个条件(位置绑定)
String hql = "select c from Children c where cid<?";
Query query = session.createQuery(hql);
query.setInteger(0, 3);*/ //多个条件(位置绑定)
/*String hql = "select c from Children c where cid<? and cname like ?";
Query query = session.createQuery(hql);
query.setParameter(0, 20L);
query.setParameter(1, "%张%");*/ //多个条件(名称绑定)
String hql = "select c from Children c where cid<:aaa and cname like :bbb";
Query query = session.createQuery(hql);
query.setParameter("aaa", 20L);
query.setParameter("bbb", "%张%"); List<Children> list = query.list(); for (Children children : list) {
System.out.println(children);
} tx.commit();
}

投影查询

查询表中部分字段

方式一:返回Object[ ]

@Test
/**
* HQL简单查询
*/
public void queryByHQL() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Query query = session.createQuery("select cname,sex from Children");
List<Object[]> list = query.list(); for (Object[] objs : list) {
System.out.println(Arrays.toString(objs));
}
tx.commit();
}

方式二:返回实体类对象

实体类

  • 添加无参构造方法
  • 添加有参构造方法(构造方法参数是你所要查询的属性)
package com.qf.entity;

public class Children {

	private Long cid;
private String cname;
private Character sex;
private Parent p; public Children(String cname, Character sex) {
super();
this.cname = cname;
this.sex = sex;
} public Children() {
super();
} ......
}

测试方法

@Test
/**
* HQL简单查询
*/
public void queryByHQL() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Query query = session.createQuery("select new Children(cname,sex) from Children");
List<Children> list = query.list(); for (Children children : list) {
System.out.println(children);
}
tx.commit();
}

分页查询

  • query.setFirstResult(int start):从第几条记录开始查询
  • query.setMaxResults(int num):本页一共查询多少条记录
@Test
public void query() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); String sql = "from Children";
Query query = session.createQuery(sql);
query.setFirstResult(2);
query.setMaxResults(3);
List<Children> list = query.list();
for (Children c : list) {
System.out.println(c);
} tx.commit();
}

分组查询

max()、min()、count()、sum()、avg()

Object obj = query.uniqueResult():返回唯一结果

@Test
/**
* HQL简单查询
*/
public void queryByHQL() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Query query = session.createQuery("select pid,pname,count(*) from Parent group by pid"); List<Object[]> list = query.list(); for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
} tx.commit();
}

HQL查询(多表)

内连接查询

正常的内连接sql:select * from Children c inner join Parent p

HQL:"from Children c inner join c.p "

  • 其中c.p是Children类的Parent属性变量p
  • 返回的是对象数组
package com.qf.entity;

public class Children {

	private Long cid;
private String cname;
private Character sex;
private Parent p;
....
}
@Test
/**
* HQL简单查询
*/
public void queryByHQL() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Query query = session.createQuery("from Children c inner join c.p "); List<Object[]> list = query.list(); for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
} tx.commit();
}

------------------------------console-------------------------------

[Children [cid=1, cname=张三8, sex=1, p=Parent [pid=1, pname=老张, age=45]], Parent [pid=1, pname=老张, age=45]]
[Children [cid=2, cname=张三0, sex=0, p=Parent [pid=1, pname=老张, age=45]], Parent [pid=1, pname=老张, age=45]]
[Children [cid=3, cname=张三2, sex=1, p=Parent [pid=1, pname=老张, age=45]], Parent [pid=1, pname=老张, age=45]]
...............
[Children [cid=28, cname=王五0, sex=0, p=Parent [pid=3, pname=老王, age=43]], Parent [pid=3, pname=老王, age=43]]
[Children [cid=29, cname=王五8, sex=0, p=Parent [pid=3, pname=老王, age=43]], Parent [pid=3, pname=老王, age=43]]
[Children [cid=30, cname=王五6, sex=1, p=Parent [pid=3, pname=老王, age=43]], Parent [pid=3, pname=老王, age=43]]

迫切内连接

Query query = session.createQuery("from Children c inner join fetch c.p ");

  • 普通内连接HQL的inner join后加上fetch即可
  • 效果:返回的是内连接的左边对象(该例中Parent作为Children属性)
@Test
/**
* HQL简单查询
*/
public void queryByHQL() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction(); Query query = session.createQuery("from Children c inner join fetch c.p "); List<Children> list = query.list(); for (Children c : list) {
System.out.println(c);
} tx.commit();
}

------------------------------console-------------------------------

Children [cid=1, cname=张三8, sex=1, p=Parent [pid=1, pname=老张, age=45]]
Children [cid=2, cname=张三0, sex=0, p=Parent [pid=1, pname=老张, age=45]]
Children [cid=3, cname=张三2, sex=1, p=Parent [pid=1, pname=老张, age=45]]
....................
Children [cid=28, cname=王五0, sex=0, p=Parent [pid=3, pname=老王, age=43]]
Children [cid=29, cname=王五8, sex=0, p=Parent [pid=3, pname=老王, age=43]]
Children [cid=30, cname=王五6, sex=1, p=Parent [pid=3, pname=老王, age=43]]

左外连接、右外连接(没有迫切右外连接)以及迫切左外连接使用也类似

最新文章

  1. spring 学习之 bean 的注入方式 property和constructor-arg的使用方式
  2. Docker - Docker基础命令及使用
  3. Effective C++ -----条款44:将与参数无关的代码抽离templates
  4. Java基础之扩展GUI——使用字体对话框(Sketcher 5 displaying a font dialog)
  5. DVR分布式路由
  6. PHP学习(三)----面向对象
  7. C++ string类取字符串的左右子串(以特定子串为分界限)
  8. uitableview 关于键盘挡住输入框解决方法
  9. executssql 函数的每一句代码的意思
  10. Java多线程中的单例模式
  11. django favicon配置
  12. MapReduce执行流程及程序编写
  13. JS中的事件以及DOM 操作
  14. Android开发之漫漫长途 XVI——ListView与RecyclerView项目实战
  15. 2种不同方式实现背景图里加入文字的简单CSS样式
  16. 研发团队如何写好API接口文档
  17. Html中video的属性和方法大全
  18. foreman源NO_PUBKEY 6F8600B9563278F6
  19. C++STL 预定义函数对象和函数适配器
  20. [Deepin 15] 安装 Java 8、Git、Firefox、SafeEyes(定时提醒休息工具)

热门文章

  1. Linux下svn回滚
  2. JVM分为哪些区,每一个区干嘛的?
  3. [SCOI2003]字符串折叠(区间dp)
  4. wireshark 抓包加密
  5. React Native框架如何白盒测试-HIPPY接口测试架构篇
  6. [BZOJ2341][Shoi2011]双倍回文 manacher+std::set
  7. 线程中的sleep()、join()、yield()方法有什么区别?
  8. cmd美化
  9. 如何通过Dataphin构建数据中台新增100万用户?
  10. Spring学习总结(2)- AOP