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

利用 Java 反射與 Hibernate 實現單表/視圖動態組合查詢

     編輯:Java 相關知識

核心思路

Hibernate 將表/視圖映射為實體類。利用反射掃描實體類的 getter 方法,按命名約定自動構建 Criteria 查詢條件,實現無需寫 HQL/SQL 的動態查詢。

命名約定與語義映射

核心代碼實現

public List queryList(Object entity, int first, int max, String orderField, boolean asc) {
    Session session = getSession();
    Criteria criteria = session.createCriteria(entity.getClass());
    Method[] methods = entity.getClass().getMethods();

    for (Method m : methods) {
        String name = m.getName();
        if (name.startsWith("getMin")) {
            String field = lowerFirst(name.substring(6));
            Object val = m.invoke(entity);
            if (val != null) criteria.add(Expression.ge(field, val));
        } else if (name.startsWith("getMax")) {
            String field = lowerFirst(name.substring(6));
            Object val = m.invoke(entity);
            if (val != null) criteria.add(Expression.le(field, val));
        } else if (name.startsWith("get") && !name.equals("getClass")) {
            String field = lowerFirst(name.substring(3));
            Object val = m.invoke(entity);
            if (val != null) {
                if (m.getReturnType() == String.class && "".equals(val)) continue;
                criteria.add(m.getReturnType() == String.class
                    ? Expression.like(field, "%" + val + "%")
                    : Expression.eq(field, val));
            }
        }
    }
    criteria.addOrder(asc ? Order.asc(orderField) : Order.desc(orderField));
    criteria.setFirstResult(first).setMaxResults(max);
    return criteria.list();
}

private String lowerFirst(String s) {
    return Character.toLowerCase(s.charAt(0)) + s.substring(1);
}

實體類擴展示例

// Staff 表映射類
class Staff {
    private String id, name, password, priv, birthday, active;
    private Long dept, post;

    // 區間查詢擴展字段
    private String minBirthday, maxBirthday;
    public String getMinBirthday() { return minBirthday; }
    public void setMinBirthday(String v) { minBirthday = v; }
    public String getMaxBirthday() { return maxBirthday; }
    public void setMaxBirthday(String v) { maxBirthday = v; }
    // ... 其他 getter/setter
}

使用場景示例

  • 全表分頁:queryList(new Staff(), 0, 1000, "id", true)
  • 姓名模糊查:Staff s=new Staff(); s.setName("丁"); queryList(s,0,1000,"id",true)
  • 多條件組合:s.setName("丁"); s.setActive("Y"); queryList(s,0,1000,"id",true)
  • 排序切換:queryList(s,0,1000,"birthday",true)
  • 區間查詢:s.setMinBirthday("1978"); s.setMaxBirthday("1981"); queryList(s,0,1000,"birthday",false)

聯表查詢策略

數據庫層面創建視圖,Hibernate 映射視圖為只讀實體類,同樣享受動態查詢能力,避免複雜關聯映射與笛卡爾積性能問題。

優勢與局限

  • 優勢:零 HQL/SQL、類型安全、重構友好、快速開發 CRUD 查詢界面。
  • 局限:複雜邏輯(OR、子查詢、聚合)仍需 HQL/SQL;反射有微小性能開銷(可緩存 Method 數組)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法前綴語義Criteria 表達式
getXxx()精確匹配(字符串用 like %xxx%)Expression.eq/like
getMinXxx()大於等於Expression.ge
getMaxXxx()小於等於Expression.le