如何有效地使用PreparedStatement?

我喜欢使用DAO模式,并且有一个类可以为特定的表和JPA实体执行所有SQL请求。 我有例如:

public class MyDao { @PersistenceContext(name = "mycontext") private EntityManager entityManager; public List find(String code) { return getEntityManager() .createQuery("FROM MyEntity e WHERE e.code = :code") .setParameter("code", code) .getResultList(); } } 

但我也知道我们可以使用静态方法直接在实体类上使用命名查询(我不喜欢这种方式):

 @Entity @Table @NamedQueries({ @NamedQuery(name = "find", query = "FROM MyEntity e WHERE e.code = :code") }) public class MyEntity { ... public static List find(EntityManager entityManager, String code) { return entityManager.createNamedQuery("find", MyEntity.class) .setParameter("code", code) .getResultList(); } } 

这些方法中的一种比另一种更好吗? 如果我想在同一个事务中执行相同的SQL查询数千次,那么这两种方法是否都在JPA内存(或其他地方)保留了预处理语句? 在这种情况下,这似乎是一种很好的做法。 我认为第二种方法是因为它是静态的而不是第一种方法。 我错了吗 ?

通过@NamedQuery进行声明定义查询的优势在于,如果使用JPA非hibernate特定API在persistence.xml中启用它,它们将被预编译,可以缓存在辅助缓存中并在启动时进行语法validation。

因此,如果您计划仅使用JPA执行查询,通常最好使用NamedQuery并缓存查询。

因此,对于使用hibernate的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"),}), 

在hibernate的persistence.xml中,您可以在启动时validation这些@NamedQueries:

   

现在,如果您使用Hibernate Session API,您建议的第一个方法可以进行缓存和预编译。 我想EclipseLink和其他ORM上有等价物,但此时你正在使用非JPAfunction,这可能会使一个JPA实现变为另一个很难。

如果您没有执行额外的实现特定工作,您的查询将不会被缓存,您将支付性能损失。

我希望有所帮助。