第6章深入使用Hibernate 6.6 SQL查询
来源:互联网 发布:网络机顶盒免费vip软件 编辑:程序博客网 时间:2024/06/05 04:03
6.6 SQL查询
如果是一个新的应用,通常不要使用SQL查询。
SQL查询是通过SQLQuery接口来表示的。有如下方法:
*setFirstResult():设置返回结果集的起始点
*setMaxResult():设置查询获取的最大记录数
*list():返回查询到的结果集
*addEntity():将查询到的记录与特定的实体关联
*addScalar():将查询的记录关联成标量值
执行SQL查询的步骤如下:
1)获取Hibernate Session对象
2)编写SQL语句
3)以SQL语句作为参数,调用Session的createSQLQuery方法创建查询对象。
4)调用SQLQuery对象的addScalar()或addEntity()方法将选出的结果与标量值或实体进行关联,分别用于进行标量查询或实体查询
5)如果SQL语句包含参数,则调用Query的setXXX方法为参数赋值
6)调用Query的list方法返回查询的结果集
6.6.1 标量查询
通过addScalar()方法返回指定列和指定列的类型
session.createSQLQuery("select * from student_inf")
.addScalar("name",StandardBasicTypes.STRING)
.list();
例子:
//执行标量查询public void scalarQuery(){//打开Session和事务Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();String sqlString = "select stu.* from student_inf as stu";List l = session.createSQLQuery(sqlString)//指定查询name和student_id两个数据列.addScalar("name" , StandardBasicTypes.STRING).addScalar("student_id" , StandardBasicTypes.INTEGER)//返回标量值列表.list();for (Iterator it = l.iterator(); it.hasNext() ; ){//每个集合元素都是一个数组,数组元素是name、student_id两列值Object[] row = (Object[])it.next();System.out.println(row[0] + "\t" + row[1]);}tx.commit();HibernateUtil.closeSession();}
6.6.2 实体查询
将查询结果转化为实体,可以使用SQLQuery提供的多个重载的addEntity()方法。
//执行实体SQL查询public void entityQuery(){//打开Session和事务Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();String sqlString = "select * from enrolment_inf where year=:year";List l = session.createSQLQuery(sqlString)//指定将查询的记录行转换成Student实体.addEntity(Enrolment.class)//为SQL字符串的参数设置值.setInteger("year" , 2005).list();for (Iterator it = l.iterator(); it.hasNext() ; ){//每个集合元素都是一个Enrolment对象Enrolment e = (Enrolment)it.next();System.out.println(e.getStudent().getName() + "\t" + e.getCourse().getName());}tx.commit();HibernateUtil.closeSession();}SQL语句可以选出多个数据表的数据,Hibernate也同样支持将查询结果转换成多个实体:
//执行返回多个实体的SQL查询public void multiEntityQuery(){//打开Session和事务Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();String sqlString = "select s.*,e.*,c.* "+ "from student_inf s,enrolment_inf e,course_inf c "+ "where s.student_id = e.student_id "+ "and e.course_code = c.course_code";List l = session.createSQLQuery(sqlString)//指定将查询的记录行转换成Student实体.addEntity("s", Student.class).addEntity("e", Enrolment.class).addEntity("c", Course.class).list();//提交事务,关闭Sessiontx.commit();HibernateUtil.closeSession();//因为数据已经全部被选出,故程序可以遍历列表中的数据for (Iterator it = l.iterator(); it.hasNext() ; ){//每个集合元素都是Student、Enrolment//和Course所组成的数组Object[] objs = (Object[])it.next();Student s = (Student)objs[0];Enrolment e = (Enrolment)objs[1];Course c = (Course)objs[2];System.out.println(s.getName() + "\t" + e.getYear() + "\t" + e.getSemester()+ "\t" + c.getName());}}不仅如此,Hibernate还可将查询的结果转化为非持久化实体。
Query接口提供了一个setResultTransformer()方法,该方法可接受一个Transformers对象,通过使用该对象即可把查询到的结果集转化成JavaBean集。
//执行返回普通JavaBean的SQL查询public void beanQuery(){//打开Session和事务Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();String sqlString = "select s.name stuName, c.name courseName "+ "from student_inf s,enrolment_inf e,course_inf c "+ "where s.student_id = e.student_id "+ "and e.course_code = c.course_code ";List l = session.createSQLQuery(sqlString)//指定将查询的记录行转换成StudentCourse对象.setResultTransformer(Transformers.aliasToBean(StudentCourse.class)).list();//提交事务,关闭Sessiontx.commit();HibernateUtil.closeSession();//因为数据已经全部被选出,故程序可以遍历列表中的数据for (Iterator it = l.iterator(); it.hasNext() ; ){//每个集合元素都是StudentCourse对象StudentCourse sc = (StudentCourse)it.next();System.out.println(sc.getStuName() + "\t" + sc.getCourseName());}}
6.6.3 处理关联和继承
将关联实体转化成查询结果的方法是SQLQuery addJoin(String alias,String path),该方法第一个参数是转换后的实体名,第二个参数是待转换的实体属性。
//使用关联的原生SQL查询public void joinQuery(){//打开Session和事务Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();String sqlString = "select s.* , e.* from student_inf s , "+ "enrolment_inf e where s.student_id=e.student_id";List l = session.createSQLQuery(sqlString).addEntity("s", Student.class).addJoin("e" , "s.enrolments").list();//提交事务,关闭Sessiontx.commit();HibernateUtil.closeSession();//因为数据已经全部被选出,故程序可以遍历列表中的数据for (Iterator it = l.iterator(); it.hasNext() ; ){//每个集合元素都是Student、Enrolment组成的数组Object[] objs = (Object[])it.next();Student s = (Student)objs[0];Enrolment e = (Enrolment)objs[1];System.out.println(s.getName() + "\t" + e.getYear());}}
6.6.4 命名SQL查询
可以将SQL语句不放在程序中,而是放在配置文件中。Hibernate使用<sql-query.../>元素来配置命名SQL查询,配置<sql-query.../>元素有一个必填的name属性,该属性用于指定该命名SQL查询的名称。包含一个或多个如下子元素:
*<return.../>:将查询结果转换为持久化实体
*<return-join.../>:预加载持久化实体的关联实体
*<return-scalar.../>:将查询的数据列转换成标量值
配置一个SQL查询片段:
<!-- 指定SQL查询的名称为queryTest --><sql-query name="queryTest"><!-- 将s别名转换成Student实体 --><return alias="s" class="Student"/><!-- 将e别名转换成Enrolment实体 --><return alias="e" class="Enrolment"/><!-- 预初始化e的course属性(关联实体) --><return-join alias="c" property="e.course"/><!-- 指定将student表的name列作为标量值返回 --><return-scalar column="s.name" type="string"/>select s.*,e.*,c.* from student_inf s,enrolment_inf e,course_inf c where s.student_id = e.student_id and e.course_code = c.course_codeand e.year=:targetYear</sql-query>使用session的getNamedQuery即可获取指定命名SQL查询。
//执行命名SQL查询private void query(){//打开Session和事务Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();//调用命名查询,直接返回结果List l = session.getNamedQuery("queryTest").setInteger("targetYear" , 2005).list();tx.commit();HibernateUtil.closeSession();//遍历结果集for(Iterator it = l.iterator(); it.hasNext() ;){//每个集合元素是Student、Enrolment//和stuName三个元素的数组Object[] objs = (Object[])it.next();Student s = (Student)objs[0];Enrolment e = (Enrolment)objs[1];String stuName = (String)objs[2];System.out.println(s.getName() + "\t"+ e.getYear() + "\t" + e.getSemester()+ "\t=" + e.getCourse().getName() + "=\t" + stuName);}}除此之外,Hibernate允许将结果集的映射信息放在<resultset.../>元素定义,这样就可以让多个命名查共用该结果集映射。通过为<sql-query.../>元素指定resultset-ref属性,就可让命名SQL查询使用一个已有的结果集映射了。
6.6.5 调用存储过程
Hibernate可以通过命名SQL查询来调用存储过程或函数。对于函数,该函数必须返回一个结果集;对于存储过程,该存储过程的第一个参数必须是传出参数,且其数据类型是结果集。
例子:
数据库中有一个存储过程:
create procedure select_all_student()
select *
from student_inf;
配置文件:
<!-- 定义一个调用存储过程的命名SQL查询 --><sql-query name="callProcedure" callable="true"><!-- 将查询结果转换成Student实体 --><return class="Student"><!-- 将查询的数据列转换成实体的属性 --><return-property name="studentNumber"column="student_id"/><return-property name="name" column="name"/></return>{call select_all_student()}</sql-query>需要增加callable="true",还需要使用<return-property.../>子元素将指定列转换成实体的属性。
//调用存储过程private void callProcedure(){//打开Session和事务Session session = HibernateUtil.currentSession();Transaction tx = session.beginTransaction();//调用命名查询,直接返回结果List l = session.getNamedQuery("callProcedure").list();tx.commit();HibernateUtil.closeSession();//遍历结果集for(Iterator it = l.iterator(); it.hasNext() ;){//每个集合元素是Student对象Student s = (Student)it.next();System.out.println(s.getName());}}
6.6.6 使用定制SQL
Hibernate允许在<class.../>元素以及系列映射集合的元素里使用<sql-insert.../>、<sql-delete.../>和<sql-update.../>等元素来指定定制SQL语句。如果我们希望使用使用存储过程来执行插入、更新、修改等操作,则只需为<sql-insert.../>、<sql-delete.../>和<sql-update.../>指定callable="true"即可。
0 0
- 第6章深入使用Hibernate 6.6 SQL查询
- 第6章 深入使用Hibernate 6.4 使用HQL查询
- 第6章深入使用Hibernate 6.5 条件查询
- 第6章深入使用Hibernate 6.9二级缓存和查询缓存
- 第6章深入使用Hibernate 6.2 继承映射
- 第6章 深入使用Hibernate 6.7 数据过滤
- 第6章 深入使用Hibernate 6.8事务控制
- 第6章深入使用Hibernate 6.10 事件机制
- hibernate使用sql查询
- hibernate 使用 sql 查询
- hibernate使用sql查询
- 第6章深入使用Hibernate 6.1Hibernate的关联映射
- 第6章深入使用Hibernate 6.3 Hibernate的批量处理
- Hibernate使用sql语句查询
- Hibernate使用sql语句查询
- Hibernate使用sql语句查询
- Hibernate使用sql语句查询
- Hibernate使用sql语句查询
- JSONKIT isa错误的解决办法
- C#程序实现闰年的判断
- comparator接口与Comparable接口的区别
- 自考第三波+GCT考试总结
- android webview 底层实现的逻辑
- 第6章深入使用Hibernate 6.6 SQL查询
- Django+session会话
- 项目3(4)
- php 设置报错等级
- 模拟赛
- HDU-1087(Super Jumping! Jumping! Jumping!)
- java学习之路_chapter15_输入/输出之文件过滤器
- 第八周 项目2-建立链串的算法库
- Linux进程管理