hibernate SQLQueryImpl setParameter vs setString

时间:2016-07-11 15:09:08

标签: java hibernate grails

我们无法弄清楚为什么在使用setString,setLong时对executeUpdate查询使用setParameter要慢一些。

  SQLQueryImpl query = session.createSQLQuery("update message set status = :status where attempt_id = :attemptId")

每当我使用:

query.setParameter("status", Status.DONE)
query.setParameter("attemptId", id)

与使用相比,它的速度降低了近10倍:

query.setString("status", Status.DONE.toString())
query.setLong("attemptId", id)

我可以验证他们是否在下面生成了类似的查询:

update message set status = ? where attempt_id = ?

为什么setParameter()会变慢?

使用setString(),setLong()优于使用setParameter()

我认为它只是添加了一个图层来确定要添加的类型但应该几乎相同。

1 个答案:

答案 0 :(得分:3)

检查AbstractQueryImpl的源代码将揭示原因。简而言之,它必须弄清楚你正在设置的Type参数,这是昂贵的(而且浪费,因为你应该知道你注射的是什么)。

public Query setParameter(String name, Object val) throws HibernateException {
    if (val == null) {
        Type type = parameterMetadata.getNamedParameterExpectedType( name );
        if ( type == null ) {
            type = StandardBasicTypes.SERIALIZABLE;
        }
        setParameter( name, val, type );
    }
    else {
        // determineType() method below is expensive
        setParameter( name, val, determineType( name, val ) );
    }

现在比较setString(),它不必确定Type并明确地设置它:

public Query setString(int position, String val) {
    setParameter(position, val, StandardBasicTypes.STRING);
    return this;
}

对于方法签名,使用setStringsetLong也是更严格类型的,这通常是您想要的(在编译时比运行时更好地失败)。