2016-08-13 89 views
0

我的問題比第一眼所描述的要複雜一點。讓我試着解釋一下。 我有兩個實體單向多對多關係:JPA按多列對多列的順序排列

public class Category implements Serializable { 

    @Id 
    @Column(name = "ct_id") 
    @SequenceGenerator(name = "category_ct_id_seq", sequenceName = "category_ct_id_seq", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "category_ct_id_seq") 
    private Long id; 

    @Column(name = "ct_name_key") 
    private String nameKey; 

    @ManyToMany 
    @JoinTable(name = "category_2_country", 
      joinColumns = @JoinColumn(name = "c2c_category_id"), 
      inverseJoinColumns = @JoinColumn(name = "c2c_country_id")) 
    private Set<Country> countries; 
} 

public class Country { 

    @Id 
    @SequenceGenerator(name = "country_c_id_seq", sequenceName = "country_c_id_seq", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "country_c_id_seq") 
    @Column(name = "c_id") 
    private Long id; 

    @Column(name = "c_name") 
    private String name; 

    @Column(name = "c_iso_2_alpha") 
    private String isoAlpha2Code; 

而且我通過國家的ISO代碼(實際上,所有類別,這與被請求國的關係)檢索分類收集。爲此我寫了一個規範:

public class CategorySpecification implements Specification<Category> { 

    Country matchCountry; 

    @Override 
    public Predicate toPredicate(Root<Category> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder builder) { 

     return builder.isMember(matchCountry, root.get("countries")); 

    } 
} 

這工作得很好。問題是我需要爲每個國家的類別訂購優先級。 過渡表如下所示: enter image description here 因此,當我檢索給定國家的類別集合時,我希望根據此sort_order列對其進行排序。

相應的SQL查詢看起來是這樣,像這樣的事情:

SELECT * 
FROM category 
    JOIN category_2_country ON category.ct_id = category_2_country.c2c_category_id 
WHERE c2c_country_id = ? 
ORDER BY sort_order; 

但我應該怎麼做它在我的JPA實體?我該如何將它保存到數據庫中,這個順序需要動態改變(例如從管理面板)?

編輯:在數據庫表 對應的實體:

的一個國家 Country

而一個用於類別:

EDITED 2: 我已經成功地使用本機查詢實現期望的行爲,如下所示:

@Repository 
public interface CategoryRepository extends JpaRepository<Category, Long>, JpaSpecificationExecutor<Category> { 

    @Query(value = "SELECT ct.*\n" + 
      "FROM category ct\n" + 
      " JOIN category_2_country c2c ON ct.ct_id = c2c.c2c_category_id\n" + 
      " JOIN country c ON c2c.c2c_country_id = c.c_id\n" + 
      "WHERE c.c_iso_2_alpha = :countryIso\n" + 
      "ORDER BY c2c.sort_order", nativeQuery = true) 
    List<Category> findCategoriesForCountryOrdered(@Param("countryIso") String countryIso); 
} 

但還是希望有當你使用你正在使用JpaRepositoryJpaSpecificationExecutor規格做這件事情

+1

[This](http://stackoverflow.com/questions/5127129/mapping-many-to-many-association-table-with-extra-columns)可能會有所幫助。 –

+0

我之前看到過這個線程,但仍然希望比僅僅因爲優先級列重構所有實體更簡單的解決方案 – DruidKuma

回答

1

更JPA /休眠方式。 JpaSpecificationExecutor API給我們一個方法findAll(Specification<T> spec, Sort sort)

使用Sort類,您可以指定您想要對結果列表進行排序的屬性(和方向)。

下面是文檔:Sort

編輯: 一些搜索後 - 不幸的是,沒有映射關聯表進入休眠,你不能命令由/排序sort_order財產。這與JPQL有關,只能對實體中的映射屬性起作用 - 如果不映射它們,則無法到達DB中的表。

因此,您可以映射關聯表並創建規範,該規範將兩個表連接起來,並通過sort_order創建排序。

+0

感謝您的一個很好的答案。但我無法傳遞給排序只是數據庫列的名稱。它必須是「類別」或「國家」的財產,但不能是許多表格中的列名稱。可能是因爲我沒有任何選擇,而不是將我的ManyToMany表變成單獨的實體? :( – DruidKuma

+0

你必須從映射的實體傳遞一個變量名,在你的例子中:'country.sortOrder'假設'Country'類具有'sortOrder'字段,這是否正確? – ByeBye

+0

不幸的是,sortOrder具體而言不是國家,而是國家/地區映射 – DruidKuma