我在我的项目中使用JPA。
我遇到一个查询,我需要对五个表进行连接操作。因此,我创建了一个返回五个字段的本机查询。
现在我想将结果对象转换为java POJO类,其中包含相同的五个字符串。
在JPA中有任何方法可以直接将结果转换为POJO对象列表吗??
我想出了如下的解决办法。
@NamedNativeQueries({
@NamedNativeQuery(
name = "nativeSQL",
query = "SELECT * FROM Actors",
resultClass = db.Actor.class),
@NamedNativeQuery(
name = "nativeSQL2",
query = "SELECT COUNT(*) FROM Actors",
resultClass = XXXXX) // <--------------- problem
})
现在在resultClass中,我们需要提供一个实际的JPA实体类吗?
或
我们可以将其转换为包含相同列名的任何JAVA POJO类?
如果希望将自定义查询结果直接映射到实体,而不需要编写任何映射代码,可以尝试这种方式。根据我的经验,这是最方便的方法,但缺点是失去了hibernate ddl-auto的好处:
Disable hibernate validation by removing the hibernate.ddl-auto. If not doing this, hibernate can complain about missing table in database.
Create a pojo with @Entity for the custom result set without table mapping, something like:
@Getter
@Setter
@Entity
public class MyCustomeResult implements Serializable {
@Id
private Long id;
@Column(name = "name")
private String name;
}
In repository, use the entity to map directly from query.getResultList()
public List<MyCustomeResult> findByExampleCustomQuery(Long test) {
String sql = "select id, name from examples where id =:test";
Query query = entityManager.createNativeQuery(sql, MyCustomeResult.class);
return query.setParameter("test", test).getResultList();
}
最简单的方法就是使用投影。它可以将查询结果直接映射到接口,并且比使用SqlResultSetMapping更容易实现。
一个例子如下所示:
@Repository
public interface PeopleRepository extends JpaRepository<People, Long> {
@Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
"FROM people p INNER JOIN dream_people dp " +
"ON p.id = dp.people_id " +
"WHERE p.user_id = :userId " +
"GROUP BY dp.people_id " +
"ORDER BY p.name", nativeQuery = true)
List<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId);
@Query(value = "SELECT p.name AS name, COUNT(dp.people_id) AS count " +
"FROM people p INNER JOIN dream_people dp " +
"ON p.id = dp.people_id " +
"WHERE p.user_id = :userId " +
"GROUP BY dp.people_id " +
"ORDER BY p.name", nativeQuery = true)
Page<PeopleDTO> findByPeopleAndCountByUserId(@Param("userId") Long userId, Pageable pageable);
}
// Interface to which result is projected
public interface PeopleDTO {
String getName();
Long getCount();
}
投影接口中的字段必须与该实体中的字段匹配。否则字段映射可能会中断。
同样,如果你使用SELECT表。列表示法总是定义与实体名称匹配的别名,如示例所示。
如果希望将自定义查询结果直接映射到实体,而不需要编写任何映射代码,可以尝试这种方式。根据我的经验,这是最方便的方法,但缺点是失去了hibernate ddl-auto的好处:
Disable hibernate validation by removing the hibernate.ddl-auto. If not doing this, hibernate can complain about missing table in database.
Create a pojo with @Entity for the custom result set without table mapping, something like:
@Getter
@Setter
@Entity
public class MyCustomeResult implements Serializable {
@Id
private Long id;
@Column(name = "name")
private String name;
}
In repository, use the entity to map directly from query.getResultList()
public List<MyCustomeResult> findByExampleCustomQuery(Long test) {
String sql = "select id, name from examples where id =:test";
Query query = entityManager.createNativeQuery(sql, MyCustomeResult.class);
return query.setParameter("test", test).getResultList();
}