Sfoglia il codice sorgente

优化乐观锁代码.

聂秋秋 6 anni fa
parent
commit
e73b673287

+ 36 - 97
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/OptimisticLockerInterceptor.java

@@ -94,21 +94,10 @@ public class OptimisticLockerInterceptor implements Interceptor {
             return invocation.proceed();
         }
         Object param = args[1];
-
-        // wrapper = ew
-        AbstractWrapper<?, ?, ?> ew = null;
-        // entity = et
-        Object et = null;
         if (param instanceof Map) {
             Map map = (Map) param;
-            if (map.containsKey(NAME_ENTITY)) {
-                //updateById(et), update(et, wrapper);
-                et = map.get(NAME_ENTITY);
-            }
-            if (map.containsKey(NAME_ENTITY_WRAPPER)) {
-                // mapper.update(updEntity, QueryWrapper<>(whereEntity);
-                ew = (AbstractWrapper<?, ?, ?>) map.get(NAME_ENTITY_WRAPPER);
-            }
+            //updateById(et), update(et, wrapper);
+            Object et = map.getOrDefault(NAME_ENTITY,null);
             if (et != null) {
                 // entity
                 String methodId = ms.getId();
@@ -126,28 +115,44 @@ public class OptimisticLockerInterceptor implements Interceptor {
                 }
                 Field field = versionField.getField();
                 Object originalVersionVal = versionField.getField().get(et);
+                if (originalVersionVal == null) {
+                    return invocation.proceed();
+                }
                 Object updatedVersionVal = getUpdatedVersionVal(originalVersionVal);
                 if (PARAM_UPDATE_METHOD_NAME.equals(methodName)) {
                     // update(entity, wrapper)
-                    if (originalVersionVal != null) {
-                        if (ew == null) {
-                            UpdateWrapper<?> uw = new UpdateWrapper<>();
-                            uw.eq(versionField.getColumnName(), originalVersionVal);
-                            map.put(NAME_ENTITY_WRAPPER, uw);
-                            field.set(et, updatedVersionVal);
-                        } else {
-                            ew.apply(versionField.getColumnName() + " = {0}", originalVersionVal);
-                            field.set(et, updatedVersionVal);
-                            //TODO: should remove version=oldval condition from aw; 0827 by k神
-                        }
+                    // mapper.update(updEntity, QueryWrapper<>(whereEntity);
+                    AbstractWrapper<?, ?, ?> ew = (AbstractWrapper<?, ?, ?>) map.getOrDefault(NAME_ENTITY_WRAPPER, null);
+                    if (ew == null) {
+                        UpdateWrapper<?> uw = new UpdateWrapper<>();
+                        uw.eq(versionField.getColumnName(), originalVersionVal);
+                        map.put(NAME_ENTITY_WRAPPER, uw);
+                        field.set(et, updatedVersionVal);
+                    } else {
+                        ew.apply(versionField.getColumnName() + " = {0}", originalVersionVal);
+                        field.set(et, updatedVersionVal);
+                        //TODO: should remove version=oldval condition from aw; 0827 by k神
                     }
                     return invocation.proceed();
                 } else {
-                    dealUpdateById(entityClass, et, versionField, originalVersionVal, updatedVersionVal, map);
+                    List<EntityField> fields = entityFieldsCache.computeIfAbsent(entityClass, this::getFieldsFromClazz);
+                    Map<String, Object> entityMap = new HashMap<>();
+                    for (EntityField ef : fields) {
+                        Field fd = ef.getField();
+                        entityMap.put(fd.getName(), fd.get(et));
+                    }
+                    String versionColumnName = versionField.getColumnName();
+                    //update to cache
+                    versionField.setColumnName(versionColumnName);
+                    entityMap.put(field.getName(), updatedVersionVal);
+                    entityMap.put(Constants.MP_OPTLOCK_VERSION_ORIGINAL, originalVersionVal);
+                    entityMap.put(Constants.MP_OPTLOCK_VERSION_COLUMN, versionColumnName);
+                    entityMap.put(Constants.MP_OPTLOCK_ET_ORIGINAL, et);
+                    map.put(NAME_ENTITY, entityMap);
                     Object resultObj = invocation.proceed();
                     if (resultObj instanceof Integer) {
                         Integer effRow = (Integer) resultObj;
-                        if (updatedVersionVal != null && effRow != 0 && field != null) {
+                        if (updatedVersionVal != null && effRow != 0) {
                             //updated version value set to entity.
                             field.set(et, updatedVersionVal);
                         }
@@ -159,39 +164,6 @@ public class OptimisticLockerInterceptor implements Interceptor {
         return invocation.proceed();
     }
 
-    /**
-     * 处理updateById(entity)乐观锁逻辑
-     *
-     * @param entityClass        实体类
-     * @param et                 参数entity
-     * @param entityVersionField ignore
-     * @param originalVersionVal 原来版本的value
-     * @param updatedVersionVal  乐观锁自动更新的新value
-     * @param map
-     */
-    @SuppressWarnings({"unchecked", "rawtypes"})
-    private void dealUpdateById(Class<?> entityClass, Object et, EntityField entityVersionField,
-                                Object originalVersionVal, Object updatedVersionVal, Map map) throws IllegalAccessException {
-        if (originalVersionVal == null) {
-            return;
-        }
-        List<EntityField> fields = getEntityFields(entityClass);
-        Map<String, Object> entityMap = new HashMap<>();
-        for (EntityField ef : fields) {
-            Field fd = ef.getField();
-            entityMap.put(fd.getName(), fd.get(et));
-        }
-        Field versionField = entityVersionField.getField();
-        String versionColumnName = entityVersionField.getColumnName();
-        //update to cache
-        entityVersionField.setColumnName(versionColumnName);
-        entityMap.put(versionField.getName(), updatedVersionVal);
-        entityMap.put(Constants.MP_OPTLOCK_VERSION_ORIGINAL, originalVersionVal);
-        entityMap.put(Constants.MP_OPTLOCK_VERSION_COLUMN, versionColumnName);
-        entityMap.put(Constants.MP_OPTLOCK_ET_ORIGINAL, et);
-        map.put(NAME_ENTITY, entityMap);
-    }
-
     /**
      * This method provides the control for version value.<BR>
      * Returned value type must be the same as original one.
@@ -200,18 +172,11 @@ public class OptimisticLockerInterceptor implements Interceptor {
      * @return updated version val
      */
     protected Object getUpdatedVersionVal(Object originalVersionVal) {
-        if (null == originalVersionVal) {
-            return null;
-        }
         Class<?> versionValClass = originalVersionVal.getClass();
-        if (long.class.equals(versionValClass)) {
+        if (long.class.equals(versionValClass) || Long.class.equals(versionValClass)) {
             return ((long) originalVersionVal) + 1;
-        } else if (Long.class.equals(versionValClass)) {
-            return ((Long) originalVersionVal) + 1;
-        } else if (int.class.equals(versionValClass)) {
+        } else if (int.class.equals(versionValClass) || Integer.class.equals(versionValClass)) {
             return ((int) originalVersionVal) + 1;
-        } else if (Integer.class.equals(versionValClass)) {
-            return ((Integer) originalVersionVal) + 1;
         } else if (Date.class.equals(versionValClass)) {
             return new Date();
         } else if (Timestamp.class.equals(versionValClass)) {
@@ -235,20 +200,9 @@ public class OptimisticLockerInterceptor implements Interceptor {
     public void setProperties(Properties properties) {
         // to do nothing
     }
-
+    
     private EntityField getVersionField(Class<?> parameterClass, TableInfo tableInfo) {
-        synchronized (parameterClass.getName()) {
-            if (versionFieldCache.containsKey(parameterClass)) {
-                return versionFieldCache.get(parameterClass);
-            }
-            // 缓存类信息
-            EntityField field = this.getVersionFieldRegular(parameterClass, tableInfo);
-            if (field != null) {
-                versionFieldCache.put(parameterClass, field);
-                return field;
-            }
-            return null;
-        }
+        return versionFieldCache.computeIfAbsent(parameterClass, mapping -> getVersionFieldRegular(parameterClass, tableInfo));
     }
 
     /**
@@ -265,25 +219,10 @@ public class OptimisticLockerInterceptor implements Interceptor {
         }).findFirst().orElseGet(() -> this.getVersionFieldRegular(parameterClass.getSuperclass(), tableInfo));
     }
 
-    /**
-     * 获取实体的反射属性(类似getter)
-     *
-     * @param parameterClass ignore
-     * @return ignore
-     */
-    private List<EntityField> getEntityFields(Class<?> parameterClass) {
-        if (entityFieldsCache.containsKey(parameterClass)) {
-            return entityFieldsCache.get(parameterClass);
-        }
-        List<EntityField> fields = this.getFieldsFromClazz(parameterClass);
-        entityFieldsCache.put(parameterClass, fields);
-        return fields;
-    }
-
     private List<EntityField> getFieldsFromClazz(Class<?> parameterClass) {
         return ReflectionKit.getFieldList(parameterClass).stream().map(field -> {
             field.setAccessible(true);
-            return field.isAnnotationPresent(Version.class) ? new EntityField(field, true) : new EntityField(field, false);
+            return new EntityField(field, field.isAnnotationPresent(Version.class));
         }).collect(Collectors.toList());
     }