【问题标题】:How can I map a result set to custom POJO in JPA如何将结果集映射到 JPA 中的自定义 POJO
【发布时间】:2020-04-07 21:44:23
【问题描述】:

我需要通过加入 3 个不同的表来获取 6 列。我已在实体类之上将它们声明为 NamedNativequery,并且我使用了 JPA 的创建命名查询方法。当我尝试获取结果集时,我得到的是数组对象列表,而不是 POJO 类型的对象列表。为了将结果集映射到外部 POJO,我应该定义任何外部映射吗?

【问题讨论】:

    标签: java spring hibernate jpa spring-data-jpa


    【解决方案1】:

    你当然可以。这应该会有所帮助:

    @NamedNativeQuery(query = "SELECT t1.col1, t2.col2 FROM t1 JOIN t2 ON ...", name = "MyNamedQuery", resultSetMapping = "MyPojoMapper")
    @SqlResultSetMapping(name = "MyPojoMapper", classes = @ConstructorResult(
        targetClass = MyPojo.class,
        columns = {
                @ColumnResult(name = "col1", type = String.class),
                @ColumnResult(name = "cols", type = String.class)
        }))
    

    然后这样使用它:

    NativeQuery query = session.getNamedNativeQuery("MyNamedQuery");
    MyPojo result = (MyPojo) query.getSingleResult();
    

    【讨论】:

    • 我们可以在这里进行转换,比如 DB 会有 Number 而 POJO 会有字符串吗?反之亦然??
    【解决方案2】:

    您可以使用投影来指定要获取哪些属性
    https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections

    或者直接用JPQL获取:

    Repository.java

    @Repository
    public class CustomRepositoryImpl {
      @Autowired
      private EntityManager entityManager;
    
      public List<Dto> find() {
        var query = "SELECT new Dto(
                        x.Field1, 
                        y.Field2, 
                        z.Field3, 
                        ...)
                     FROM XxxEntity x
                     LEFT JOIN YyyEntity y
                     LEFT JOIN ZzzEntity z"
    
        var jpqlQuery = entityManager.createQuery(query);
    
        return jpqlQuery.getResultList();
      }
    }
    

    Dto.java

    public class Dto {
    
        // Must have parameterized constructor with all fields what used in Repository
        public Dto(int field1, String field2, String field3, ...) {
        }
    }
    

    【讨论】:

    • 能否在实体类中定义相同的查询,并使用命名查询并将结果集映射到DTO?
    • > 我们可以在实体类中定义相同的查询并使用命名查询并将结果集映射到 DTO 吗?是的,你可以这样做。但在一些复杂的情况下,我认为命名查询是不够的(例如:动态查询)。
    • 当我在命名查询中做同样的事情时,我得到一个 DTO 无法识别的异常
    猜你喜欢
    • 2019-01-20
    • 2014-10-01
    • 2011-03-11
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 2019-05-23
    相关资源
    最近更新 更多