1. 程式人生 > >HQL連接查詢和註解

HQL連接查詢和註解

lis [1] 所有 比較運算 檢索 類型 empty string hql

1.連接查詢
迫切內連接: 特點是:不返回左表不滿足條件
   eg:FROM Department d INNER JOIN FETCH d.emps
    • INNER JOIN FETCH 關鍵字表示迫切內連接, 也可以省略 INNER 關鍵字
    • list() 方法返回的集合中存放Department對象的引用, 每個Department對象的 Employee 集合都被初始化, 存放所有關聯的 Employee 對象
內連接:
   eg:FROM Department d INNER JOIN d.emps
    • INNER JOIN 關鍵字表示內連接, 也可以省略 INNER 關鍵字
    • list() 方法的集合中存放的每個元素對應查詢結果的一條記錄, 每個元素都是對象數組類型, 如果希望 list() 方法的返回的集合僅包含 Department 對象, 可以在 HQL 查詢語句中使用 SELECT 關鍵字
迫切左外連接: 特點是:如果左表有不滿足條件的,也返回左表不滿足條件
    • LEFT JOIN FETCH 關鍵字表示迫切左外連接檢索策略.
    • list() 方法返回的集合中存放實體對象的引用, 每個 Department 對象關聯的 Employee 集合都被初始化,存放所有關聯的 Employee 的實體對象.

2.. 查詢結果中可能會包含重復元素, 可以通過一個 HashSet 來過濾重復元素 去重:
方法一:使用 distinct
String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN FETCH d.emps ";
Query query = session.createQuery(hql);

List<Department> depts = query.list();
System.out.println(depts.size());
方法二
String hql = "FROM Department d LEFT JOIN FETCH d.emps ";
Query query = session.createQuery(hql);
List<Department> depts = query.list();

depts = new ArrayList<>(new LinkedHashSet(depts));
System.out.println(depts.size());
for(Department dept:depts){
System.out.println(dept.getName() + "--" + dept.getEmps().size() );
}
左外連接:
1. LEFT JOIN 關鍵字表示左外連接查詢.
2. list() 方法返回的集合中存放的是對象數組類型
3. 根據配置文件來決定 Employee 集合的檢索策略.
4. 如果希望 list() 方法返回的集合中僅包含 Department 對象, 可以在HQL 查詢語句中使用 SELECT 關鍵字
這樣的語句查詢的結果有重復:
String hql = "FROM Department d LEFT JOIN d.emps";
Query query = session.createQuery(hql);

List<Object[]> results = query.list();
System.out.println(results.size());
去重:
僅能使用 distinct 的方法去除重復
String hql = "SELECT DISTINCT d FROM Department d LEFT JOIN d.emps";
Query query = session.createQuery(hql);

List<Department> depts = query.list();
System.out.println(depts.size());
for(Department dept:depts){
System.out.println(dept.getName() + dept.getEmps().size());
}
註意:
如果要查詢表中所有字段的信息,那麽hql語句中不使用
String hql = "from Book" <==>
String hql = "select bookId,bookName,author,price from Book";
String hql = "select bookName,author from Book";
如果只查詢某一列的值,那麽集合中對應的就不再是一個對象了
List<String> list = query.list(hql);
如果查詢某幾列的數據,那麽集合中對應的每個元素對應的就是一個數組相同數據類型使用String[] 或其他數據類型數組,不同數據類型使用Object[], 模糊查詢 排序都不變,查詢不需要發起事務,修改需要發起事務query.executeUpdate(); 可以自行修改刪除
HQL分頁
query.setFirstResult(); 設置當前頁起始行索引
query.setMaxResults(); 設置每頁記錄條數
具體查詢一條數據可以使用uniqueResult();
Book book = (Book)uniqueResult();
2.2.Criteria查詢:
Criteria查詢示例:
1.獲得Session
Session session = HibernateSessionFactory.getSession();
2.通過session創建Criteria對象
Criteria criteria = session.createCriteria(Class arg);
eg:Criteria criteria = session.createCriteria(Book.class);
Criteria criteria = session.createCriteria(String arg);
eg:Criteria criteria = session.createCriteria("com.entity.Book");
3.通過Criteria對象執行查詢
List<Book> list = criteria.list();
4.關閉Session
session.close(); 條件查詢
//比較運算
cri.add(Restrictions.eq("bookName","sql")); //eq等於 le小於等於 lt小於 ge大於等於 gt大於
//模糊查詢
cri.add(Restrictions.like("bookName","%a%"));
//範圍運算
技術分享Restrictions.in

( )
//邏輯運算
Restrictions.and( )
cri.add(Restrictions.or(Restrictions.eq("bookName","sql"),Expression.eq("price",50)));
criteria.addOrder(Order.desc("price"));
集合運算
Restrictions.isEmpty( )
排序
List<Emp> list = session.createCriteria(Emp.class)
.add(技術分享Restrictions.gt

("salary", 4000D))
.addOrder(Order.asc("salary"))
.addOrder(Order.desc("empNo")).list();
分頁:
criteria.setFirstResult(); 設置當前頁起始行索引
criteria.setMaxResults(); 設置每頁記錄條數
List<Emp> list = session.createCriteria(Emp.class)
.add(Restrictions.isNotNull("salary"))
.addOrder(Order.desc("salary"))
.setFirstResult(0)
.setMaxResults(2).list();
查詢唯一對象:
Emp emp = (Emp) session.createCriteria(Emp.class)
.add(Restrictions.isNotNull("salary"))
.addOrder(Order.desc("salary"))
.setMaxResults(1)
.uniqueResult();
關聯:
方式一:
List<Emp> list = session.createCriteria(Emp.class)
.add(Restrictions.ilike("empName", "a", MatchMode.ANYWHERE))
.createCriteria("dept")
.add(Restrictions.eq("deptName", "財務部").ignoreCase()) .list();
方式二:
List<Emp> list = session.createCriteria(Emp.class, "e")
.createAlias("dept", "d")
.add(Restrictions.ilike("e.empName", "a",MatchMode.ANYWHERE))
.add(Restrictions.eq("d.deptName", "財務部").ignoreCase()).list();
投影:
List<String> list = session.createCriteria(Dept.class).setProjection(Property.forName("deptName")).list();
List<Object[]> list = session.createCriteria(Emp.class)
.setProjection(Projections.projectionList().add(Property.forName("empName")).add(Property.forName("hiredate"))).list();
分組、聚合函數:
List<Object[]> list = session.createCriteria(Emp.class, "e").createAlias("e.dept", "d")
.setProjection(Projections.projectionList().add(Projections.groupProperty("d.deptName"))
.add(Projections.avg("e.salary")).add(Projections.max("e.salary")).add(Projections.min("e.salary"))).list();
for (Object[] obj : list) {
System.out.println(obj[0] + ","+obj[1]+ ","+obj[2]+ ","+obj[3]);
}
DetachedCriteria查詢:
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Emp.class, "e").createAlias("e.dept", "d")
.add(Restrictions.eq("d.deptName", "財務部").ignoreCase()).add(Restrictions.ilike("e.empName", "a",MatchMode.ANYWHERE));
List<Emp> list = detachedCriteria.getExecutableCriteria(session).list();
3. 註解   Hibernate 提供了註解進行對象--關系映射,它可以代替大量的hbm.xml 文件,使得Hibernate 程序的文件的數量大大精簡。使用註解,可以直接映射信息定義在持久化類中,而無需編寫對應的*.hbm.xml文件。   使用hibernate 註解的步驟:
    • 使用註解配置持久化類及對象關聯關系
    • 在Hibernate 配置文件(hibernate.cfg.xml) 中聲明持久化類

HQL連接查詢和註解