【问题标题】:What is a named query?什么是命名查询?
【发布时间】:2010-12-23 08:40:53
【问题描述】:

我已经阅读了它的定义,但无法完全理解。

【问题讨论】:

标签: sql


【解决方案1】:

让我猜猜:您偶然发现了命名查询的概念,并且想知道它在 SQL 中的位置。

嗯,据我所知,命名查询与“纯”SQL 没有任何关系,但它们是在各种 ORM(对象关系映射)框架中发现的概念,ala Java Persistence API

基本上,命名查询是将名称映射到可能在不同位置的代码中多次调用的查询的一种方法。

所以,而不是使用

"SELECT i FROM Item i WHERE i.product.categoryID LIKE :cID"

作为代码中不同位置的字符串,您可以使用:

@NamedQuery( 
  name="MyEntity.getItemsPerProductCategory", 
  query="SELECT i FROM Item i WHERE i.product.categoryID LIKE :cID"
)

然后您使用MyEntity.getItemsPerProductCategory 引用此查询。

示例取自this site

您可能想知道为什么这很有用?

Hibernate 这样的JPA 实现可以在启动时检查命名查询的有效性,因此在某种程度上,您可以进行安全的类型检查。这将有助于减少运行时的错误。

【讨论】:

  • Hibernate Named Query 帮助我们在中心位置对查询进行分组,而不是让它们分散在整个代码中。 Hibernate Named Query 语法在创建 hibernate 会话工厂时被检查,从而使应用程序快速失败,以防命名查询中出现任何错误。 Hibernate 命名查询是全局的,这意味着一旦定义它就可以在整个应用程序中使用。
【解决方案2】:

我相信你说的是 Hibernate。

简单来说,命名查询就是可以通过名称来识别的查询。您可以如下定义一个命名查询并按其名称使用它。

@NamedQuery name="findAllUsers" query="SELECT u FROM Users u"
findByNamedQuery("findAllUsers")

你有更多的选择,也可以向它传递参数。

【讨论】:

    【解决方案3】:

    命名查询是以元数据表示的静态查询。查询名称的范围为持久性单元。 以下是 Java Persistence 查询语言中命名查询的定义示例:

    @NamedQuery(
            name="findAllCustomersWithName",
            query="SELECT c FROM Customer c WHERE c.name LIKE :custName"
    )
    

    以下是使用命名查询的示例:

    @PersistenceContext
    public EntityManager em;
    ...
    customers = em.createNamedQuery("findAllCustomersWithName")
            .setParameter("custName", "Smith")
            .getResultList();
    

    【讨论】:

      【解决方案4】:

      在 JPA 中有 2 种方式来定义查询,动态和静态。命名查询是后者(即静态)。您可以在 XML 元数据文件中或直接在实际实体上定义查询。请注意,这些查询具有全局范围(即跨越整个持久性单元),即无论它们在哪里定义,名称都必须是唯一的,例如如果您在实体“Employee”上定义了一个命名查询,并且命名查询称为“findAll”,并且您在名为“Department”的实体上定义了另一个名为“findAll”的命名查询,那么这些查询将发生冲突。

      这就是为什么命名查询的名称通常带有它们所应用的实体名称的前缀,例如:

          @NamedQueries({@NamedQuery(name="Employee.findAll", query="select e from Employee e"),
                     @NamedQuery(name="Employee.findByName", query="select e from Employee e where e.name = :name")})
          @Entity
          public class Employee ... {
          ....
      

      作为一般的最佳实践,任何不需要动态构建的查询(例如,在编译时具有不确定数量的 and 子句的查询,因为这些是由用户在运行时定义的过滤器确定的up dynamic) 应该通过本机查询来完成,因为它们在应用程序启动时被处理/转换为 SQL 一次,而不是每次使用查询时。因此它们比动态查询更有效。

      【讨论】:

        【解决方案5】:

        根据http://www.objectdb.com/java/jpa/query/named 命名查询是具有预定义的不可更改查询字符串的静态定义查询。使用命名查询而不是动态查询可以通过将 JPQL 查询字符串与 Java 代码分开来改进代码组织。它还强制使用查询参数,而不是将文字动态嵌入到查询字符串中,从而提高查询效率。

        这是一个例子, 你应该导入

        导入 javax.persistence.NamedQueries; 导入 javax.persistence.NamedQuery;

        @NamedQueries({
            @NamedQuery(name = "Tenantdata.findAll", query = "SELECT c FROM Tenantdata c"),
            @NamedQuery(name = "Tenantdata.findById", query = "SELECT c FROM Tenantdata c WHERE c.id = :id")
        }    
        )
        

        【讨论】:

          【解决方案6】:

          命名查询是表示为表的 SQL 表达式。在命名查询中,您可以指定 SQL 表达式来选择从一个或多个数据源中的一个或多个表返回的行和列。命名查询与数据源视图 (DSV) 中具有行和关系的任何其他表类似,但命名查询基于表达式。

          命名查询允许您扩展 DSV 中现有表的关系架构,而无需修改基础数据源。例如,可以使用一系列命名查询将复杂的维度表拆分为更小、更简单的维度表,以便在数据库维度中使用。命名查询还可用于将来自一个或多个数据源的多个数据库表连接到一个数据源视图表中。

          (TechNet: Define Named Queries in a Data Source View (Analysis Services))

          @Entity
          @Table(name = "users")
          @XmlRootElement
          @NamedQueries({
              @NamedQuery(name = "Users.findAll", query = "SELECT u FROM Users u")
              , @NamedQuery(name = "Users.findById", query = "SELECT u FROM Users u WHERE u.id = :id")
              , @NamedQuery(name = "Users.findByUsername", query = "SELECT u FROM Users u WHERE u.username = :username")
              , @NamedQuery(name = "Users.findByPassword", query = "SELECT u FROM Users u WHERE u.password = :password")
              , @NamedQuery(name = "Users.findByStatus", query = "SELECT u FROM Users u WHERE u.status = :status")
              , @NamedQuery(name = "Users.findByDateCreated", query = "SELECT u FROM Users u WHERE u.dateCreated = :dateCreated")})
          public class Users implements Serializable {
          

          【讨论】:

          • 供将来参考:引用其他人时的归属和可理解的格式在 SO 上不是可选的。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-04
          • 2010-11-26
          • 1970-01-01
          • 2010-09-15
          • 2011-03-23
          相关资源
          最近更新 更多