Spring-Data + QueryDSL + JDBC:如何将查询结果映射到域对象?

时间:2014-10-27 19:59:38

标签: spring spring-data mybatis querydsl

我正在考虑使用Spring-Data + QueryDSL + JDBC来替换(或增强)当前使用的MyBatis。
我的理由是:

  1. 列名的编译时检查
  2. 从SQL编译SQL tatements和自动完成的编译时检查
  3. 能够针对与实际数据库相同的代码编写Java Collections上的单元测试,这比预先填充数据库要简单快得多
  4. 它比MyBatis更简洁 - 不需要在DAO层下单独的 XxxMapper.java XxxMapper.xml
  5. 但我发现以下问题:

    1. 没有用于将查询结果映射到域对象的基础结构。 QueryDSL的 QBean MappingProjection ,Spring的 BeanPropertyRowMapper 和Spring-Data的 OneToManyResultSetExtractor 似乎太低了,见下文。
    2. 在MyBatis
    3. 中免费提供开箱即用的会话/交易级缓存
    4. MyBatis中没有开箱即用的SQL语句和结果日志记录
    5. 由于我在问一个问题,所以让我们专注于我认为最重要问题的映射 所以我的问题是:
      有没有方便的解决方案将QueryDSL的SQLQuery结果映射到域对象,类似于MyBatis或JPA提供的?也就是说,基于一些简单配置的映射,无论是XML,注释,还是简单的Java?

      特别是,我对以下内容感兴趣:

      1. 将列映射到自定义类型,例如 EmailAddress Java对象
      2. 的String列
      3. 将一组列映射到嵌入对象,例如将 {first_name,last_name} 分组到 FullName Java对象
      4. 支持一对多关系,例如能够提取包含地址列表的 Customer 对象。
      5. 总而言之,我需要一种简单的方法来获取以下' 客户的一个或多个对象。来自以下SQL查询的类:

        class Customer {
            EmailAddress emailAddress;
            FullName fullName;
            Set<Address> addresses;
            Set<Comment> selfDescription;
        }
        class EmailAddress {
            private String address;
            EmailAddress(String address) {this.address = address; }
        }
        class FullName {
            String firstName, lastName;
        }
        class Address {
            String street, town, country;
        }
        class Comment {
            LocalDateTime timeStamp;
            String content;
        }
        

        查询:

        query.from(qCustomer).
            leftJoin(qCustomer._addressCustomerRef, qAddress)).
            leftJoin(qCustomer._commentCustomerRed).
            getResults(
               qCustomer.email_address, qCustomer.first_name, qCustomer.last_name, 
               qAddress.street, qAddress.town, qAddress.country, 
               qComment.creation_time_stamp, qComment.content);
        

        对我来说,理想的解决方案是重用MyBatis制图基础设施。
        另一种映射解决方案或自定义解决方案也是可接受
        注意:
        我也可以接受&#34;否定&#34;如果你展示一个替代方案,答案是:

        1. 具有与MyBatis相当的易用性和透明度 - 您只需通过检查代码知道执行哪个SQL
        2. 允许完全控制执行的SQL代码,特别是允许轻松编写三种DAO方法来检索“客户”:没有“地址”#39;和&#39; selfDescription&#39;信息,只有&#39;地址&#39;以及所有字段
        3. 允许对SQL代码进行编译时检查
        4. 不需要手动编码SQL中每个域类的映射。
        5. 替代方案应该适用于上面的例子。

          已经考虑过解决方案:

          • MyBatis&#39; Builder&#39; class(http://mybatis.github.io/mybatis-3/statement-builders.html):不够,因为列和表名仍然是字符串,所以它违反了要求(3)
          • Spring-data + JPA + QueryDSL:如果您展示如何满足要求(1)和(2)并且不提供更简单的解决方案,则可能是一个选项

1 个答案:

答案 0 :(得分:0)

Lukas Eder在这里给出了一个类似问题的优秀答案:Is it possible to combine MyBatis and QueryDSL/jOOQ?

他对映射问题的回答是使用Java 8 functional style capabilitiesmodelmapper等专用解决方案。

他还提到Spring JCache support作为缓存解决方案,this solution作为日志记录。