[英]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.