优雅解决Spring-boot中mybatis注解方式foreach循环

SpringBoot workingTime 6646℃ 0评论

e4562a20d4b5ac5f6cdf2d8bc7c391f5.png

因为spring-boot是注解的形式进行配置,为了优雅与匹配,所以我们一般mybatis也舍弃xml的形式,换成注解。

但是在以注解的形式写sql的时候,会发现foreach循环是这样的:


@Select({"<script>",
         "SELECT *", 
         "FROM user",
         "WHERE id IN", 
           "<foreach item='item' index='index' collection='list'",
             "open='(' separator=',' close=')'>",
             "#{item}",
           "</foreach>",
         "</script>"}) 
List<User> selectUsers(@Param("userIds") List<Intger> userIds);

是不是看着很难受,感觉还不如写xml呢…

那么如何优雅的解决这个问题呢?我们通过实现自己的LanguageDriver,在MyBatis编译语句前,将我们自定义的标签替换为了动态SQL语句

在项目随便一个包,新建如下类:


public class SimpleSelectInExtendedLanguageDriver 
                        extends XMLLanguageDriver implements LanguageDriver {
    
    private final Pattern inPattern = Pattern.compile("\\(#\\{(\\w+)\\}\\)");

    @Override
    public SqlSource createSqlSource(Configuration configuration, 
                                        String script, Class<?> parameterType) {
        
        Matcher matcher = inPattern.matcher(script);
        if (matcher.find()) {
            script = matcher.replaceAll("(<foreach collection=\"$1\" item=\"__item\" separator=\",\" >#{__item}</foreach>)");
        }
        
        script = "<script>" + script + "</script>";
        return super.createSqlSource(configuration, script, parameterType);
    }
}

接下来在mapper中,如果需要使用foreach循环,好比我们使用查询特定id的数据:


select username ,sex from users where uid in (1,5,10,20)

在mybatis注解中就可以这么写:


@Lang(SimpleSelectInExtendedLanguageDriver.class)
@Select("SELECT * FROM users WHERE uid IN (#{userIds})")
List<User> selectUsers(@Param("userIds") List<String> userIds);

注意:

  • 需要@Lang(SimpleSelectInExtendedLanguageDriver.class)
  • (#{userIds})括号中不能有空格,应为在正则中没有匹配其他符号。
  • @Lang()注解只能加载UsersMapper的方法中,在UsersProvider的方法中不生效。

转载请注明:R&M » 优雅解决Spring-boot中mybatis注解方式foreach循环

喜欢 (0)or分享 (0)
发表我的评论
取消评论

表情

备案号:京ICP备14044161号;联系我:rm@rmworking.com