有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

sql如何使用java将复杂的NativeQuery结果映射到DTO对象

Query query = em.createNativeQuery(STUDENT_QUERY_WITH_PARAMS);
        query.setParameter("studentId", stduentId);
        query.setParameter("startDate", valueOf(startDate), TemporalType.DATE);
        query.setParameter("endDate", valueOf(endDate), TemporalType.DATE);
        List<Object[]> resultList = query.getResultList();

        List<StudentDepartmentCatDTO> result = new ArrayList<>(resultList.size());
        for (Object[] row : resultList) {
            result.add(new StudentDepartmentCatDTO((String)row[0], (String)row[1], (String)row[2], null,(UUID)row[4], (Integer)row[5], (Integer)row[6], (Integer)row[7], (Integer)row[8], null, null, null, null ));
        }

`我有一个SQL查询,通过连接多个表(在我的例子中是13个表)从不同的表中提取特定数据,我能够成功地获取所有结果,但是当我尝试将这些结果映射回DTO时,我得到了强制转换异常。我如何克服这些例外

B不能转换为类java。util。UUID和 类java。数学无法将BigDecimal转换为类java。整型

由于所有结果都来自不同的表,因此我没有找到使用SqlResultsMapping实现这一点的方法,因为没有任何托管实体可以直接映射到结果。有更好的方法吗?我想知道如何修复这些强制转换异常?我可以创建非托管实体以将所有结果映射到它吗?如何将sql结果提取到DTO中


共 (1) 个答案

  1. # 1 楼答案

    你可以use an ^{} to convert each record in your result set to a DTO对象。但这需要一个额外的构造函数,这样就不需要将任何参数设置为null

    下面是这样一个映射的示例。如您所见,您需要按名称引用结果集中的元素,但您没有共享您的查询。因此,我无法根据您的查询调整示例

    @SqlResultSetMapping(
            name = "BookValueMapping",
            classes = @ConstructorResult(
                    targetClass = BookValue.class,
                    columns = {
                        @ColumnResult(name = "id", type = Long.class),
                        @ColumnResult(name = "title"),
                        @ColumnResult(name = "version", type = Long.class),
                        @ColumnResult(name = "authorName")}))
    

    我将此映射用于从数据库中选择idtitleversionauthorName列的查询。@ConstructorResult注释描述了BookValue类的构造函数调用。@ColumnResult注释定义了构造函数参数及其顺序。您需要确保实例化的类提供了与这些参数匹配的构造函数

    @SqlResultSetMapping是JPA中一个强大且灵活的功能。我在这里详细解释:https://thoughts-on-java.org/result-set-mapping-constructor-result-mappings/


    好的,现在让我们来看看班级演员问题

    强制转换失败,因为这两个对象属于错误的类row[4]似乎是一个byte[],其中一个row[6/7/8](或全部)似乎是一个大整数

    此代码段将帮助您将字节[]转换为UUID:

    ByteBuffer bb = ByteBuffer.wrap(bytes);
    long high = bb.getLong();
    long low = bb.getLong();
    UUID uuid = new UUID(high, low);
    

    BigDecimal转换为Integer要容易得多。只需在BigDecimal上调用intValueExact()方法,例如row[6].intValueExact();