3.4.4.5. 执行 SQL 查询

ORM 允许执行返回个别字段列表或实体实例的 SQL 查询。为此,通过调用 EntityManager.createNativeQuery() 方法创建 QueryTypedQuery 对象。

如果选择了个别列,则结果列表中每行的类型为 Object[]。例如:

Query query = persistence.getEntityManager().createNativeQuery(
        "select ID, NAME from SALES_CUSTOMER where NAME like ?1");
query.setParameter(1, "%Company%");
List list = query.getResultList();
for (Iterator it = list.iterator(); it.hasNext(); ) {
    Object[] row = (Object[]) it.next();
    UUID id = (UUID) row[0];
    String name = (String) row[1];
}

如果选择了单个列或聚合函数,结果列表将直接包含这些值:

Query query = persistence.getEntityManager().createNativeQuery(
        "select count(*) from SEC_USER where login = #login");
query.setParameter("login", "admin");
long count = (long) query.getSingleResult();

如果要生成的实体类型与查询语句一起传递给 EntityManager.createNativeQuery(),则返回 TypedQuery 对象,并且 ORM 尝试将查询结果映射到相应的实体属性。例如:

TypedQuery<Customer> query = em.createNativeQuery(
    "select * from SALES_CUSTOMER where NAME like ?1",
    Customer.class);
query.setParameter(1, "%Company%");
List<Customer> list = query.getResultList();

在使用 SQL 时需要注意,对应于 UUID 类型的实体属性的列将以 UUID 类型或 String 类型返回,具体取决于所使用的 DBMS:

  • HSQLDBString

  • PostgreSQLUUID

  • Microsoft SQL ServerString

  • OracleString

  • MySQLString

此类型的参数也应该以 UUID 或字符串格式传递,具体取决于 DBMS。要确保代码不依赖于 DBMS 细节,请使用 DbTypeConverter ,它提供了在 Java 对象与 JDBC 参数和结果之间转换数据的方法。

原生查询语句支持位置和命名参数。位置参数在查询语句中以 ? 标记,后而跟从 1 开始的参数序号。命名参数用数字符号(#)标记。请参阅上面的示例。

与当前持久化上下文相关的返回实体的 SQL 查询和修改查询(updatedelete)的行为类似于上面描述的JPQL 查询