2017-05-10 92 views
0

我想比較一個字符串對錶中的每一列。有沒有更簡單的方法來做到這一點?全文搜索Java規範/謂詞

public class MySpec implements Specification<Tbl> { 

    private Tbl searchCriteria; 

    public MySpec(Tbl searchCriteria){ 
     this.searchCriteria = searchCriteria; 
    } 

    @Override 
    public Predicate toPredicate(Root<Tbl> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 

     List<Predicate> textPredicates = new ArrayList<>(); 
     String searchText = "%" + searchCriteria.getSearchText() + "%"; 

     textPredicates.add(cb.like(root.get("col1"), searchText)); 
     textPredicates.add(cb.like(root.get("col2"), searchText)); 
     textPredicates.add(cb.like(root.get("col3"), searchText)); 
     textPredicates.add(cb.like(root.get("col4"), searchText)); 
     textPredicates.add(cb.like(root.get("col5"), searchText)); 
     textPredicates.add(cb.like(root.get("col6"), searchText)); 
     textPredicates.add(cb.like(root.get("col7"), searchText)); 
     textPredicates.add(cb.like(root.get("col8"), searchText)); 
     textPredicates.add(cb.like(root.get("col9"), searchText)); 

     return query.where(cb.or(textPredicates.toArray(new Predicate[0]) 
        .distinct(true).getRestriction(); 
    } 
} 

我不希望有我每次一個新列添加到表時更改規格代號。另一個選項是一個單獨的表格,它將在字符串中保存每列的連接版本。如:

TBL 
Col1 | Col2 | Col3 | Col4 
----------------------------------------- 
1 | "Name" | "Value" | "Other Value" 


TBL_CACHE 
Col1 | Col2 
------------------------------ 
1 | "Name Value OtherValue" 

但我不希望爲每個表另一個表我想全文搜索上,我不想填充此數據或創建一個SQL工作做的維護自動。

回答

1

用於hibernate從實體中檢索列的列表。

String[] columnNames = getSessionFactory().getClassMetadata(Entity.class).getPropertyNames(); 

對於JPA你可以通過場

for (Field field : entity.getClass().getDeclaredFields()) { 
    Column column = field.getAnnotation(Column.class); 
    if (column != null) { 
     columnNames.add(column.name()); 
    } 
} 

的列表,如果你註釋的方法,你可以使用相同的方法。

還要檢查thisthis。還有一種獲取元數據的方法。

然後使用列列出jusst在一個循環中添加您的條件。

+0

謝謝。我沒有考慮使用反射來獲取列名。我一直堅持認爲root會有getAll解決方案。這應該很好。 – jDub9

0

你可以得到從CriteriaBuilder大小(),並創建一個循環。這假定列從1開始並以列數結束。

int sz = cb.size(); 
for (int ii = 1; ii <= sz; ii++) { 
    String textIndex = "" + ii; 
    textPredicates.add(cb.like(root.get("col" + textIndex), searchText)); 
} 
+0

嘿達科他州,遺憾的混亂,但COL1,COL2,COL3只是示例數據。真正的列名不是那樣的。真實數據就像名稱,類型,聯繫人,ID。我怎樣才能找到沒有硬編碼他們的列名稱。我不想強調列名的原因是因爲如果明天添加新列,我將需要再次更改此規範。無論如何只要說一些像cb.like(root,searchText)來比較根內的每一列? – jDub9