如何避免创建多余的实体?

sta*_*ker 6 java hibernate jpa

在我当前的项目中,我需要执行一些本机查询,从查询中加入的表中选择一些字段,例如:

SELECT t1.col1, t2.col5
FROM t1
JOIN t2 ON t2.id = t1.t2_id
Run Code Online (Sandbox Code Playgroud)

我试着将它们存放在类似的类中

class Result {
  String t1_col1;
  String t2_col5;
}
Run Code Online (Sandbox Code Playgroud)

运用

Query q = entityManager.createNativeQuery( "THE SQL SELECT" , Result.class );
Run Code Online (Sandbox Code Playgroud)

JPA现在抱怨("uknown entity:result")类"结果"不是可能需要将列映射到对象的实体.我还试图@Column在结果类中重复声明.

我的问题是如何声明这一点而不必在我的数据库中创建表示为表格的entites?

Boz*_*zho 6

唉,我认为在JPA中没有办法做到这一点.但是,您可以使用hibernate Query对象执行此操作.获得它使用:

org.hibernate.Query query = q.unwrap(org.hibernate.Query.class);
Run Code Online (Sandbox Code Playgroud)

然后设置结果转换器.看到这里:

query.setResultTransformer(Transformers.aliasToBean(Result.class));
Run Code Online (Sandbox Code Playgroud)


JB *_*zet 5

如果您使用JPA/Hibernate执行SQL查询,那么您使用的是错误的工具.Hibernate是一个ORM,你应该将表映射到实体.这就是JPA的重点.我只想执行SQL查询,使用JDBC(例如Spring的JdbcTemplate)

一旦table1和table2映射到实体(让我们调用这些实体T1和T2),您将不再需要这些SQL查询,因为JPQL只能选择实体的某些字段.您的查询可能如下所示(取决于t1和t2之间的关联):

select t1.col1, t2.col5 from T1 t1 join t1.t2 t2
Run Code Online (Sandbox Code Playgroud)

你只需要迭代结果(Object []列表)来构建你的结果(这是一个DTO而不是一个映射的实体):

List<Object[]> rows = (List<Object[]>) query.list();
List<Result> listOfResults = new ArrayList<Result>(rows.size);
for (Object[] row : rows) {
    listOfResults.add(new Result((String) row[0], (String) row[1]));
}
Run Code Online (Sandbox Code Playgroud)

  • 如果我向构造函数添加一个参数,上面的代码将停止编译,我知道我必须修复查询.使用JPQL查询中的new,我只会在运行时出现异常.如果我在构造函数中切换参数的顺序,我的IDE将切换所有的调用.但如果新的是在JPQL中则不行.如果我的查询返回一些错误的类型,我将有一个干净的ClassCastException,而不是一些模糊的"找不到构造函数"异常.我将能够检查查询的结果,看看有什么问题. (3认同)