- 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>