mybatis-plus自定义、扩展BaseMapper方法
1.自定义mapper
编写自定义mapper:CustomBaseMapper,类似于mybatis中自定义的IBaseMapper
所有的dao方法实现CustomBaseMapper。在该方法中定义需要实现的方法。
这里以updateByIdWithNull(更新所有字段,包括为null的字段,类似于mybatis中的updateByPrimaryKey)
代码如下:
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
public interface CustomBaseMapper<T> extends BaseMapper<T> {
int updateByIdWithNull(@Param(Constants.ENTITY) T entity);
}
2.编写方法实现类,完成sql拼写
mybatis-plus中BaseMapper定义方法继承自AbstractMethod。
这里代码参考了mybatis-plus中的updateById方法,核心区别为标红处部分(是否忽略IF包裹部分)。
代码如下:
import static java.util.stream.Collectors.joining;
import java.util.Objects;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
public class UpdateByIdWithNull extends AbstractMethod {
private static final long serialVersionUID = 1L;
private static String methodName = "updateByIdWithNull";
private static String methodSql = "<script>
UPDATE %s %s WHERE %s=#{%s} %s
</script>";
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
final String additional = optlockVersion(tableInfo) + tableInfo.getLogicDeleteSql(true, true);
String sql = String.format(methodSql, tableInfo.getTableName(),
sqlSet(tableInfo.isWithLogicDelete(), false, tableInfo, false, ENTITY, ENTITY_DOT),
tableInfo.getKeyColumn(), ENTITY_DOT + tableInfo.getKeyProperty(), additional);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
return addUpdateMappedStatement(mapperClass, modelClass, methodName, sqlSource);
}
@Override
protected String sqlSet(boolean logic, boolean ew, TableInfo table, boolean judgeAliasNull, final String alias,
final String prefix) {
String sqlScript = getAllSqlSetWithOutIfNull(table, logic, prefix);
if (judgeAliasNull) {
sqlScript = SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", alias), true);
}
if (ew) {
sqlScript += NEWLINE;
sqlScript += SqlScriptUtils.convertIf(SqlScriptUtils.unSafeParam(U_WRAPPER_SQL_SET),
String.format("%s != null and %s != null", WRAPPER, U_WRAPPER_SQL_SET), false);
}
sqlScript = SqlScriptUtils.convertSet(sqlScript);
return sqlScript;
}
private String getAllSqlSetWithOutIfNull(TableInfo tableInfo, boolean ignoreLogicDelFiled, final String prefix) {
final String newPrefix = prefix == null ? EMPTY : prefix;
return tableInfo.getFieldList().stream()
.filter(i -> {
if (ignoreLogicDelFiled) {
return !(tableInfo.isWithLogicDelete() && i.isLogicDelete());
}
return true;
}).map(i -> i.getSqlSet(true, newPrefix)).filter(Objects::nonNull).collect(joining(NEWLINE));
}
}
2.将该方法注册进spring,以便服务启动时扫描
2.1实现SqlInjector
代码如下:
import java.util.List;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
public class MySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
methodList.add(new UpdateByIdWithNull());
return methodList;
}
}
2.2注册sqlInjector
代码如下:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyConfiguration {
@Bean
public MySqlInjector sqlInjector() {
return new MySqlInjector();
}
}
3.特别注意。
当更新字段为null,无法进行类型转换,会报错。所以需要为实体类添加jdbcType
