Fenriswolf 程式筆記

奮利斯狼的地盤,小綿羊勿入

HibernateTemplate enhancement

spring 所提供的 HibernateTemplate 有兩個問題

  • 建立 Hibernate DAO beans 時一般都是設 singleton scope,所以 DAO 裡的 HibernateTemplate 也是 singleton,但是 HibernateTemplate 在 class 裡有很多 instance variables,包括 fetchSize、maxResults 等等,會造成 thread-safe 的問題
  • 直到 spring 2.5 的 HibernateTemplate 仍然沒有支援 SQLQuery function及 firstResult 屬性


1. 要從 HibernateDaoSupport 著手

public final FwHibernateTemplate getHibernateTemplate() {
    return new FwHibernateTemplate(getSessionFactory());
}

在取得 HibernateTemplate 會直接回傳一個新的 object
不過以前用

getHibernateTemplate().setMaxResults(10);
List list = getHibernateTemplate().find("from Customer c");

都要改成

HibernateTemplate template = getHibernateTemplate();
template.setMaxResults(10);
List list = template.find("from Customer c");

嗯…….有點頭痛

2. 要改寫 HibernateTemplate,除了支援 firstResult 外,並加上以下程式碼

public int executeNativeSQL(final String sql, final String paramName,
            final Object value) {
    return executeNativeSQL(sql, new String[] { paramName },
            new Object[] { value });
}

public int executeNativeSQL(final String sql, final String[] paramNames,
        final Object[] values) {
    if (paramNames != null && values != null
            && paramNames.length != values.length) {
        throw new IllegalArgumentException(
                "Length of paramNames array must match length of values array");
    }

    Integer updateCount = (Integer) execute(new HibernateCallback() {
        public Object doInHibernate(Session session)
                throws HibernateException {
            Query queryObject = session.createSQLQuery(sql);
            prepareQuery(queryObject);
            if (values != null) {
                for (int i = 0; i < values.length; i++) {
                    applyNamedParameterToQuery(queryObject, paramNames[i],
                            values[i]);
                }
            }
            return new Integer(queryObject.executeUpdate());
        }
    }, true);
    return updateCount.intValue();
}

public List findByNativeSQL(String sql, String paramName, Object value) {
    return findByNativeSQL(sql, new String[] { paramName },
            new Object[] { value });
}

public List findByNativeSQL(final String sql, final String[] paramNames,
        final Object[] values) {
    if (paramNames != null && values != null
            && paramNames.length != values.length) {
        throw new IllegalArgumentException(
                "Length of paramNames array must match length of values array");
    }

    return (List) execute(new HibernateCallback() {
        public Object doInHibernate(Session session)
                throws HibernateException {
            Query queryObject = session.createSQLQuery(sql);
            prepareQuery(queryObject);
            if (values != null) {
                for (int i = 0; i < values.length; i++) {
                    applyNamedParameterToQuery(queryObject, paramNames[i],
                            values[i]);
                }
            }
            return queryObject.list();
        }
    }, true);
}

方便以後直接使用 native SQL,不需要自己 implement 醜醜的 HibernateCallback
不過目前的版本只支援用 NamedParameter 傳參數,不支援 ? 的方式
 
 
執行環境
JDK 1.6.0_03
spring 2.5
hibernate 3.2.5

參考資料
Spring Application Framework
hibernate.org

程式下載
FwDaoSupport.java
FwHibernateTemplate.java

廣告

2012/03/19 - Posted by | Java Framework | ,

1 則迴響 »

  1. use Hibernate 4 with spring . say good bay 2 Hibernatetample

    迴響 由 olddor | 2015/05/26 | 回應


發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

%d 位部落客按了讚: