Skip to content

Commit 8389d80

Browse files
committed
feature: saveOrUpdate逻辑优化,支持查询数据库中的记录
1 parent 0401cc9 commit 8389d80

File tree

4 files changed

+106
-10
lines changed

4 files changed

+106
-10
lines changed

src/main/java/app/myoss/cloud/mybatis/constants/MybatisConstants.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,21 @@ public class MybatisConstants {
2727
/**
2828
* 字段或者实体对象没有值
2929
*/
30-
public static final String VALUE_IS_BLANK = "valueIsBlank";
30+
public static final String VALUE_IS_BLANK = "valueIsBlank";
3131
/**
3232
* 匹配到了多条的记录
3333
*/
34-
public static final String MORE_RECORDS = "moreRecords";
34+
public static final String MORE_RECORDS = "moreRecords";
3535
/**
3636
* 数据库插入失败
3737
*/
38-
public static final String INSERT_DB_FAILED = "insertDBFailed";
38+
public static final String INSERT_DB_FAILED = "insertDBFailed";
39+
/**
40+
* 更新实体类字段失败
41+
*/
42+
public static final String UPDATE_ENTITY_FIELD_FAILED = "updateEntityFieldFailed";
3943
/**
4044
* 未匹配到相应的记录
4145
*/
42-
public static final String NOT_MATCH_RECORDS = "notMatchRecords";
46+
public static final String NOT_MATCH_RECORDS = "notMatchRecords";
4347
}

src/main/java/app/myoss/cloud/mybatis/repository/service/impl/BaseCrudServiceImpl.java

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020
import static app.myoss.cloud.mybatis.repository.utils.DbUtils.checkDBResult;
2121

2222
import java.io.Serializable;
23+
import java.lang.reflect.InvocationTargetException;
24+
import java.lang.reflect.Method;
2325
import java.lang.reflect.ParameterizedType;
2426
import java.lang.reflect.Type;
2527
import java.util.ArrayList;
28+
import java.util.Arrays;
2629
import java.util.Collections;
2730
import java.util.Iterator;
2831
import java.util.List;
@@ -39,6 +42,7 @@
3942
import org.springframework.util.CollectionUtils;
4043

4144
import app.myoss.cloud.core.constants.MyossConstants;
45+
import app.myoss.cloud.core.exception.BizRuntimeException;
4246
import app.myoss.cloud.core.lang.bean.BeanUtil;
4347
import app.myoss.cloud.core.lang.concurrent.CallableFunc;
4448
import app.myoss.cloud.core.lang.dto.Order;
@@ -516,6 +520,25 @@ protected <I> Result<I> getPrimaryKeyValue(T record, Result<I> result) {
516520
return result.setValue((I) value);
517521
}
518522

523+
protected void setPrimaryKeyValue(T record, Object... value) {
524+
Set<TableColumnInfo> primaryKeyColumns = tableInfo.getPrimaryKeyColumns();
525+
int size = primaryKeyColumns.size();
526+
if (size == 0) {
527+
// 忽略没有主键字段的情况
528+
return;
529+
}
530+
int idx = 0;
531+
for (TableColumnInfo columnInfo : primaryKeyColumns) {
532+
Method writeMethod = columnInfo.getPropertyDescriptor().getWriteMethod();
533+
try {
534+
writeMethod.invoke(record, value[idx++]);
535+
} catch (IllegalAccessException | InvocationTargetException e) {
536+
throw new BizRuntimeException(MybatisConstants.UPDATE_ENTITY_FIELD_FAILED,
537+
"更新Entity主键失败,请检查。[" + record + ", " + Arrays.toString(value) + "]", null);
538+
}
539+
}
540+
}
541+
519542
@Transactional(rollbackFor = Exception.class)
520543
@Override
521544
public Result<Boolean> createBatch(List<T> records, Object optionParam) {
@@ -630,7 +653,23 @@ public <I> Result<I> saveOrUpdate(T record, Object optionParam) {
630653
Result<I> result = new Result<>();
631654
Result<I> primaryKeyValue = getPrimaryKeyValue(record, result);
632655
if (primaryKeyValue.getValue() == null) {
633-
return create(record, optionParam);
656+
List<T> exists = findExistRecord4CheckRecord(result, record);
657+
if (CollectionUtils.isEmpty(exists)) {
658+
return create(record, optionParam);
659+
}
660+
T exist = exists.get(0);
661+
if (exist != null) {
662+
primaryKeyValue = getPrimaryKeyValue(record, result);
663+
setPrimaryKeyValue(record, primaryKeyValue.getValue());
664+
Result<Boolean> updateResult = updateByPrimaryKey(record, optionParam);
665+
result.setSuccess(updateResult.isSuccess())
666+
.setErrorCode(updateResult.getErrorCode())
667+
.setErrorMsg(updateResult.getErrorMsg())
668+
.setValue(primaryKeyValue.getValue())
669+
.setExtraInfo(updateResult.getExtraInfo());
670+
} else {
671+
return create(record, optionParam);
672+
}
634673
} else {
635674
Result<Boolean> updateResult = updateByPrimaryKey(record, optionParam);
636675
result.setSuccess(updateResult.isSuccess())

src/main/java/app/myoss/cloud/mybatis/repository/v2/service/impl/BaseCrudServiceImpl.java

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@
2020
import static app.myoss.cloud.mybatis.repository.utils.DbUtils.checkDBResult;
2121

2222
import java.io.Serializable;
23+
import java.lang.reflect.InvocationTargetException;
24+
import java.lang.reflect.Method;
2325
import java.lang.reflect.ParameterizedType;
2426
import java.lang.reflect.Type;
2527
import java.util.ArrayList;
28+
import java.util.Arrays;
2629
import java.util.Collections;
2730
import java.util.Iterator;
2831
import java.util.List;
@@ -452,6 +455,25 @@ protected <I> I getPrimaryKeyValue(T record) {
452455
return (I) value;
453456
}
454457

458+
protected void setPrimaryKeyValue(T record, Object... value) {
459+
Set<TableColumnInfo> primaryKeyColumns = tableInfo.getPrimaryKeyColumns();
460+
int size = primaryKeyColumns.size();
461+
if (size == 0) {
462+
// 忽略没有主键字段的情况
463+
return;
464+
}
465+
int idx = 0;
466+
for (TableColumnInfo columnInfo : primaryKeyColumns) {
467+
Method writeMethod = columnInfo.getPropertyDescriptor().getWriteMethod();
468+
try {
469+
writeMethod.invoke(record, value[idx++]);
470+
} catch (IllegalAccessException | InvocationTargetException e) {
471+
throw new BizServiceException(MybatisConstants.UPDATE_ENTITY_FIELD_FAILED,
472+
"更新Entity主键失败,请检查。[" + record + ", " + Arrays.toString(value) + "]");
473+
}
474+
}
475+
}
476+
455477
@Transactional(rollbackFor = Exception.class)
456478
@Override
457479
public void createBatch(List<T> records, Object optionParam) {
@@ -548,7 +570,19 @@ public <I> I saveOrUpdate(T record) {
548570
public <I> I saveOrUpdate(T record, Object optionParam) {
549571
I primaryKeyValue = getPrimaryKeyValue(record);
550572
if (primaryKeyValue == null) {
551-
return create(record, optionParam);
573+
List<T> exists = findExistRecord4CheckRecord(record);
574+
if (CollectionUtils.isEmpty(exists)) {
575+
return create(record, optionParam);
576+
}
577+
T exist = exists.get(0);
578+
if (exist != null) {
579+
primaryKeyValue = getPrimaryKeyValue(exist);
580+
setPrimaryKeyValue(record, primaryKeyValue);
581+
updateByPrimaryKey(record, optionParam);
582+
return primaryKeyValue;
583+
} else {
584+
return create(record, optionParam);
585+
}
552586
} else {
553587
updateByPrimaryKey(record, optionParam);
554588
return getPrimaryKeyValue(record);

src/main/java/app/myoss/cloud/mybatis/table/TableMetaObject.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.beans.PropertyDescriptor;
2424
import java.lang.annotation.Annotation;
2525
import java.lang.reflect.Field;
26+
import java.lang.reflect.Method;
2627
import java.lang.reflect.Modifier;
2728
import java.lang.reflect.ParameterizedType;
2829
import java.lang.reflect.Type;
@@ -65,13 +66,15 @@
6566
import app.myoss.cloud.mybatis.type.EnumValueMappedType;
6667
import app.myoss.cloud.mybatis.type.EnumValueTypeHandler;
6768
import app.myoss.cloud.mybatis.type.UnsupportedTypeHandler;
69+
import lombok.extern.slf4j.Slf4j;
6870

6971
/**
7072
* 数据库表结构信息工具类
7173
*
7274
* @author Jerry.Chen
7375
* @since 2018年4月26日 上午10:46:25
7476
*/
77+
@Slf4j
7578
public class TableMetaObject {
7679
/**
7780
* 实体类 => 表对象
@@ -557,20 +560,36 @@ public static List<Field> getFieldList(Class<?> clazz) {
557560
/**
558561
* 获取 {@code clazz } Class 中所有的 getter/setter 方法
559562
*
560-
* @param clazz 反射类
563+
* @param beanClass 反射类
561564
* @return clazz 所有的 getter/setter 方法
562565
*/
563-
public static Map<String, PropertyDescriptor> getPropertyDescriptorMap(Class<?> clazz) {
566+
public static Map<String, PropertyDescriptor> getPropertyDescriptorMap(Class<?> beanClass) {
564567
BeanInfo beanInfo;
565568
try {
566-
beanInfo = Introspector.getBeanInfo(clazz);
569+
beanInfo = Introspector.getBeanInfo(beanClass);
567570
} catch (IntrospectionException e) {
568571
throw new BizRuntimeException(e);
569572
}
570573
PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
571574
return Stream.of(descriptors)
572575
.filter(s -> !"class".equals(s.getName()))
573-
.collect(Collectors.toMap(PropertyDescriptor::getName, Function.identity()));
576+
.collect(Collectors.toMap(PropertyDescriptor::getName, descriptor -> {
577+
if (descriptor.getWriteMethod() == null) {
578+
String propName = descriptor.getName().substring(0, 1).toUpperCase()
579+
+ descriptor.getName().substring(1);
580+
String methodName = "set" + propName;
581+
Method writeMethod = org.springframework.util.ReflectionUtils.findMethod(beanClass, methodName,
582+
descriptor.getReadMethod().getReturnType());
583+
if (writeMethod != null) {
584+
try {
585+
descriptor.setWriteMethod(writeMethod);
586+
} catch (final Exception e) {
587+
log.error("Error setting indexed property write method", e);
588+
}
589+
}
590+
}
591+
return descriptor;
592+
}));
574593
}
575594

576595
/**

0 commit comments

Comments
 (0)