以雙向一對多關聯的 Department 與 Employee 為例,展示常用 HQL 技巧。
@Test
public void testHql() {
Department dept = new Department(); dept.setDeptId(7);
List<Employee> list = session.createQuery(
"FROM Employee e WHERE e.empName LIKE ? AND e.empId > ? AND e.dept = ? ORDER BY e.empId DESC")
.setString(0, "%b%").setInteger(1, 3).setEntity(2, dept).list();
// 輸出結果...
}
說明:支援位置參數(從 0 起)、鏈式呼叫、setEntity 僅需 ID、ORDER BY 排序。
@Test
public void testHqlNamed() {
List<Employee> list = session.createQuery(
"FROM Employee e WHERE e.empName LIKE :name AND e.empId > :id AND e.dept = ?")
.setString("name", "%a%").setInteger("id", 1).list();
}
Object[]:SELECT empName, empId FROM Employee ...SELECT NEW Employee(empId, empName) FROM Employee ... 需實體提供對應建構子。session.createQuery("FROM Employee")
.setFirstResult((pageNo - 1) * pageSize)
.setMaxResults(pageSize).list();
session.getNamedQuery("findAllEmployees")
.setFirstResult(...).setMaxResults(...).list();
SELECT dept.deptName, MIN(salary), MAX(salary) FROM Employee GROUP BY dept HAVING MIN(salary) > :salary
LEFT JOIN FETCH:一次查詢關聯集合並初始化,忽略映射檔策略,返回實體列表(可能重複,可用 DISTINCT 或 Set 去重)。LEFT JOIN:返回 Object[],關聯集合初始化時機遵循映射檔策略(預設 lazy)。fetch="join",必須在 HQL 顯式指定 FETCH。完全面向物件風格,適合動態組裝條件。
Criteria criteria = session.createCriteria(Employee.class);
criteria.add(Restrictions.like("empName", "a", MatchMode.ANYWHERE));
criteria.add(Restrictions.gt("salary", 1000F));
criteria.addOrder(Order.desc("salary"));
Conjunction and = Restrictions.conjunction();
and.add(Restrictions.like("empName", "a", MatchMode.ANYWHERE));
and.add(Restrictions.eq("dept", dept));
Disjunction or = Restrictions.disjunction();
or.add(Restrictions.gt("salary", 1000F));
or.add(Restrictions.lt("salary", 20000F));
criteria.add(and).add(or);
criteria.setFirstResult(...).setMaxResults(...).list();
criteria.setProjection(Projections.max("salary"));
String max = criteria.uniqueResult().toString();
session.createSQLQuery("SELECT emp_name FROM employee WHERE emp_id = ?")
.setEntity(0, employee).uniqueResult();
session.createQuery("DELETE FROM Employee WHERE empId = ?")
.setInteger(0, 13).executeUpdate();
createQuery、createCriteria、createSQLQuery。