溫故知新: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 "
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"
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查詢會忽略配置。
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 ");
+ "( 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
posted on 2015-01-21 14:13 都較瘦 閱讀(108) 評論(0) 編輯 收藏 所屬分類: ORMFramework