TK-Mybatis的Example的一些用法


TK-Mybatis的Example的一些用法

背景

最近項目中使用tk-mybatis遇到了一些問題:

問題詳情:

(A=A1 and B=B1) or (A=A2 and B=B2) and C IN (C1,C2)

抽象一點:

A or B and C

實際執行方式為:

A or (B and C)

實際期望:

(A or B ) and C

代碼

有問題的代碼為:

    List<Map<String, String>> properties = new ArrayList<>();
    Example example = new Example(Country.class);

    properties.forEach(map -> {
        Example.Criteria criteria = example.createCriteria();
        map.forEach((key, value) -> criteria.andEqualTo(key, value));
        example.or(criteria);
    });

    Example.Criteria criteria = example.createCriteria()
        .andIn("countryname", Arrays.asList("CN", "US", "UK"));

    example.and(criteria);

    CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);

    mapper.selectByExample(example);

最終生成的sql為:

(A=A1 and B=B1) or (A=A2 and B=B2) and C IN (C1,C2)

每個粗體代表一個criteria

很明顯不符合預期

解決方案

只能手寫sql進行組裝

// 這里組裝sql
    String sql = properties.stream()
        .map(map ->
            map.entrySet()
                .stream()
                .map(item -> String.format("`%s` = '%s'", item.getKey(), item.getValue()))
                .collect(Collectors.joining(" and ", " ( ", " ) "))
        ).collect(Collectors.joining(" or "));
//這里只有一個criteria 就可以避免問題
    example.createCriteria().andCondition(sql);

//其他一樣的
    Example.Criteria criteria1 = example.createCriteria()
        .andIn("countryname", Arrays.asList("CN", "US", "UK"));
    
    example.and(criteria1);

    CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);

    mapper.selectByExample(example);

生成sql為:

((A=A1 and B=B1) or (A=A2 and B=B2)) and C IN (C1,C2)

每個粗體代表一個criteria

核心解決方案

讓OR語句生成一個criteria,之后就不會影響后續的步驟了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM