2016-07-22 54 views
2

使用Spring數據jpa和規範,我有要求在spring mvc中實現過濾/搜索功能。後端接收一個對象(ReportTemplateBean),它基本上是一個bean,其中一些字段代表前端的過濾器。Spring Data JPA中的動態查詢。重構

public class ReportTemplateBean implements Serializable { 

private static final long serialVersionUID = -3915391620260021813L; 

private Long id; 

private String property; 

private String city; 

private String state; 

private String zipCode; 

private String propertyStatus; 

private String realEstateRep; 
//more code 

我們有控制器

@RequestMapping(value = "/search", method = RequestMethod.GET) 
@ResponseBody 
public ReportBean search(@AuthenticationPrincipal ActiveUser activeUser, 
    @ModelAttribute("templateForm") ReportTemplateBean template, 
    Pageable pageable) throws GenericException { 
LOGGER.info("Pulling report requested"); 

ReportBean report = reportService.searchProperties(template, 
    pageable.getPageNumber(), pageable.getPageSize()); 

return report; 
} 

服務

@Override 
@Transactional(readOnly = true, timeout = 20) 
public ReportBean searchProperties(ReportTemplateBean template, 
    Integer pageNumber, Integer pageSize) throws GenericException, 
    TransactionTimedOutException { 
LOGGER.info("searchProperties({})", template); 

try { 
    // pageNumber = (pageNumber == null ? 0 : pageNumber); 
    // pageSize = (pageSize == null ? 10 : pageSize); 
    ReportTemplate t = reportTemplateMapper.beanToEntity(template); 
    List<PropertyBean> beans = new ArrayList<PropertyBean>(); 
    PropertySpecification spec = new PropertySpecification(t); 
    Page<Property> properties = propertyRepository.findAll(spec, 
     new PageRequest(pageNumber, pageSize, Sort.Direction.ASC, 
      "name")); 

然後它動態地建立查詢,但使用長IF鏈,我不喜歡它。這是規範。你可以注意到規格看起來很難看,而且SONAR抱怨這種方法的圓環複雜性(這很好)。

所以問題是,我如何重構規範(IF的)更面向對象的代碼? 在此先感謝。我想使用/實現像Spring Data JPA中的新特性(Query by Example)似乎如果你通過一個bean ExampleMatcher類將忽略bean字段中的空值,這幾乎是什麼我在尋找。忽略空值和空值。

+0

你想一個解決方案僅使用規範?我有一個類似的問題,但我解決它寫的查詢與@Query標註使用可選參數在我的倉庫 – amicoderozer

+0

會很好,使用規範,但並不是強制性的,我可以把您的解決方案來看看? – TheProgrammer

回答

0

我寫我的解決方案,給你另一種選擇,但正如我在評論說我不使用的規範,我很好奇,看看是否有人知道另一種方式做動態查詢春季JPA。

你可以用@Repository界面內@Query註釋寫自己的查詢。 在你的情況(假設ReportTemplateBean是你的實體,其主要關鍵是類型)它會像:

@Repository 
public interface ReportTemplateRepo extends JpaRepository<ReportTemplateBean, Long>{ 

    @Query("SELECT rb FROM ReportBeanTemplate rb JOIN ExampleTable et WHERE et.idTemplate = rb.id AND (:id is null OR :id = rb.id) AND (:city is null OR :city = rb.city) AND (:state is null OR :state = rb.state)") 
    public List<ReportTemplateBean> findTemplates(@Param("id") Long id, @Param("city") String city, @Param("state") String state); 
} 

您可以添加你想要的所有參數,它什麼時候通過爲空調用該方法。方法調用(在你的服務類)的

例子:

@Autowire 
ReportTemplateRepo templateRepo; 

public void invocation(ReportTemplateBean template){ 
    List<ReportTemplateBean> templateRepo.findTemplates(
     template.getId(), template.getCity(), template.getState()); 
    } 

這是我發現做這種查詢的唯一途徑。

+0

如果你有關係呢?我的意思是,我的bean有OneToOne和OneToMany關係。你的解決方案可以管理這個嗎?如何管理空時爲空?謝謝。 – TheProgrammer

+0

我沒有測試過,因爲我還沒有在我的項目一對多的關係,但是看看這個問題http://stackoverflow.com/questions/38614247/default-sort-on-a-spring-data -jpa - 庫法與 - 定製查詢和pageab。他使用關係和查詢動態參數,他說,它的工作原理。但是,我不知道如何處理這種關係時爲空 – amicoderozer

+0

感謝@amicoderozer,這個信息是非常有用的。 – TheProgrammer