MybatisPlus更新為null的字段及自定義sql注入
mybatis-plus在執(zhí)行更新操作,當(dāng)更新字段為 空字符串 或者 null 的則不會(huì)執(zhí)行更新。如果要將指定字段更新null,可以通過(guò)以下四種方式實(shí)現(xiàn)
1、全局配置(不推薦)
可以在 application.yml 配置文件中注入配置 GlobalConfiguration 屬性 update-strategy,
將 update-strategy 策略調(diào)整為 IGNORED,即忽略判斷策略。即可調(diào)整全局的驗(yàn)證策略。
# yml 配置:
mybatis-plus:
global-config:
db-config:
update-strategy: IGNORED
2、添加updateStrategy 注解(不推薦)
在實(shí)體類中將需要更新為null的字段上添加updateStrategy 注解,并將更新策略設(shè)置為IGNORED。
@TableField(value = "name", updateStrategy=FieldStrategy.IGNORED) private String name;
3、使用UpdateWrapper更新(當(dāng)屬性很多寫起來(lái)很麻煩)
通過(guò)baseMapper的UpdateWrapper將實(shí)體類的指定字段set為null。
baseMapper.update(sysUser, Wrappers.<SysUser>lambdaUpdate()
.set(SysUser::getOrgId, null)
.set(SysUser::getOrgName, null)
.eq(SysUser::getId, sysUser.getId())
);
4、Mybatis Plus 自定義SqlInjector sql注入器(推薦)
(1)、自定義sql注入器MySqlInjector
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.injector.DefaultSqlInjector;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import java.util.List;
public class MySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
// 根據(jù)id更新所有數(shù)據(jù)
methodList.add(new UpdateWithNullMethod());
return methodList;
}
}
(2)、方法對(duì)應(yīng)的實(shí)現(xiàn)類UpdateWithNullMethod
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.core.injector.AbstractMethod;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlSource;
import java.lang.reflect.Field;
import java.util.List;
import static java.util.stream.Collectors.joining;
/**
* @author :zzt
*/
@Slf4j
public class UpdateWithNullMethod extends AbstractMethod {
protected UpdateWithNullMethod() {
super("updateWithNull");
}
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
String sql = "<script>\nupdate %s %s where %s=#{%s}\n</script>";
final List<TableFieldInfo> fieldList = tableInfo.getFieldList();
for (TableFieldInfo tableFieldInfo : fieldList) {
final Class<? extends TableFieldInfo> aClass = tableFieldInfo.getClass();
try {
final Field fieldFill = aClass.getDeclaredField("fieldFill");
fieldFill.setAccessible(true);
fieldFill.set(tableFieldInfo, FieldFill.UPDATE);
} catch (NoSuchFieldException | IllegalAccessException e) {
log.error("獲取fieldFill失敗", e);
}
}
String setSql = this.sqlSet(tableInfo);
String sqlResult = String.format(sql, tableInfo.getTableName(), setSql, tableInfo.getKeyColumn(), tableInfo.getKeyProperty());
log.debug("sqlResult----->{}", sqlResult);
SqlSource sqlSource = languageDriver.createSqlSource(configuration, sqlResult, modelClass);
// 第三個(gè)參數(shù)必須和rootMapper的自定義方法名一致
return this.addUpdateMappedStatement(mapperClass, modelClass, "updateWithNull", sqlSource);
}
protected String sqlSet(TableInfo table) {
String sqlScript = table.getFieldList()
.stream().map(i -> this.getSqlSet(i, StringPool.EMPTY)).collect(joining(StringPool.NEWLINE));
sqlScript = SqlScriptUtils.convertTrim(sqlScript, "SET", null, null, ",");
return sqlScript;
}
public String getSqlSet(TableFieldInfo i, String prefix) {
String newPrefix = prefix == null ? StringPool.EMPTY : prefix;
String column = i.getColumn();
String update = i.getUpdate();
FieldFill fieldFill = i.getFieldFill();
String el = i.getEl();
// 默認(rèn):column=
String sqlSet = column + StringPool.EQUALS;
if (StringUtils.isNotEmpty(update)) {
sqlSet += String.format(update, column);
} else {
sqlSet += SqlScriptUtils.safeParam(newPrefix +el);
}
sqlSet += StringPool.COMMA;
if (fieldFill == FieldFill.UPDATE || fieldFill == FieldFill.INSERT_UPDATE) {
// 不進(jìn)行if包裹
return sqlSet;
}
return convertIf(sqlSet, convertIfProperty(newPrefix, column), i.getUpdateStrategy(),
i.getPropertyType().isPrimitive(), StringUtils.isCharSequence(i.getPropertyType()));
}
private String convertIfProperty(String prefix, String property) {
return StringUtils.isNotBlank(prefix)
? prefix.substring(0, prefix.length() - 1) + "['" + property + "']" : property;
}
private String convertIf(final String sqlScript, final String property, final FieldStrategy fieldStrategy,
boolean isPrimitive, boolean isCharSequence) {
if (fieldStrategy == FieldStrategy.NEVER) {
return null;
}
if (isPrimitive || fieldStrategy == FieldStrategy.IGNORED) {
return sqlScript;
}
if (fieldStrategy == FieldStrategy.NOT_EMPTY && isCharSequence) {
return SqlScriptUtils.convertIf(sqlScript, String.format("%s != null and %s !=''", property, property), false);
}
return SqlScriptUtils.convertIf(sqlScript, String.format("%s != null", property), false);
}
}
(2)、自定義基礎(chǔ)Mapper繼承BaseMapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**
* @description: 自定義mapper借口,mybatisPlus
* @author: zzt
*/
public interface MyBaseMapper<T> extends BaseMapper<T> {
/**
* 全字段更新,更新為null的字段
* @param obj 待更新對(duì)象
* @return 是否成功
*/
boolean updateWithNull(T obj);
}
最后直接調(diào)用即可。
到此這篇關(guān)于MybatisPlus更新為null的字段及自定義sql注入的文章就介紹到這了,更多相關(guān)MybatisPlus更新為null內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot 2 統(tǒng)一異常處理過(guò)程解析
這篇文章主要介紹了SpringBoot 2 統(tǒng)一異常處理過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
java啟動(dòng)jar包修改JVM默認(rèn)內(nèi)存問(wèn)題
這篇文章主要介紹了java啟動(dòng)jar包修改JVM默認(rèn)內(nèi)存問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
idea web項(xiàng)目沒(méi)有小藍(lán)點(diǎn)的的兩種解決方法
本文主要介紹了idea web項(xiàng)目沒(méi)有小藍(lán)點(diǎn)的的兩種解決方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07
SpringBoot集成ffmpeg實(shí)現(xiàn)視頻轉(zhuǎn)碼播放示例詳解
這篇文章主要為大家介紹了SpringBoot集成ffmpeg實(shí)現(xiàn)視頻轉(zhuǎn)碼播放示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-07-07
Spring boot+mybatis+thymeleaf 實(shí)現(xiàn)登錄注冊(cè)增刪改查功能的示例代碼
這篇文章主要介紹了Spring boot+mybatis+thymeleaf 實(shí)現(xiàn)登錄注冊(cè)增刪改查功能的示例代碼,本文通過(guò)實(shí)例圖文相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
Java 根據(jù)貸款年限對(duì)應(yīng)利率計(jì)算功能實(shí)現(xiàn)解析
這篇文章主要介紹了Java 根據(jù)貸款年限對(duì)應(yīng)利率計(jì)算功能實(shí)現(xiàn)解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10

