首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Hibernate Criteria 查詢與註解映射全攻略:從基礎條件到動態查詢、投影、分頁實戰

     編輯:Java 綜合教學

Hibernate 五大檢索方式

  1. 導航對象圖
  2. OID 查詢 (get/load)
  3. HQL 查詢
  4. QBC (Criteria API):面向對象、類型安全、動態組裝
  5. 原生 SQL

Criteria 核心接口體系

  • Criteria:主查詢接口,繼承 CriteriaSpecification
  • Restrictions:條件構建工廠,返回 Criterion
  • Order:排序
  • Projections:投影/聚合

Criteria 接口結構

Criteria 核心方法

13 大實戰案例

1. 查詢所有

Criteria c = session.createCriteria(Dept.class);
List list = c.list();

2. 條件查詢

Criterion criterion = Restrictions.eq("dName", "開發部");
c.add(criterion);

3. 關聯查詢:查「開發部」所有員工

 list = session.createCriteria(Employee.class, "emp")
    .createAlias("dept", "d")
    .add(Restrictions.ilike("emp.ename", "a", MatchMode.ANYWHERE))
    .add(Restrictions.eq("d.dName", "開發部").ignoreCase())
    .list();

// 方式三:設置抓取模式 + 去重
List list = session.createCriteria(Dept.class, "d")
    .setFetchMode("emps", FetchMode.JOIN)
    .add(Restrictions.eq("d.loc", "北京").ignoreCase())
    .list();
new HashSet<>(list).forEach(d -> ...); // 過濾重複

4. 範圍查詢

List cities = Arrays.asList("bj", "sh");
c.add(Restrictions.in("empCity", cities));

5. 模糊匹配

c.add(Restrictions.ilike("empCity", "%b%")); // 不區分大小寫

6. 邏輯組合

Criterion c1 = Restrictions.eq("empCity", "bj");
Criterion c2 = Restrictions.like("empName", "號", MatchMode.ANYWHERE);
c.add(Restrictions.and(c1, c2));

7. 集合判空

c.add(Restrictions.isEmpty("emps")); // 查無員工部門

8. 動態查詢構建

Criteria c = session.createCriteria(Employee.class);
if (cond.getEname() != null) c.add(Restrictions.like("ename", cond.getEname(), MatchMode.EXACT));
if (cond.getEmpno() != null) c.add(Restrictions.eq("empno", cond.getEmpno()));
List list = c.list();

9. 排序

c.addOrder(Order.asc("empno")); // 或 desc

10. 分頁

// 總記錄數
Integer count = ((Long) session.createCriteria(Employee.class)
    .setProjection(Projections.count("empno")).uniqueResult()).intValue();

// 分頁查詢
int pageSize = 3, pageIndex = 2;
List list = session.createCriteria(Employee.class)
    .addOrder(Order.desc("empno"))
    .setFirstResult((pageIndex - 1) * pageSize)
    .setMaxResults(pageSize)
    .list();

11. DetachedCriteria 離線查詢

DetachedCriteria dc = DetachedCriteria.forClass(Emp.class);
dc.createAlias("dept", "d");
dc.add(Restrictions.eq("d.deptName", "開發部"));
List list = dc.getExecutableCriteria(session).list();

優勢:無需 Session 創建,可傳遞給 Service 層組裝條件。

12. 唯一結果

Employee emp = (Employee) session.createCriteria(Employee.class)
    .add(Restrictions.isNotNull("empno"))
    .addOrder(Order.desc("empno"))
    .setMaxResults(1) // 防 NonUniqueResultException
    .uniqueResult();

13. 投影查詢

 rows = c.setProjection(Projections.projectionList()
    .add(Property.forName("loc"))
    .add(Property.forName("dName"))).list();
for (Object[] row : rows) { System.out.println(row[0] + ", " + row[1]); }

Restrictions 常用方法速查

Restrictions 方法表


第二部分:Hibernate 註解映射

依賴與配置

  • Hibernate 3.x 需額外導入 hibernate-annotations.jar、ejb3-persistence.jar
  • Hibernate 4+ 已整合
  • 會話工廠:new AnnotationConfiguration().configure().buildSessionFactory()
  • hibernate.cfg.xml 中用 <mapping class="..."/> 註冊實體

核心註解速查

關聯映射實戰

一對一:身份證與學生

// 主控端 Student
@Entity @Table(name="MyStudent")
public class Student {
    @Id @GeneratedValue private Integer id;
    @OneToOne(cascade=CascadeType.ALL)
    @JoinColumn(name="cid") // 外鍵列在 Student 表
    private IdCard craid;
}

// 被控端 IdCard
@Entity @Table(name="IdCard")
public class IdCard {
    @Id @Column(length=18) private String cid;
    @OneToOne(mappedBy="craid") // 放棄維護權
    private Student stu;
}

一對多:部門與員工

@Entity @Table(name="Dept")
public class Dept {
    @Id @GeneratedValue private Integer deptNo;
    @OneToMany(mappedBy="dept")
    @LazyCollection(LazyCollectionOption.FALSE) // 關閉懶加載
    private Set emps = new HashSet<>();
}

@Entity @Table
public class Emp {
    @Id private Integer empId;
    @ManyToOne @JoinColumn(name="deptNo")
    private Dept dept;
}

多對多:員工與項目

@Entity @Table(name="YEmp")
public class Emp {
    @Id @GeneratedValue private Integer eid;
    @ManyToMany(cascade=CascadeType.ALL)
    @JoinTable(name="YEmpPro",
        joinColumns=@JoinColumn(name="eid"),
        inverseJoinColumns=@JoinColumn(name="pid"))
    private Set pros = new HashSet<>();
}

@Entity @Table(name="YProject")
public class Project {
    @Id @GeneratedValue private Integer pid;
    @ManyToMany(mappedBy="pros")
    private Set emps = new HashSet<>();
}

關鍵屬性解析

  • mappedBy:關係維護方(對應 XML inverse="true"),值為對方屬性名
  • cascade:級聯操作
    CascadeType 枚舉
  • @JoinColumn:外鍵列定義
  • @JoinTable:中間表定義(多對多必須)

註解 vs XML

註解優勢:零配置文件、代碼與映射同步、重構友好、可讀性高。現代項目首選註解模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
註解作用關鍵屬性
@Entity標識實體類
@Table指定表名name
@Id主鍵
@GeneratedValue主鍵生成策略strategy(AUTO/IDENTITY/SEQUENCE/TABLE)
@Column列映射name, length, nullable, unique
@Temporal日期類型value(DATE/TIME/TIMESTAMP)