使用hibernate标准的泛型dao方法是错误的,但感觉非常正确

时间:2012-02-23 09:33:31

标签: java hibernate generics

目前我有一个dao,它使用泛型方法和hibernate标准来执行几乎所有的数据访问(我计划在以后为更复杂的事情创建子类),它看起来像这样:

public <T> List<T> getAll(final Class<T> type){
    final Session session = sessionFactory.getCurrentSession();
    final Criteria crit = session.createCriteria(type);
    return crit.list();
}

public <T> List<T> getFieldEq(final Class<T> type, final String propertyName, final Object value){
    final Session session = sessionFactory.getCurrentSession();
    final Criteria crit = session.createCriteria(type);
    crit.add(Restrictions.eq(propertyName, value));
    return crit.list();
}

但是,HQL是优选的,因为它可以通过数据库/连接(即参数化查询)进行优化,而标准api必须在运行时进行评估,因此Restrictions.eq("name", "NimChimpksy")根本不是错误安全的。

我应该保留通用dao(只有一个dao感觉很好),或者只是为每个域对象实现一个公共接口并在一个单独的dao中使用hql。

2 个答案:

答案 0 :(得分:3)

坦率地说,假设您的查询简单明了,我认为您当前的方法没有任何问题。

通常,至少在我的团队中,使用HQL与Criteria的选择更像是一种“偏好”的东西。 HQL看起来更像SQL,您可以编写更多压缩代码。对于一些开发人员而言,标准看起来更为OO。

在我的情况下,我倾向于使用HQL,因为它允许我为复杂的查询编写更短更简洁的代码(再次,它确实是一个偏好的问题,我相信)。但是,Criteria也非常有用,因为它允许我比HQL更容易构建查询条件,这是一个非常简单的例子: -

public void doIt(String s1, String s2, String s3){
    ...

    if (/*some s1 condition*/) {
        crit.add(Restrictions.eq("s1", s1));
    }

    if (/*some s2 condition*/) {
        crit.add(Restrictions.like("s2", s2 + "%"));
    }

    if (/*some s3 condition*/) {
        crit.add(Restrictions.ne("s3", s3));
    }

    return crit.list();
}

想象一下,如果你要在HQL中做这样的事情,你将不得不动态地动态构造HQL查询字符串,这会使代码有点讨厌阅读。

答案 1 :(得分:0)

我使用静态类来完成所有基本的Hibernate获取,保存,更新,删除操作,并且它运行良好。

public static List getList(Class c, Session session)
{
    return session.createQuery("FROM " + c.getSimpleName()).list();
}