您的位置:首页 > 其它

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语法

@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);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息