Spring Data JPA 将本机查询结果映射到非实体 POJO

新手上路,请多包涵

我有一个带有本机查询的 Spring Data 存储库方法

@Query(value = "SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", nativeQuery = true)
GroupDetails getGroupDetails(@Param("userId") Integer userId, @Param("groupId") Integer groupId);

我想将结果映射到非实体 POJO GroupDetails

有可能吗?如果可以,请举个例子好吗?

原文由 alexanoid 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 630
2 个回答

假设 GroupDetails 与 orid 的回答相同,您是否尝试过 JPA 2.1 @ConstructorResult

 @SqlResultSetMapping(
    name="groupDetailsMapping",
    classes={
        @ConstructorResult(
            targetClass=GroupDetails.class,
            columns={
                @ColumnResult(name="GROUP_ID"),
                @ColumnResult(name="USER_ID")
            }
        )
    }
)

@NamedNativeQuery(name="getGroupDetails", query="SELECT g.*, gm.* FROM group g LEFT JOIN group_members gm ON g.group_id = gm.group_id and gm.user_id = :userId WHERE g.group_id = :groupId", resultSetMapping="groupDetailsMapping")

并在存储库界面中使用以下内容:

 GroupDetails getGroupDetails(@Param("userId") Integer userId, @Param("groupId") Integer groupId);

根据 Spring Data JPA 文档,spring 将首先尝试查找与您的方法名称匹配的命名查询 - 所以通过使用 @NamedNativeQuery@SqlResultSetMapping@ConstructorResult 应该能够实现这种行为

原文由 Daimon 发布,翻译遵循 CC BY-SA 3.0 许可协议

我认为最简单的方法是使用所谓的投影。它可以将查询结果映射到接口。使用 SqlResultSetMapping ,而且会让你的代码变得丑陋:)。

来自 spring data JPA 源代码的示例:

 public interface UserRepository extends JpaRepository<User, Integer> {

   @Query(value = "SELECT firstname, lastname FROM SD_User WHERE id = ?1", nativeQuery = true)
   NameOnly findByNativeQuery(Integer id);

   public static interface NameOnly {

     String getFirstname();

     String getLastname();

  }
}

您还可以使用此方法获取投影列表。

查看此 spring data JPA 文档条目以获取有关投影的更多信息。

注一:

请记住将您的 User 实体定义为正常 - 投影接口中的字段必须与该实体中的字段匹配。否则字段映射可能会被破坏( getFirstname() 可能返回姓氏等的值)。

笔记2:

如果您使用 SELECT table.column ... 表示法始终定义与实体名称匹配的别名。例如,此代码将无法正常工作(投影将为每个 getter 返回空值):

 @Query(value = "SELECT user.firstname, user.lastname FROM SD_User user WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);

但这很好用:

 @Query(value = "SELECT user.firstname AS firstname, user.lastname AS lastname FROM SD_User user WHERE id = ?1", nativeQuery = true)
NameOnly findByNativeQuery(Integer id);

对于更复杂的查询,我宁愿使用 JdbcTemplate 和自定义存储库。

原文由 Michał Stochmal 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题