2014-10-27 118 views
4

我正在考慮使用Spring-Data + QueryDSL + JDBC來替換(或增強)當前使用的MyBatis。
我的理由是:Spring-Data + QueryDSL + JDBC:如何將查詢結果映射到域對象?

  1. 列名的編譯時間檢查
  2. SQL tatements和IDE自動完成
  3. 能力寫在Java集合單元測試針對同一代碼的
  4. 編譯時間檢查將工作與實際分貝,這比簡單得多,更快的預填充一個DB
  5. 它比MyBatis的更簡潔 - 無需單獨XxxMapper.javaXxxMapper.xml的DAO信用證項下艾爾

然而,我看到以下問題:

  1. 沒有爲查詢結果映射到域對象沒有基礎設施。 QueryDSL的QBeanMappingProjection,Spring的BeanPropertyRowMapper和Spring Data的OneToManyResultSetExtractor似乎太低級,見下文。
  2. 沒有開箱會話/事務級緩存的這MyBatis的免費的午餐
  3. 沒有開箱的SQL語句和結果記錄這MyBatis的

免費的午餐因爲我問了的單個問題讓我們專注於我認爲最重要的問題的映射。
所以我的問題是:
是否有任何方便的解決方案將QueryDSL的SQLQuery結果映射到域對象,類似於MyBatis或JPA提供的?也就是說,映射基於一些簡單的配置,無論是XML,註釋還是簡單的Java?

特別地,我對以下內容:

  1. 映射列到自定義類型,例如字符串列到電子郵件地址 Java對象
  2. 將一組列映射到嵌入對象,例如,分組{名字,姓氏}全名 Java對象
  3. 支持一對多的關係,例如能夠以提取含有地址列表的顧客(多個)對象。

總之,我需要一個簡單的方法來從下面的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映射基礎結構。
另一種映射解決方案或自定義的解決方案也是可以接受的。
注:
如果你顯示一個替代我也可以接受「否定」的答案:

  1. 擁有的易用性和透明度媲美的MyBatis的 - 你總是知道哪些SQL是通過簡單地檢查執行代碼
  2. 允許在執行SQL代碼的完全控制,特別是,可以輕鬆地編寫檢索「客戶」三種道街方法:無「地址」和「selfDescription」的信息,只是以「地址」,並與所有的字段
  3. 允許編譯時檢查您的SQL代碼
  4. 不需要手動編碼來自SQL的每個單個域類的映射。

替代應該在例如很好地工作的上方。已經考慮

解決方案:

  • MyBatis的 '生成器' 級(http://mybatis.github.io/mybatis-3/statement-builders.html):不夠,因爲列和表名仍然是字符串,因此它違反了要求(3)
  • 春數據+ JPA + QueryDSL:如果您呈現怎樣的要求(1)和(2)可以得到滿足,如果沒有簡單的解決方案將提供

回答