简体   繁体   English

如何有效使用PreparedStatement?

[英]How to use PreparedStatement efficiently?

I like to use the DAO pattern and have a class which do all my SQL request for a particular table and JPA entity. 我喜欢使用DAO模式,并具有一个类,该类对特定的表和JPA实体执行我的所有SQL请求。 I have for example something like: 例如,我有类似的东西:

public class MyDao {

    @PersistenceContext(name = "mycontext")
    private EntityManager entityManager;

    public List<MyEntity> find(String code)  {

        return getEntityManager()
            .createQuery("FROM MyEntity e WHERE e.code = :code")
            .setParameter("code", code)
            .getResultList();

    }

}

But I also know we can use named query directly on the entity class with a static method (I don't like this way): 但是我也知道我们可以使用静态方法直接在实体类上使用命名查询(我不喜欢这种方式):

@Entity
@Table
@NamedQueries({
    @NamedQuery(name = "find", query = "FROM MyEntity e WHERE e.code = :code")
})
public class MyEntity {

    ...

    public static List<MyEntity> find(EntityManager entityManager, String code) {

        return entityManager.createNamedQuery("find", MyEntity.class)
            .setParameter("code", code)
            .getResultList();

    }

}

Is one of those method better than the other one ? 这些方法中的一种优于另一种吗? If I want to execute the same SQL query thousands of times in the same transaction, is both methods keep in JPA memory (or somewhere else) the prepared statement ? 如果我想在同一事务中执行数千次相同的SQL查询,这两种方法是否都将JPA内存(或其他位置)保留在准备好的语句中? Which seems to be a good practise in this case. 在这种情况下,这似乎是一个好习惯。 I would think the second method does it because it's static but not the first one. 我认为第二种方法可以做到,因为它是静态的,但不是第一种。 Am I wrong ? 我错了吗 ?

The advantage for declaritively defined queries via @NamedQuery is that they will be precompiled, can be cached within the secondary cache and syntactically validated on startup if you enable it within the persistence.xml using the JPA non-hibernate specific API . 通过@NamedQuery进行声明式定义的查询的优势在于,如果使用JPA非休眠特定的API在persistence.xml中启用它,它们将被预编译,可以在辅助缓存中缓存并在启动时进行语法验证。

So if you plan on executing a query, using only JPA, often it is probably best to use NamedQuery and cache the query. 因此,如果计划仅使用JPA执行查询,则通常最好使用NamedQuery并缓存查询。

So for JPA using hibernate you could do something like this: 因此,对于使用休眠的JPA,您可以执行以下操作:

            @NamedQuery(name="AbstractBaseQuestion.findAllInstancesByGroupID", query="SELECT q FROM AbstractBaseQuestion q WHERE q.isTemplate = FALSE", hints={@QueryHint(name="org.hibernate.cacheable", value="true"),@QueryHint(name="org.hibernate.cacheMode", value="NORMAL"),}),

Within your persistence.xml for hibernate you can validate these @NamedQueries on startup: 在用于休眠的persistence.xml中,可以在启动时验证以下@NamedQueries:

      <property name="hibernate.hbm2ddl.auto" value="validate"/>

Now the first method you suggested can be cached and precompiled if you use the Hibernate Session API. 现在,如果您使用的是Hibernate Session API,则可以对您建议的一种方法进行缓存和预编译。 I imagine there are equivalents on EclipseLink and other ORM's but at this point you are using non-JPA features which could make moving from one JPA implementation to another difficult. 我想在EclipseLink和其他ORM上有等同功能,但是此时您正在使用非JPA功能,这可能会使从一种JPA实现过渡到另一种JPA实现变得困难。

If you don't do that extra implementation specific work your query is going to not be cached and you will pay a performance penalty. 如果您不执行额外的特定于实现的工作,那么您的查询将不会被缓存,并且您将付出性能损失。

I hope that helps. 希望对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM