Mybatis @SelectProvider @DeleteProvider @InsertProvider @UpdateProvider

755 阅读2分钟

mybatis-3 docs

代码在这里

MyBatis3提供的这个注解可以让程序员用自定义的类构造SQL语句 使用这些备选的SQL注解可以指定返回SQL语句的类和方法。

  • @SelectProvider
  • @DeleteProvider
  • @InsertProvider
  • @UpdateProvider
@Mapper
public interface StudentMapper {
    @SelectProvider(method = "findAll", type = StudentMapper.SelectProviderSql.class)
    List<Student> findAll();

    @SelectProvider(method = "findById", type = StudentMapper.SelectProviderSql.class)
    Optional<Student> findById(@Param("id") String id);

    @SelectProvider(method = "findByIds", type = StudentMapper.SelectProviderSql.class)
    List<Student> findByIds(@Param("ids") List<String> ids);

    class SelectProviderSql{
        public static String findAll() {
            SQL sql = new SQL();
            sql.SELECT("*");
            sql.FROM("students");
            return "<script>" + sql + "</script>";
        }

        public static String findById(String id) {
            return new SQL() {{
                SELECT("id", "name");
                FROM("students");
                if (!StringUtils.isEmpty(id)) {
                    WHERE("id = #{id, javaType=String, jdbcType=VARCHAR}");
                }
            }}.toString();
        }

        public static String findByIds(List<String> ids) {
            return new SQL() {
                {
                    SELECT("id", "name");
                    FROM("students");
                    if (!CollectionUtils.isEmpty(ids)) {
                        WHERE("id in (" + String.join(",", ids) + ")");
                    }
                }
            }.toString();
        }
    }
}

@SelectProvider

  1. value() type() 指定一个实现SQL Provider方法的类型。

  2. method 在type指定的类中指定一个提供SQL的方法。在3.5.1后可以省略,如果省略则按照一下规则

  • 如果type指定的类实现了org.apache.ibatis.builder.annotation.ProviderMethodResolver,MyBatis会使用它返回的方法。
@Mapper
public interface StudentMapper {
    @SelectProvider(type = StudentMapper.SelectProviderSql.class)
    List<Student> findAll();

    @SelectProvider(type = StudentMapper.SelectProviderSql.class)
    Optional<Student> findById(@Param("id") String id);

    @SelectProvider(type = StudentMapper.SelectProviderSql.class)
    List<Student> findByIds(@Param("ids") List<String> ids);

    class SelectProviderSql implements ProviderMethodResolver {
        public static String findAll() {
            SQL sql = new SQL();
            sql.SELECT("*");
            sql.FROM("students");
            return "<script>" + sql + "</script>";
        }

        public static String findById(String id) {
            return new SQL() {{
                SELECT("id", "name");
                FROM("students");
                if (!StringUtils.isEmpty(id)) {
                    WHERE("id = #{id, javaType=String, jdbcType=VARCHAR}");
                }
            }}.toString();
        }

        public static String findByIds(List<String> ids) {
            return new SQL() {
                {
                    SELECT("id", "name");
                    FROM("students");
                    if (!CollectionUtils.isEmpty(ids)) {
                        WHERE("id in (" + String.join(",", ids) + ")");
                    }
                }
            }.toString();
        }
    }
}
  • 如果没有实现org.apache.ibatis.builder.annotation.ProviderMethodResolver,MyBatis将从指定的类型中搜索并使用一个名为provideSql的后备方法。

provideSql 不是providerSql
所有方法都会使用provideSql方法

@Mapper
public interface StudentMapper {
    @SelectProvider(type = StudentMapper.SelectProviderSql1.class)
    List<Student> findAll();

    @SelectProvider(type = StudentMapper.SelectProviderSql2.class)
    Optional<Student> findById(@Param("id") String id);

    @SelectProvider(type = StudentMapper.SelectProviderSql3.class)
    List<Student> findByIds(@Param("ids") List<String> ids);


    class SelectProviderSql1 {
        public static String provideSql() {
            SQL sql = new SQL();
            sql.SELECT("*");
            sql.FROM("students");
            return "<script>" + sql + "</script>";
        }
    }
    class SelectProviderSql2 {
        public static String provideSql(String id) {
            return new SQL() {{
                SELECT("id", "name");
                FROM("students");
                if (!StringUtils.isEmpty(id)) {
                    WHERE("id = #{id, javaType=String, jdbcType=VARCHAR}");
                }
            }}.toString();
        }
    }
    class SelectProviderSql3 {
        public static String provideSql(List<String> ids) {
            return new SQL() {
                {
                    SELECT("id", "name");
                    FROM("students");
                    if (!CollectionUtils.isEmpty(ids)) {
                        WHERE("id in (" + String.join(",", ids) + ")");
                    }
                }
            }.toString();
        }
    }
}
  1. databaseId(3.5.5以上可用), 如果有一个配置好的 DatabaseIdProvider, MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。如果同时存在带 databaseId 和不带 databaseId 属性的相同语句,则后者会被舍弃。