hibernate的三種查詢方式
目錄
hibernate的查詢方式常見的主要分為三種: HQL, QBC(命名查詢), 以及使用原生SQL查詢(SqlQuery);
1、HQL查詢
1.1、SQL概述
HQL是
Hibernate Query Language的縮寫,提供更加豐富靈活、更為強大的查詢能力;
HQL接近
SQL`語句查詢語法。
完整的HQL
語句形式如下:
select
| update
| delete
… from
… where
… group by
… having
… order by
… asc
|desc
其中的update
、delete
為Hibernate3
中所新新增的功能,可見HQL
查詢非常類似於標準SQL
查詢。HQL
查詢在整個Hibernate
實體操作體系中佔核心地位。
String hql = "HQL語句";
Query query = session.createQuery(hql);
List list = query.list(); //查詢得到多個實體物件集合
Object result = query.uniqueResult(); //查詢得到一個實體物件
int x = query.executeUpdate(); //執行update或delete語句,返回資料表受影響行數
1.2、實體查詢
查詢過程中表名使用類名,列名使用屬性名,類名和屬性名稱區分大小寫
String hql="from Users";//from 實體類型別名稱
Query query = session.createQuery(hql);
List<Users> list = query.list();
for (Users user : list) {
System.out.println(user);
}
1.3、帶where的查詢
Query query = session.createQuery("from Users where uid=3");
Users user = (Users) query.uniqueResult();//uniqueResult 單一物件
System.out.println(user);
Query query = session.createQuery("from Users where uid>5");
List<Users> list = query.list();
for (Users user : list) {
System.out.println(user);
}
1.3、屬性查詢
查詢部分屬性
String hql="select u.uid,u.uname,u.upwd from Users u where u.uname='張三'";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
String hql="select new Users(u.uname,u.upwd) from Users u where u.uname='張三'";
Query query = session.createQuery(hql);
List<Users> list = query.list();
for (Users user : list) {
System.out.println(user);
}
1.4、實體的更新和刪除
從hibernate 3版本開始才支援
//更新
String hql="update Users set uname='王五',upwd='321' where uid=3";
int res = session.createQuery(hql).executeUpdate();
//刪除
String hql="delete from Users where uid=3";
int res = session.createQuery(hql).executeUpdate();
/*
返回值結果:
正整數:表受影響的行資料
0: 語句正常執行,但沒有行受影響
負整數:通常是-1,執行HQL語句是一條查詢語句
*/
HQL語句不能做新增
1.5、分組與排序
-
排序
處理方式和SQL語句中的排序是一樣的
String hql="from Users order by uid"; Query query = session.createQuery(hql); List<Users> list = query.list(); for (Users user : list) { System.out.println(user); }
order by語句只能出現在語句的最後位置
-
分組
處理方式和SQL語句中分組查詢相同
分組語句需要處理篩選,只能使用having語句,而不能使用where語句。
String hql = "select e.dept.deptno, count(e) from Emp e group by dept.deptno"; String hql = "select e.dept.deptno, count(e) from Emp e group by dept.deptno having count(e)>=5";
1.6、引數繫結
-
使用佔位引數
String hql="from Users where uid=? or uname=?"; Query query = session.createQuery(hql); //索引從0開始 query.setInteger(0, 3);//query.setParameter(0, 3); query.setString(1, "張三");//query.setParameter(1, "張三"); List<Users> list = query.list(); for (Users user : list) { System.out.println(user); }
-
使用引數名稱
String hql = "from Users where uid=:no1 or uid=:no2"; Query query = session.createQuery(hql); query.setInteger("no1", 1); query.setInteger("no2", 3); //....
-
可以使用點位引數和名稱引數混合使用
String hql = "from User where uid=? or uid=:no2"; Query query = session.createQuery(hql); query.setInteger(0, 7788); query.setInteger("no2", 7566); //.... //使用點位引數和名稱引數混合使用,所有點位引數必須放在前面,一旦有名稱引數出現,其後將不能再出現佔位引數
1.7、連線查詢
--SQL語句:查詢員工姓名、薪資、部門名稱
SELECT ENAME,SAL,DNAME
FROM EMP e JOIN DEPT d ON e.DEPTNO=d.DEPTNO
SELECT ENAME,SAL,DNAME FROM EMP,DEPT WHERE EMP.DEPTNO=DEPT.DEPTNO
- 沒有on語句
- 能被連線到查詢中的必須是主查詢物件的子屬性
String hql="SELECT e.ename, e.sal, e.dept.dname FROM Emp e";
//HQL連線查詢
String hql="SELECT e.ename, e.sal, d.dname FROM Emp e JOIN e.dept d";
String hql = "SELECT e FROM Emp e JOIN e.dept"; //JOIN將沒有意義
String hql = "FROM Emp e JOIN e.dept";
Query query = session.createQuery(hql);
List<Object[]> list = query.list();
//List集合中的陣列中會儲存兩個元素:
//0:主資料(Emp)
//1:從資料(Dept)
//查詢編號為7788的員工資訊,同時將對應的dept資訊和manager資訊查詢並儲存在對應的子屬性中
String hql = "FROM Emp e JOIN FETCH e.dept d JOIN FETCH e.manager m WHERE e.empno=7788";
Query query = session.createQuery(hql);
Emp emp = (Emp) query.uniqueResult();
System.out.println(emp);
System.out.println(emp.getManager());
System.out.println(emp.getDept());
1.8、分頁
String hql = "from Users";
Query query = session.createQuery(hql);
query.setFirstResult(0);
query.setMaxResults(2);
2、QBC查詢
QBC(Query By Criteria)查詢就是通過使用Hibernate提供的Query By Criteria API來查詢物件,這種API封裝了SQL語句的動態拼裝,對查詢提供了更加物件導向的功能介面。
QBC查詢最重要的三個類:
- Restrictions 條件限制
- Projections 列設射
- Order 排序
2.1、查詢實現
Criteria criteria = session.createCriteria(Users.class);
//session.createCriteria("entity.Users");
//session.createCriteria(Users.class, "別名");
List<Dept> list = criteria.list();
//查詢單行結果(如果結果有兩行或更多,會報錯)
Object uniqueResult = criteria.uniqueResult();
2.2、Projections 列投射
語法:
//查詢uname屬性
Criteria criteria = session.createCriteria(Users.class);
PropertyProjection property = Projections.property("name");
criteria.setProjection(property);
List<Object> result = criteria.list();
//查詢uname, upwd屬性
Criteria criteria = session.createCriteria(Users.class);
//1.建立投射列表
ProjectionList projectionList = Projections.projectionList();
//2.向投射列表中新增列投射
PropertyProjection property1 = Projections.property("uname");
PropertyProjection property2 = Projections.property("upwd");
projectionList.add(property1).add(property2);
//3.將投射列表設定到準則中
criteria.setProjection(projectionList);
List<Object> result = criteria.list();
返回值型別 | 方法名稱 | 描述 |
---|---|---|
PropertyProjection | Projections.property | 指定某屬性 |
AggregateProjection | Projections.avg | 求平均值 |
CountProjection | Projections.count | 統計某屬性的數量 |
CountProjection | Projections.countDistinct | 統計某屬性不同值的數量 |
PropertyProjection | Projections.groupProperty | 指定某個屬性為分組屬性 |
AggregateProjection | Projections.max | 求最大值 |
AggregateProjection | Projections.min | 求最小值 |
ProjectionList | Projections.projectionList | 建立一個ProjectionList物件 |
Projection | Projections.rowCount | 查詢結果集中的記錄條數 |
AggregateProjection | Projections.sum | 求某屬性的合計 |
2.3、Restrictions 條件限制
語法:
Criteria criteria = session.createCriteria(Users.class);
Criterion notNull = Restrictions.isNotNull("comm");
criteria.add(notNull); //新增一個條件(如果新增了多個條件,預設條件之間使用and連線)
List<Users> list = criteria.list();
返回值型別 | 方法名稱 | 描述 |
---|---|---|
SimpleExpression | Restrictions.eq | 等於(equal) |
Criterion | Restrictions.allEq | 使用Map,Key/Valu進行多個等於的比對 |
SimpleExpression | Restrictions.gt | 大於(great than) |
SimpleExpression | Restrictions.ge | 大於等於(great than or equal) |
SimpleExpression | Restrictions.lt | 小於(less than) |
SimpleExpression | Restrictions.le | 小於等於(less than or equal) |
Criterion | Restrictions.between | 對應SQL的between |
SimpleExpression | Restrictions.like | 對應SQL的like |
Criterion | Restrictions.in | 對應SQL的in |
LogicalExpression | Restrictions.and | and關係 |
LogicalExpression | Restrictions.or | or關係 |
Criterion | Restrictions.isNull | 為空 |
Criterion | Restrictions.sqlRestriction | SQL限定查詢 |
Criterion | Restrictions.not | 取反 |
2.3、Order排序
語法:
Criteria criteria = session.createCriteria(Dept.class);
criteria.addOrder(Order.asc("name"))
.addOrder(Order.desc("loc"));
//SELECT * FROM DEPT ORDER BY name ASC, loc DESC
返回值型別 | 方法名稱 | 描述 |
---|---|---|
Order | Order.asc(String propertyName) | 升序 |
Order | Order.desc(String propertyName) | 降序 |
2.4、分頁查詢
Criteria criteria = session.createCriteria(Dept.class);
int pageNum = 2, pageSize = 5;
criteria.setFirstResult((pageNum-1)*pageSize); //查詢起始行下標
criteria.setMaxResults(pageSize); //查詢的最大行數
List list = criteria.list();
//setFirstResult方法和setMaxResults方法同樣可以在SQLQuery及Query型別上使用
3、原生SQL查詢
1、查詢
String sql = "select uid,uname,upwd from _users";
List list = session.createSQLQuery(sql).list();
for(Object obj : list){
System.out.println(obj);
}
2、 addEntity()
String sql = "select uid,uname,upwd from _users";
// addEntity()可以告訴Hibernate你想要封裝成物件的型別,然後自動為你封裝
SQLQuery query = session.createSQLQuery(sql).addEntity(Users.class);
List<User> list = query.list();
for(Users user : list){
System.out.println(user.getUname());
}
3、 uniqueResult
String sql = "select uid,uname,upwd from _users where uid = 2";
SQLQuery query = session.createSQLQuery(sql).addEntity(Users.class);
Users user = (Users) query.uniqueResult();//返回單一物件
System.out.println(user.getUname());