自定义语句驱动注解(@Lang)

Exisi 2021-03-27 07:47:57
Categories: Tags:
  • Mybatis 3.2版本之后,提供了 LanguageDriver 接口,我们可以使用该接口自定义SQL的解析方式,LanguageDriver 的默认实现类为 XMLLanguageDriver RawLanguageDriver

 

  • MyBatis 中的 @Lang 注解是用于指定自定义语言驱动的注解。它可以在 Mapper 接口方法上使用,用于指定该方法使用的SQL语言驱动。@Lang 注解需要传入一个实现了 LanguageDriver 接口的类作为参数,这个类将会被用来解析 Mapper 接口方法上的 SQL 语句。通过自定义 LanguageDriver,我们可以实现更加灵活和高效的SQL语句生成方式。

 

  • 通过自定义 LanguageDriver 优化 select in 语句

示例

  • UserMapper.java

public interface UserMapper {

@Lang(SimpleSelectInLangDriver.class)

@Select("SELECT * " +

        "FROM users " +

        "WHERE id IN " +

        "<foreach item='item' index='index' collection='list'open='(' separator=',' close=')'>" +

        "#{item}" +

        "</foreach>")

List<User> selectUsersByUserId(List<Integer> userIdList);

}

 

  • SimpleSelectInLangDriver.class

public class SimpleSelectInLangDriver extends XMLLanguageDriver implements LanguageDriver {

 

    private static 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\" open=\"(\" " +

                                        "separator=\",\" close=\")\" >#{_item}</foreach>");

        }

 

 

        script = "<script>" + script + "</script>";

        return super.createSqlSource(configuration, script, parameterType);

    }

}

 

  • 通过自定义 LanguageDriver 优化实体类到 update 语句的直接转换

示例

  • UserMapper.java

public interface UserMapper {

@Insert("INSERT INTO users (#{user})")

@Lang(SimpleInsertLangDriver.class)

void insertUserDAO(User user);

}

 

  • SimpleSelectInLangDriver.class

public class SimpleInsertLangDriver 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()) {

            StringBuilder sb = new StringBuilder();

            StringBuilder tmp = new StringBuilder();

            sb.append("(");

 

            for (Field field : parameterType.getDeclaredFields()) {

                sb.append(CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName()) + ",");

                tmp.append("#{" + field.getName() + "},");

            }

 

            sb.deleteCharAt(sb.lastIndexOf(","));

            tmp.deleteCharAt(tmp.lastIndexOf(","));

            sb.append(") values (" + tmp.toString() + ")");

 

            script = matcher.replaceAll(sb.toString());

            script = "<script>" + script + "</script>";

        }

 

        return super.createSqlSource(configuration, script, parameterType);

    }

}

 

  • 通过自定义 LanguageDriver 优化实体类下划线属性到驼峰命名的转换,映射到 update 语句

示例

  • UserMapper.java

public interface UserMapper {

@Update("UPDATE users (#{user}) WHERE id = #{id}")

@Lang(SimpleUpdateLangDriver.class)

void updateUsersById(User user);

}

 

  • SimpleSelectInLangDriver.class

public class SimpleUpdateLangDriver 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()) {

            StringBuilder sb = new StringBuilder();

            sb.append("<set>");

 

            for (Field field : parameterType.getDeclaredFields()) {

                String tmp = "<if test=\"_field != null\">_column=#{_field},</if>";

                sb.append(tmp.replaceAll("_field", field.getName()).replaceAll("_column",

                        CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName())));

            }

 

            sb.deleteCharAt(sb.lastIndexOf(","));

            sb.append("</set>");

 

            script = matcher.replaceAll(sb.toString());

            script = "<script>" + script + "</script>";

        }

 

        return super.createSqlSource(configuration, script, parameterType);

    }

}

 

 

来自 < https://blog.csdn.net/ExcellentYuXiao/article/details/53262928>