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 中
-
value()type()指定一个实现SQL Provider方法的类型。 -
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();
}
}
}
databaseId(3.5.5以上可用), 如果有一个配置好的DatabaseIdProvider, MyBatis 会加载不带databaseId属性和带有匹配当前数据库databaseId属性的所有语句。如果同时存在带databaseId和不带databaseId属性的相同语句,则后者会被舍弃。