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

经验分享 程序员 微信小程序 职场和发展