- 动态 SQL 构建注解用于指定一个类或方法,该类或方法返回一个字符串类型的SQL语句,用于查询插入更新和删除操作
注解 |
说明 |
@SelectProvider |
用于构建动态查询SQL |
@InsertProvider |
用于构建动态新增SQL |
@UpdateProvider |
用于构建动态更新SQL |
@DeleteProvider |
用于构建动态删除SQL |
- 动态 SQL 构建注解都有以下属性:
参数 |
描述 |
type |
用于指定类名 (type 属性是 value 的别名) |
value |
用于指定类名 |
method |
指定工具类的方法,必须是 public 的,返回值必须为 String,可以为 static |
databaseId |
MyBatis 3.5.5以上可用, 如果有一个配置好的 DatabaseIdProvider, MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。如果同时存在带 databaseId 和不带 databaseId 属性的相同语句,则后者会被舍弃。 |
示例
- UserMapper.java
public interface UserMapper(){
@SelectProvider(type = UserSqlBuilder.class, method = "buildGetUserByIdSql")
UserInfo getUserById(Integer userId);
@InsertProvider(type=UserSqlBuilder.class, method = "buildInsertUserSql")
Integer updateUser(UserInfo user);
@UpdateProvider(type = UserSqlBuilder.class, method = "buildUpdateUserSql")
public int updateUser(UserInfo user);
@DeleteProvider(type = UserSqlBuilder.class, method = "buildDeleteUserSql")
public int deleteUser(Integer userId);
}
- UserSqlBuilder.java
public class UserSqlBuilder {
public String buildGetUserByIdSql(@Param("userId") Integer userId) {
return new SQL() {
{
SELECT("*");
FROM("tb_user");
WHERE("user_id = #{userId}");
}
}.toString();
}
public String buildInsertUserSql(UserInfo user) {
return new SQL() {
{
INSERT_INTO("tb_user");
VALUES("user_name", "#{userName}");
VALUES("blog_url", "#{blogUrl}");
VALUES("blog_remark", "#{blogRemark}");
}
}.toString();
}
public String buildUpdateUserSql(UserInfo user) {
return new SQL() {
{
UPDATE("tb_user");
SET("user_name = #{userName} ,blog_url=#{blogUrl} ,blog_remark=#{blogRemark}");
WHERE("user_id = #{userId}");
}
}.toString();
}
public String buildDeleteUserSql(@Param("userId") Integer userId) {
return new SQL() {
{
DELETE_FROM("tb_user");
WHERE("user_id = #{userId}");
}
}.toString();
}
}
- 多个参数的动态 SQL 构建注解
示例
- UserMapper.java
public interface UserMapper(){
@SelectProvider(type = UserSqlBuilder.class, method = "buildGetUsersByName")
List<User> getUsersByName(@Param("name") String name, @Param("orderByColumn") String orderByColumn);
}
- UserSqlBuilder.java
public class UserSqlBuilder {
// 如果不使用 @Param,就应该定义与 mapper 方法相同的参数
public static String buildGetUsersByName(
final String name, final String orderByColumn) {
return new SQL() {
{
SELECT("*");
FROM("users");
WHERE("name like #{name} || '%'");
ORDER_BY(orderByColumn);
}
}.toString();
}
// 如果使用 @Param,就可以只定义需要使用的参数
public static String buildGetUsersByName(@Param("orderByColumn") final String orderByColumn) {
return new SQL() {
{
SELECT("*");
FROM("users");
WHERE("name like #{name} || '%'");
ORDER_BY(orderByColumn);
}
}.toString();
}
}
注
- type 和 value 属性,必须指定任意一个
- 在 MyBatis 3.5.1 后的版本中,提供了 ProviderMethodResolver 接口,只需要实现这个接口,就会将映射器方法的调用解析到实现的同名方法上,而无需使用 method 属性指定方法
示例
- UserSqlProvider.java
// 在你的 provider 类中实现 ProviderMethodResolver 接口
public class UserSqlProvider implements ProviderMethodResolver {
// 默认实现中,会将映射器方法的调用解析到实现的同名方法上
public static String getUsersByName(final String name) {
return new SQL() {
{
SELECT("*");
FROM("users");
if (name != null) {
WHERE("name like #{value} || '%'");
}
ORDER_BY("id");
}
}.toString();
}
}
- UserMapper.java
public interface UserMapper() {
@SelectProvider(UserSqlProvider.class)
List<User> getUsersByName(String name);
}
- 但是在 MyBatis 3.5.1 后的版本中,如果在全局配置中指定了 defaultSqlProviderType,两个属性都可以忽略,如果省略,MyBatis 将使用 defaultSqlProviderType 所指定的类
示例
- UserTest.java
Configuration configuration = new Configuration();
// 让所有映射方法在同一个 sql provider 类里面
configuration.setDefaultSqlProviderType(TemplateFilePathProvider.class);
- UserMapper.java
public interface UserMapper {
@SelectProvider // 等价于 @SelectProvider(TemplateFilePathProvider.class)
User findUser(int id);
@InsertProvider // 等价于 @InsertProvider(TemplateFilePathProvider.class)
void createUser(User user);
@UpdateProvider // 等价于 @UpdateProvider(TemplateFilePathProvider.class)
void updateUser(User user);
@DeleteProvider // 等价于 @DeleteProvider(TemplateFilePathProvider.class)
void deleteUser(int id);
}
- 从版本 3.5.1 开始,可以省略 method 属性,MyBatis 将会使用 ProviderMethodResolver 接口解析方法的具体实现。如果解析失败,MyBatis 将会使用名为 provideSql 的降级实现
来自 <https://mybatis.org/mybatis-3/zh/java-api.html#sqlSessions>