修改对象的null值属性为null值 ,听着有点奇怪哦。
使用mybatis的 updateById() 方法进行对象更新的操作。
或使用 update()加lambada表达式 的方式进行更新。
demoDao.updateById(demo);
demoDao.update(null, new LambdaUpdateWrapper<Demo>().set(Demo::getName, "link").eq(Demo::getId(), 1111L));
demoDao.update(demo, new LambdaUpdateWrapper<Demo>().eq(Demo::getId(), 1111L));
问题在于,使用 updateById() 方法只会更新非null的属性,null值的属性不会进行更新。
虽然我们可以修改mybatis的配置让它达到如果是null值也进行更新的效果。
但是有些场景也需要如果是null值则不更新的效果。
所以如果要将null值更新为null的话,只能手动set。
demoDao.update(null, new LambdaUpdateWrapper<Demo>().eq(Demo::getId(), 1111L).set(Demo::getName(), null) );
UpdateWrapper<Demo> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", 1111L);
updateWrapper.set("name", null);
demoDao.update(null, updateWrapper);
但是这种方式每个值都要手动去set,过于麻烦。
那么有没有一种比较简单方便的方式呢。
那当然是有的啊,为了解决这个问题。那么接着往下看吧。
定义一个自定义注解,用于修饰属性,目的是将对象的属性名转为数据库字段名,同时被修饰的属性才需要进行更新。
/**
* 占位
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PlaceHolder {
String value() default "";
}
定义对象,如果字段名称规范的话,其实也可以不需要用注解标注数据库字段名。
可以写个方法将 驼峰的字段转为下划线 的形式。但是如果不规范的话那就只能使用注解标识了。
public class Demo implements Serializable {
/**
* label=PKID
*/
@TableId
private Long id;
/**
* label=合约号
*/
@PlaceHolder("ctr_no")
private String ctrNo;
/**
* label=合约类型;bizrule=NAC/NOVCC
*/
@PlaceHolder("ctr_type")
private String ctrType;
/**
* label=SCAC
*/
@PlaceHolder("scac")
private String scac;
}
我们使用 new updateWrapper() 加 反射&泛型 生成一个 updateWrapper 对象。
createUpdateWrapper() 方法。生成updateWrapper对象。
@Override
@Transactional(rollbackFor = Exception.class)
public void saveDemo(Demo demo) throws NoSuchFieldException, IllegalAccessException {
Long roworgId = JwtUtils.getRoworgId();
if(null == demo.getId()) {
demo.setRoworgid(roworgId);
demoDao.insert(demo);
} else {
UpdateWrapper<Demo> updateWrapper = createUpdateWrapper(demo, "id");
demoDao.update(null,updateWrapper);
}
}
获取对象的所有属性,获取被 PlaceHolder 注解修饰的字段的值,如果是null的话.
则将该字段的值通过 set() 方法设置为null,如果是 String , Integer , BigDecimal 类型,则设置为对应类型的默认值.
将需要eq的主键名称 idFieldName 作为参数传递到方法中.
原因是,有些set不是通过id来进行更新,可能是根据别的字段进行修改.
如果是根据多个参数eq进行更新,则可以将 idFieldName 设置为可变参数.
在这段代码后面也会贴上动态参数方式的代码
private <T> UpdateWrapper<T> createUpdateWrapper(T t, String idFieldName) throws IllegalAccessException, NoSuchFieldException {
UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
Class clazz = t.getClass();
Field[] allField = clazz.getDeclaredFields();
for (Field field : allField) {
field.setAccessible(true);
PlaceHolder annotation = field.getAnnotation(PlaceHolder.class);
if(null == annotation) {
continue;
}
String fieldName = annotation.value();
Object value = field.get(t);
String typeName = field.getType().getSimpleName();
if(null == value && "String".equals(typeName)) {
value = "";
}
if(null == value && "Integer".equals(typeName)) {
value = 0;
}
if(null == value && "BigDecimal".equals(typeName)) {
value = BigDecimal.ZERO;
}
updateWrapper.set(fieldName,value);
}
Field idField = clazz.getDeclaredField(idFieldName);
idField.setAccessible(true);
Long id = (Long) idField.get(t);
PlaceHolder idPlaceHolder = idField.getAnnotation(PlaceHolder.class);
updateWrapper.eq(null == idPlaceHolder ? idFieldName : idPlaceHolder.value(), id);
return updateWrapper;
}
这段没测试,应该没什么问题吧.如果有问题可以评论留言提醒我.
private <T> UpdateWrapper<T> createUpdateWrapper(T t, String... idFieldName) throws IllegalAccessException, NoSuchFieldException {
UpdateWrapper<T> updateWrapper = new UpdateWrapper<>();
Class clazz = t.getClass();
Field[] allField = clazz.getDeclaredFields();
for (Field field : allField) {
field.setAccessible(true);
PlaceHolder annotation = field.getAnnotation(PlaceHolder.class);
if(null == annotation) {
continue;
}
String fieldName = annotation.value();
Object value = field.get(t);
String typeName = field.getType().getSimpleName();
if(null == value && "String".equals(typeName)) {
value = "";
}
if(null == value && "Integer".equals(typeName)) {
value = 0;
}
if(null == value && "BigDecimal".equals(typeName)) {
value = BigDecimal.ZERO;
}
updateWrapper.set(fieldName,value);
}
for(String idFieldEntity : idFieldName) {
Field idField = clazz.getDeclaredField(idFieldEntity);
idField.setAccessible(true);
Long id = (Long) idField.get(t);
PlaceHolder idPlaceHolder = idField.getAnnotation(PlaceHolder.class);
updateWrapper.eq(null == idPlaceHolder ? idFieldName : idPlaceHolder.value(), id);
}
return updateWrapper;
}
如果本文对你有帮助,请帮忙点点赞( •̀ ω •́ )✧
要是能点个关注就更好了闪闪发光