Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/381.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用hibernate标准的泛型dao方法是错误的,但感觉非常正确_Java_Hibernate_Generics - Fatal编程技术网

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

Java 使用hibernate标准的泛型dao方法是错误的,但感觉非常正确,java,hibernate,generics,Java,Hibernate,Generics,目前我有一个dao,它使用通用方法和hibernate标准来执行几乎所有的数据访问(我计划稍后为更复杂的事情创建子类),它看起来如下所示: public <T> List<T> getAll(final Class<T> type){ final Session session = sessionFactory.getCurrentSession(); final Criteria crit = session.createCriteria(t

目前我有一个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();
}
public List getAll(最终类类型){
最终会话会话=sessionFactory.getCurrentSession();
最终标准crit=session.createCriteria(类型);
返回crit.list();
}
公共列表getFieldEq(最终类类型、最终字符串propertyName、最终对象值){
最终会话会话=sessionFactory.getCurrentSession();
最终标准crit=session.createCriteria(类型);
标准添加(Restrictions.eq(propertyName,value));
返回crit.list();
}
但是,HQL更可取,因为它可以通过数据库/连接(即参数化查询)进行优化,而criteria api必须在运行时进行评估,因此
限制。eq(“name”,“NimChimpksy”)
根本不安全


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

坦率地说,我认为您当前的方法没有任何问题,假设您的查询是如此简单和直接

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

在我的例子中,我倾向于使用HQL,因为它允许我为复杂的查询编写更简短、更清晰的代码(我认为,这确实是一个偏好问题)。但是,条件也非常有用,因为它允许我动态构造查询条件,比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查询字符串,这会使代码读起来有点麻烦。

我使用一个静态类来执行所有基本的Hibernate获取、保存、更新和删除操作,它工作得非常好

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

关于准备好的报表,HQL和标准之间没有区别。两者都使用事先准备好的语句。我看不出限制是如何不安全的。@JBNizet因为限制直到运行时才得到计算,而hql在部署时得到检查?我指的是我得到的另一个答案:HQL也在运行时检查。命名查询在部署时被检查,但这并不意味着它们是正确的。如果您想确保错误安全,请为DAO实现单元测试。然后,在构建时将检查所有内容。@JBNizet谢谢,这确实是我最初的计划。那么,使用标准是否也不会对性能产生任何影响?如果不进行测量,您将无法知道。但是,与对数据库实际执行请求的成本相比,在命名HQL查询、HQL查询和条件查询之间构建SQL的成本差异将完全可以忽略不计。你在错误的地方进行优化。