温故知新:hibernate_13_常用HQL

通过hibernate进行数据的查询,一般会采用HQL语句,HQL是将数据表对象化的查询语言,和SQL类似,但却是通过面向对象的方式去书写,更易于理解。写一个测试类,将一般情况下会用到的HQL写法记录下来。
  1 package demo;
  2 
  3 import java.util.List;
  4 
  5 import org.hibernate.Query;
  6 import org.hibernate.Session;
  7 import org.junit.Test;
  8 
  9 import domain.Classroom;
 10 import domain.ReportDto;
 11 import domain.Specialty;
 12 import domain.Student;
 13 import util.HibernateUtil;
 14 
 15 
 16 public class App 
 17 {
 18     
 19     @SuppressWarnings("unchecked")
 20     @Test
 21     public void hqltest01(){
 22         Session session = null;
 23         try {
 24             session = HibernateUtil.openSession();
 25             session.beginTransaction();
 26             //全查询
 27             Query q = session.createQuery("from Student");
 28             List<Student> ss = q.list();
 29             for (Student s : ss) {
 30                 System.out.println(s.getName());
 31             }
 32             
 33             System.err.println("=================================");
 34             
 35             //条件查询
 36             Query q1 = session.createQuery("from Student s where s.name like ?")
 37                     .setParameter(0, "%小%");
 38             //还可以基于参数名的方式,比如hql中为:name,则setParameter("name", "%小%")
 39             List<Student> sss = q1.list();
 40             for (Student s : sss) {
 41                 System.out.println(s.getName());
 42             }
 43             
 44             session.getTransaction().commit();
 45             
 46         } catch (Exception e) {
 47             if (session != null) {
 48                 session.getTransaction().rollback();
 49             }
 50         } finally{
 51             if (session != null) {
 52                 session.close();
 53             }
 54         }
 55     }
 56     
 57     @Test
 58     /**
 59      * 查询唯一结果
 60      */
 61     public void hqltest02(){
 62         Session session = null;
 63         try {
 64             session = HibernateUtil.openSession();
 65             session.beginTransaction();
 66             
 67             //查询记录的数量
 68             Query q = session.createQuery("select count(*) from Student");
 69             Long l = (Long) q.uniqueResult();
 70             System.out.println(l);
 71             
 72             //查询某个特定对象
 73             Query q1 = session.createQuery("from Student s where s.id = 1");
 74             Student s =  (Student) q1.uniqueResult();
 75             System.out.println(s.getName());
 76             session.getTransaction().commit();
 77             
 78         } catch (Exception e) {
 79             if (session != null) {
 80                 session.getTransaction().rollback();
 81             }
 82         } finally{
 83             if (session != null) {
 84                 session.close();
 85             }
 86         }
 87     }
 88     
 89     @SuppressWarnings("unchecked")
 90     @Test
 91     /**
 92      * 查询一个投影
 93      */
 94     public void hqltest03(){
 95         Session session = null;
 96         try {
 97             session = HibernateUtil.openSession();
 98             session.beginTransaction();
 99             
100             //查询记录的数量
101             Query q = session.createQuery("select s.grade,count(*) from Student s group by s.grade");
102             List<Object[]> objs = q.list();
103             for (Object[] obj : objs) {
104                 System.out.println(obj[0]+":"+obj[1]);
105             }
106             
107         } catch (Exception e) {
108             if (session != null) {
109                 session.getTransaction().rollback();
110             }
111         } finally{
112             if (session != null) {
113                 session.close();
114             }
115         }
116     }
117     
118     @SuppressWarnings("unchecked")
119     @Test
120     /**
121      * 基于导航对象进行,传统sql语句进行跨表查询时,需要进行连接
122      * hql提供了导航查询.
123      * *但是不建议使用导航查询,导航查询使用cross join进行查询,低效
124      */
125     public void hqltest04(){
126         Session session = null;
127         try {
128             session = HibernateUtil.openSession();
129             session.beginTransaction();
130             
131             //查询记录的数量
132             Query q = session.createQuery("from Student s where s.classroom.id = 1");
133             List<Student> ss = q.list();
134             for (Student s : ss) {
135                 System.out.println(s.getName());
136             }
137             
138         } catch (Exception e) {
139             if (session != null) {
140                 session.getTransaction().rollback();
141             }
142         } finally{
143             if (session != null) {
144                 session.close();
145             }
146         }
147     }
148     
149     @SuppressWarnings("unchecked")
150     @Test
151     /**
152      * 参数列表的设置
153      */
154     public void hqltest05(){
155         Session session = null;
156         try {
157             session = HibernateUtil.openSession();
158             session.beginTransaction();
159             
160             //查询记录的数量
161             Query q = session.createQuery("from Student s where s.classroom.id = ? and s.id in(:sids)");
162             List<Student> ss = q.setParameter(0, 1).setParameterList("sids", new Object[]{1,3}).list();
163             for (Student s : ss) {
164                 System.out.println(s.getName());
165             }
166             
167         } catch (Exception e) {
168             if (session != null) {
169                 session.getTransaction().rollback();
170             }
171         } finally{
172             if (session != null) {
173                 session.close();
174             }
175         }
176     }
177     
178     @SuppressWarnings("unchecked")
179     @Test
180     /**
181      * 内连接查询
182      */
183     public void hqltest06(){
184         Session session = null;
185         try {
186             session = HibernateUtil.openSession();
187             session.beginTransaction();
188             
189             //查询记录的数量
190             Query q = session.createQuery("select s from Student s join s.classroom cla where cla.id = 2");
191             List<Student> ss = q.list();
192             for (Student s : ss) {
193                 System.out.println(s.getName());
194             }
195             
196         } catch (Exception e) {
197             if (session != null) {
198                 session.getTransaction().rollback();
199             }
200         } finally{
201             if (session != null) {
202                 session.close();
203             }
204         }
205     }
206     
207     
208     @SuppressWarnings("unchecked")
209     @Test
210     /**
211      * 实现一个类似报表的查询
212      */
213     public void hqltest07(){
214         Session session = null;
215         try {
216             session = HibernateUtil.openSession();
217             session.beginTransaction();
218             
219             //查询记录的数量
220             Query q = session.createQuery("select stu.name,stu.grade,cla.name,sp.name from Student stu "
+ "left join stu.classroom cla left join stu.classroom.specialty sp ");
221             List<Object[]> objs = q.list();
222             for (Object[] s : objs) {
223                 System.out.println(s[0]+" -- "+ s[1]+" -- " + s[2] + " -- " +s[3] );
224             }
225             
226             //基本的查询会返回一个对象数组object[],但是如此一来,在控制层获取会很困难
227             //所以,就需要创建一个dto对象来存储这些查询出的数据
228             //此处的dto对象ReportDto,其实体类中必须包含ReportDto(String name, String grade, String claName, String spName)形式的构造函数,才能如下书写
229             Query q1 = session.createQuery("select new domain.ReportDto"
+ "(stu.name,stu.grade,cla.name,sp.name) from Student stu)" 
                                + "left join stu.classroom cla left join stu.classroom.specialty sp ");

230             List<ReportDto> rds = q1.list();
231             for (ReportDto rd : rds) {
232                 System.out.println(rd.getName()+" -- " +rd.getGrade()+" -- "+rd.getClaName()+" -- " + rd.getSpName());
233             }
234             
235         } catch (Exception e) {
236             e.printStackTrace();
237             if (session != null) {
238                 session.getTransaction().rollback();
239             }
240         } finally{
241             if (session != null) {
242                 session.close();
243             }
244         }
245     }
246 }
247 
说到HQL查询,就要提到关联对象间的延迟加载问题,hibernate中的抓取策略和延迟加载息息相关,基于XML配置类文件,通过XML的fetch配置可以自定义抓取策略,XML配置默认是select,也就是说,如果当前取得的对象中存在延迟加载对象,那么在取得延迟加载对象的时候,会通过select语句取得。如果配置为join,则会通过关联方式取得。对于使用HQL查询的对象无效,需要同过batch-size的设置,或者使用HQL的时候,在join关键后添加fetch关键字来抓取。基于注解的方式配置实体类,默认会通过关联join的方式取得。不论是注解的方式还是XML的方式去配置实体类,配置中的抓取策略只针对load的对象有效,HQL查询会忽略配置。

posted on 2015-01-21 14:13 都较瘦 阅读(98) 评论(0)  编辑  收藏 所属分类: ORMFramework


只有注册用户登录后才能发表评论。


网站导航:
 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

公告

博客定位:囿于目前的水平,博客定位在记录自己的学习心得和随手的练习

常用链接

留言簿

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜