Mybatis-plus 自动装配
Mysql 分页
mybatis-plus 自动填充数据(默认开启)
多租户自动配置
package com.np.pm.common.core.properties;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import java.util.ArrayList;
import java.util.List;
/**
* 多租户配置
*
* @author tangxingpeng
* @date 2021/1/26 23:32
*/
@Setter
@Getter
@ConfigurationProperties(prefix = "pm.tenant")
@RefreshScope
public class TenantProperties {
/**
* 是否开启多租户
*/
private Boolean enable = false;
/**
* 配置不进行多租户隔离的表名
*/
private List<String> ignoreTables = new ArrayList<>();
/**
* 配置不进行多租户隔离的sql
* 需要配置mapper的全路径如:com.central.user.mapper.SysUserMapper.findList
*/
private List<String> ignoreSqls = new ArrayList<>();
}
package com.np.pm.common.datasource.configure;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.np.pm.common.core.context.TenantContextHolder;
import com.np.pm.common.core.properties.TenantProperties;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.NullValue;
import net.sf.jsqlparser.expression.StringValue;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
/**
* 多租户自动配置
*
* @author tangxingpeng
* @date 2021/1/27 14:17
*/
@EnableConfigurationProperties(TenantProperties.class)
public class TenantAutoConfigure {
@Autowired
private TenantProperties tenantProperties;
@Bean
public TenantLineHandler tenantHandler() {
return new TenantLineHandler() {
/**
* 获取租户id
*/
@Override
public Expression getTenantId() {
String tenant = TenantContextHolder.getTenant();
if (tenant != null) {
return new StringValue(TenantContextHolder.getTenant());
}
return new NullValue();
}
/**
* 获取租户列名
*/
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
/**
* 过滤不需要根据租户隔离的表
* @param tableName 表名
*/
@Override
public boolean ignoreTable(String tableName) {
return tenantProperties.getIgnoreTables().stream().anyMatch(
(e) -> e.equalsIgnoreCase(tableName)
);
}
};
}
}
update增强
项目的mybatis-plus默认的所有策略都是NOT_NULL(见pm-configure)
如果遇到向导更新null
值时会忽略更新的问题
方式一(手动更新null):
UpdateWrapper<T> tLambdaUpdateWrapper = new UpdateWrapper<T>(); tLambdaUpdateWrapper.set("field", null); tLambdaUpdateWrapper.eq(idTableFeild.value(), id); return SqlHelper.retBool(baseMapper.update(null, tLambdaUpdateWrapper));
方式二(前端传全部数据,后端全更新):
官方文档:https://mp.baomidou.com/guide/sql-injector.html
public void updateEntity(SysMenu entity) {
entity = this.beforeTreeSave(entity);
baseMapper.updateAllById(entity);
}
package com.np.pm.common.datasource.inteceptor;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.np.pm.common.datasource.inteceptor.methods.UpdateAllById;
import java.util.List;
/**
* @author tangxingpeng
* @date 2021/8/3 10:14
*/
public class UpdateSqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass);
methodList.add(new UpdateAllById());
return methodList;
}
}
package com.np.pm.common.datasource.inteceptor.methods;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import java.util.Objects;
import static java.util.stream.Collectors.joining;
/**
* 根据 ID 更新所有字段
*
* @author tangxingpeng
* @date 2021/8/3 10:19
*/
public class UpdateAllById extends AbstractMethod {
public UpdateAllById() {
}
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
SqlMethod sqlMethod = SqlMethod.UPDATE_BY_ID;
final String additional = optlockVersion(tableInfo) + tableInfo.getLogicDeleteSql(true, true);
String sql = String.format(sqlMethod.getSql(), 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, getMethod(sqlMethod), sqlSource);
}
/**
* SQL 更新 set 语句
*
* @param logic 是否逻辑删除注入器
* @param ew 是否存在 UpdateWrapper 条件
* @param table 表信息
* @param alias 别名
* @param prefix 前缀
* @return sql
*/
@Override
protected String sqlSet(boolean logic, boolean ew, TableInfo table, boolean judgeAliasNull, final String alias,
final String prefix) {
String sqlScript = getAllSqlSet(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;
}
/**
* 获取所有的 sql set 片段
*
* @param ignoreLogicDelFiled 是否过滤掉逻辑删除字段
* @param prefix 前缀
* @return sql 脚本片段
*/
public String getAllSqlSet(TableInfo table, boolean ignoreLogicDelFiled, final String prefix) {
final String newPrefix = prefix == null ? EMPTY : prefix;
return table.getFieldList().stream()
.filter(i -> {
if (ignoreLogicDelFiled) {
return !(table.isWithLogicDelete() && i.isLogicDelete());
}
return true;
}).map(i -> i.getSqlSet(true, newPrefix)).filter(Objects::nonNull).collect(joining(NEWLINE));
}
@Override
public String getMethod(SqlMethod sqlMethod) {
return "updateAllById";
}
}
package com.np.pm.common.springboot.starter.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
/**
* <p>mapper 基础接口</p>
*
* @Author: zhaojiwei
* @Versions 1.0
* @Date: 2021/7/26 下午12:48
*/
public interface PMBaseMapper<T> extends BaseMapper<T> {
/**
* 根据 ID 全部修改
*
* @param entity 实体对象
*/
int updateAllById(@Param(Constants.ENTITY) T entity);
}