hibernate的三種查詢方式

糖goblin 發表於 2021-04-21

hibernate的三種查詢方式

hibernate的查詢方式常見的主要分為三種: HQL, QBC(命名查詢), 以及使用原生SQL查詢(SqlQuery);

1、HQL查詢

1.1、SQL概述

HQLHibernate Query Language的縮寫,提供更加豐富靈活、更為強大的查詢能力;HQL接近SQL`語句查詢語法。

完整的HQL語句形式如下:
select | update | deletefromwheregroup byhavingorder byasc|desc

其中的updatedeleteHibernate3中所新新增的功能,可見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
  1. 沒有on語句
  2. 能被連線到查詢中的必須是主查詢物件的子屬性
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查詢最重要的三個類:

  1. Restrictions 條件限制
  2. Projections 列設射
  3. 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());