Pārlūkot izejas kodu

乐观锁完善测试,更新为预编译

小锅盖 8 gadi atpakaļ
vecāks
revīzija
e201c98ef1
15 mainītis faili ar 395 papildinājumiem un 137 dzēšanām
  1. 140 110
      mybatis-plus/src/main/java/com/baomidou/mybatisplus/plugins/OptimisticLockerInterceptor.java
  2. 6 11
      mybatis-plus/src/main/java/com/baomidou/mybatisplus/plugins/VersionHandler.java
  3. 3 1
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/CreateDB.sql
  4. 72 5
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/OptimisticLockerInterceptorJUnitTest.java
  5. 1 1
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/DateVersionUser.java
  6. 1 1
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/IntVersionUser.java
  7. 46 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/LongVersionUser.java
  8. 46 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/ShortVersionUser.java
  9. 47 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/TimestampVersionUser.java
  10. 2 2
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/DateVersionUserMapper.java
  11. 2 2
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/IntVersionUserMapper.java
  12. 8 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/LongVersionUserMapper.java
  13. 8 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/ShortVersionUserMapper.java
  14. 8 0
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/TimestampVersionUserMapper.java
  15. 5 4
      mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mybatis-config.xml

+ 140 - 110
mybatis-plus/src/main/java/com/baomidou/mybatisplus/plugins/OptimisticLockerInterceptor.java

@@ -2,25 +2,26 @@ package com.baomidou.mybatisplus.plugins;
 
 import java.lang.reflect.Field;
 import java.sql.Timestamp;
-import java.text.SimpleDateFormat;
 import java.util.ArrayList;
-import java.util.Calendar;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Properties;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.apache.ibatis.binding.MapperMethod;
 import org.apache.ibatis.binding.MapperMethod.ParamMap;
-import org.apache.ibatis.builder.StaticSqlSource;
+import org.apache.ibatis.builder.SqlSourceBuilder;
 import org.apache.ibatis.exceptions.ExceptionFactory;
 import org.apache.ibatis.executor.Executor;
 import org.apache.ibatis.javassist.util.proxy.ProxyFactory;
 import org.apache.ibatis.mapping.BoundSql;
 import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.mapping.ParameterMapping;
 import org.apache.ibatis.mapping.SqlCommandType;
+import org.apache.ibatis.mapping.SqlSource;
 import org.apache.ibatis.plugin.Interceptor;
 import org.apache.ibatis.plugin.Intercepts;
 import org.apache.ibatis.plugin.Invocation;
@@ -33,14 +34,12 @@ import org.apache.ibatis.type.TypeException;
 
 import com.baomidou.mybatisplus.annotations.TableName;
 import com.baomidou.mybatisplus.annotations.Version;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.LongVersionUser;
 import com.baomidou.mybatisplus.toolkit.ArrayUtils;
 import com.baomidou.mybatisplus.toolkit.StringUtils;
 
 import net.sf.jsqlparser.expression.BinaryExpression;
 import net.sf.jsqlparser.expression.Expression;
-import net.sf.jsqlparser.expression.ExpressionVisitorAdapter;
-import net.sf.jsqlparser.expression.LongValue;
-import net.sf.jsqlparser.expression.StringValue;
 import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
 import net.sf.jsqlparser.expression.operators.relational.EqualsTo;
 import net.sf.jsqlparser.parser.CCJSqlParserUtil;
@@ -67,16 +66,19 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 	/**
 	 * 根据对象类型缓存version基本信息
 	 */
-	private static final Map<Class<?>, VersionCache> versionCache = new ConcurrentHashMap<Class<?>, VersionCache>();
+	private static final Map<String, VersionCache> versionCache = new ConcurrentHashMap<>();
 
 	/**
 	 * 根据version字段类型缓存的处理器
 	 */
-	private static final Map<Class<?>, VersionHandler> typeHandlers = new HashMap<Class<?>, VersionHandler>();
+	private static final Map<Class<?>, VersionHandler<?>> typeHandlers = new HashMap<Class<?>, VersionHandler<?>>();
 
 	static {
-		registerHandler(new BaseTypeHnadler());
+		registerHandler(new ShortTypeHnadler());
+		registerHandler(new IntegerTypeHnadler());
+		registerHandler(new LongTypeHnadler());
 		registerHandler(new DateTypeHandler());
+		registerHandler(new TimestampTypeHandler());
 	}
 
 	public Object intercept(Invocation invocation) throws Exception {
@@ -91,15 +93,17 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 		Class<? extends Object> parameterClass = parameterObject.getClass();
 		Class<?> realClass = null;
 		if (parameterObject instanceof ParamMap) {
-			//FIXME 这里还没处理
+			// FIXME 这里还没处理
 			ParamMap<?> tt = (ParamMap<?>) parameterObject;
-			realClass = tt.get("param1").getClass();
-		} else if (ProxyFactory.isProxyClass(parameterClass)) {
+			parameterClass = tt.get("param1").getClass();
+		}
+		if (ProxyFactory.isProxyClass(parameterClass)) {
 			realClass = parameterClass.getSuperclass();
 		} else {
 			realClass = parameterClass;
 		}
-		VersionCache versionPo = versionCache.get(realClass);
+		String cacheKey = realClass.getName();
+		VersionCache versionPo = versionCache.get(cacheKey);
 		if (versionPo != null) {
 			if (versionPo.isVersionControl) {
 				processChangeSql(ms, parameterObject, versionPo);
@@ -125,87 +129,86 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 			if (versionField != null) {
 				versionField.setAccessible(true);
 				VersionCache cachePo = new VersionCache(true, versionColumn, versionField);
-				versionCache.put(parameterClass, cachePo);
+				versionCache.put(cacheKey, cachePo);
 				processChangeSql(ms, parameterObject, cachePo);
 			} else {
-				versionCache.put(parameterClass, new VersionCache(false));
+				versionCache.put(cacheKey, new VersionCache(false));
 			}
 		}
 		return invocation.proceed();
 	}
 
+	@SuppressWarnings({ "rawtypes", "unchecked" })
 	private void processChangeSql(MappedStatement ms, Object parameterObject, VersionCache versionPo) throws Exception {
 		Field versionField = versionPo.versionField;
 		String versionColumn = versionPo.versionColumn;
-		final Object versionValue = versionField.get(parameterObject);
-		if (versionValue != null) {// 先判断传参是否携带version,没带跳过插件,不可能去数据库查吧
+		Object realObject = null;
+		if (parameterObject instanceof ParamMap) {
+			ParamMap<?> tt = (ParamMap<?>) parameterObject;
+			realObject = tt.get("param1");
+		} else {
+			realObject = parameterObject;
+		}
+		final Object versionValue = versionField.get(realObject);
+		if (versionValue != null) {// 先判断传参是否携带version,没带跳过插件
 			Configuration configuration = ms.getConfiguration();
-			BoundSql boundSql = ms.getBoundSql(parameterObject);
-			String originalSql = boundSql.getSql();
+			BoundSql originBoundSql = ms.getBoundSql(parameterObject);
+			String originalSql = originBoundSql.getSql();
+			// 解析sql,预处理更新字段没有version字段的情况
 			Update parse = (Update) CCJSqlParserUtil.parse(originalSql);
 			List<Column> columns = parse.getColumns();
 			List<String> columnNames = new ArrayList<String>();
 			for (Column column : columns) {
 				columnNames.add(column.getColumnName());
 			}
-			if (!columnNames.contains(versionColumn)) {// 如果sql没有version手动加一个
+			if (!columnNames.contains(versionColumn)) {
 				columns.add(new Column(versionColumn));
 				parse.setColumns(columns);
-			} else {
-				VersionHandler targetHandler = typeHandlers.get(versionField.getType());
-				Expression plusExpression = targetHandler.getPlusExpression(versionValue);
-				VersionExpSimpleTypeVisitor visitor = new VersionExpSimpleTypeVisitor();
-				plusExpression.accept(visitor);
-				if (visitor.isLongValue()) {
-					Object versionNewValue = null;
-					String versionClassname = versionValue.getClass().getSimpleName();
-					switch (versionClassname) {
-						case "Long":
-							versionNewValue = Long.parseLong(plusExpression.toString());
-							break;
-						case "long":
-							versionNewValue = Long.parseLong(plusExpression.toString());
-							break;
-						case "Integer":
-							versionNewValue = Integer.parseInt(plusExpression.toString());
-							break;
-						case "int":
-							versionNewValue = Integer.parseInt(plusExpression.toString());
-							break;
-						case "Short":
-							versionNewValue = Short.parseShort(plusExpression.toString());
-							break;
-						case "short":
-							versionNewValue = Short.parseShort(plusExpression.toString());
-							break;
-						default:
-							versionNewValue = versionValue;// not support
-							break;
-					}
-					versionField.set(parameterObject, versionNewValue);
-				} else {
-					// TODO: 自定义VersionHandler处理
-
-				}
 			}
+			// 添加条件
 			BinaryExpression expression = (BinaryExpression) parse.getWhere();
 			if (expression != null && !expression.toString().contains(versionColumn)) {
 				EqualsTo equalsTo = new EqualsTo();
 				equalsTo.setLeftExpression(new Column(versionColumn));
-				VersionHandler targetHandler = typeHandlers.get(versionField.getType());
-				Expression rightExpression = targetHandler.getRightExpression(versionValue);
-				Expression plusExpression = targetHandler.getPlusExpression(versionValue);
+				Expression rightExpression = new Column("#{originVersionValue}");
 				equalsTo.setRightExpression(rightExpression);
 				parse.setWhere(new AndExpression(equalsTo, expression));
-				List<Expression> expressions = parse.getExpressions();
-				expressions.add(plusExpression);
-				parse.setExpressions(expressions);
 			}
+			String newSql = parse.toString();
+			int originVersionIndex = getOriginVersionIndex(newSql);
+			VersionHandler targetHandler = typeHandlers.get(versionField.getType());
+			targetHandler.plusVersion(parameterObject, versionField, versionValue);
+			SqlSource sqlSource = new SqlSourceBuilder(configuration).parse(newSql, LongVersionUser.class, null);
+			BoundSql newBoundSql = sqlSource.getBoundSql(parameterObject);
+			List<ParameterMapping> parameterMappings = newBoundSql.getParameterMappings();
+			parameterMappings.addAll(originBoundSql.getParameterMappings());
+			List<ParameterMapping> linkedList = new LinkedList<>(originBoundSql.getParameterMappings());
+			linkedList.add(originVersionIndex, parameterMappings.get(0));
+			Map<String, Object> additionalParameters = new HashMap<>();
+			additionalParameters.put("originVersionValue", versionValue);
+			MySqlSource mySqlSource = new MySqlSource(configuration, newBoundSql.getSql(), linkedList, additionalParameters);
 			MetaObject metaObject = SystemMetaObject.forObject(ms);
-			metaObject.setValue("sqlSource", new StaticSqlSource(configuration, parse.toString(), boundSql.getParameterMappings()));
+			metaObject.setValue("sqlSource", mySqlSource);
 		}
 	}
 
+	private int getOriginVersionIndex(String newSql) {
+		int indexOf = newSql.indexOf("#{originVersionValue}");
+		int index = 0;
+		int originVersionIndex = 0;
+		for (int i = 0; i < newSql.length(); i++) {
+			if (newSql.charAt(i) == '?') {
+				index++;
+			}
+			if (indexOf == i) {
+				originVersionIndex = index--;
+				break;
+			}
+
+		}
+		return originVersionIndex;
+	}
+
 	public Object plugin(Object target) {
 		if (target instanceof Executor) {
 			return Plugin.wrap(target, this);
@@ -219,7 +222,7 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 			String[] userHandlers = versionHandlers.split(",");
 			for (String handlerClazz : userHandlers) {
 				try {
-					VersionHandler versionHandler = (VersionHandler) Class.forName(handlerClazz).newInstance();
+					VersionHandler<?> versionHandler = (VersionHandler<?>) Class.forName(handlerClazz).newInstance();
 					registerHandler(versionHandler);
 				} catch (Exception e) {
 					throw ExceptionFactory.wrapException("乐观锁插件自定义处理器注册失败", e);
@@ -232,7 +235,7 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 	/**
 	 * 注册处理器
 	 */
-	private static void registerHandler(VersionHandler versionHandler) {
+	private static void registerHandler(VersionHandler<?> versionHandler) {
 		Class<?>[] handleType = versionHandler.handleType();
 		if (ArrayUtils.isNotEmpty(handleType)) {
 			for (Class<?> type : handleType) {
@@ -260,74 +263,101 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 		}
 	}
 
-	/**
-	 * 基本类型处理器
-	 * 
-	 * @author TaoYu
-	 */
-	private static class BaseTypeHnadler implements VersionHandler {
+	private class MySqlSource implements SqlSource {
+
+		private String sql;
+		private List<ParameterMapping> parameterMappings;
+		private Configuration configuration;
+		private Map<String, Object> additionalParameters;
+
+		public MySqlSource(Configuration configuration, String sql, List<ParameterMapping> parameterMappings, Map<String, Object> additionalParameters) {
+			this.sql = sql;
+			this.parameterMappings = parameterMappings;
+			this.configuration = configuration;
+			this.additionalParameters = additionalParameters;
+		}
+
+		@Override
+		public BoundSql getBoundSql(Object parameterObject) {
+			BoundSql boundSql = new BoundSql(configuration, sql, parameterMappings, parameterObject);
+			if (additionalParameters != null && additionalParameters.size() > 0) {
+				for (Entry<String, Object> item : additionalParameters.entrySet()) {
+					boundSql.setAdditionalParameter(item.getKey(), item.getValue());
+				}
+			}
+			return boundSql;
+		}
+
+	}
+	// *****************************基本类型处理器*****************************
 
+	private static class ShortTypeHnadler implements VersionHandler<Short> {
+
+		@Override
 		public Class<?>[] handleType() {
-			return new Class<?>[] { Long.class, long.class, Integer.class, int.class, Short.class, short.class };
+			return new Class<?>[] { Short.class, short.class };
 		}
 
-		public Expression getRightExpression(Object param) {
-			return new LongValue(param.toString());
+		@Override
+		public void plusVersion(Object paramObj, Field field, Short versionValue) throws Exception {
+			field.set(paramObj, (short) (versionValue + 1));
+		}
+	}
+
+	private static class IntegerTypeHnadler implements VersionHandler<Integer> {
+
+		@Override
+		public Class<?>[] handleType() {
+			return new Class<?>[] { Integer.class, int.class };
 		}
 
-		public Expression getPlusExpression(Object param) {
-			return new LongValue(Long.parseLong(param.toString()) + 1);
+		@Override
+		public void plusVersion(Object paramObj, Field field, Integer versionValue) throws Exception {
+			field.set(paramObj, versionValue + 1);
 		}
 
 	}
 
-	/**
-	 * 时间类型处理器
-	 * 
-	 * @author TaoYu
-	 */
-	private static class DateTypeHandler implements VersionHandler {
+	private static class LongTypeHnadler implements VersionHandler<Long> {
 
+		@Override
 		public Class<?>[] handleType() {
-			return new Class<?>[] { Date.class, java.sql.Date.class, Timestamp.class };
+			return new Class<?>[] { Long.class, long.class };
 		}
 
-		/*
-		 * 时间处理是大坑!!!!!http://www.yufengof.com/2015/08/17/mysql-datetime-type-millisecond-rounding/
-		 */
-
-		public Expression getRightExpression(Object param) {
-			Date date = (Date) param;
-			String millTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").format((Date) param);
-			String realTime;
-			Integer mills = Integer.valueOf(millTime.substring(20, 21));
-			if (mills >= 5) {
-				Calendar calendar = Calendar.getInstance();
-				calendar.setTime(date);
-				calendar.add(Calendar.SECOND, 1);
-				realTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
-			} else {
-				realTime = millTime.substring(0, 19);
-			}
-			return new StringValue(realTime);
+		@Override
+		public void plusVersion(Object paramObj, Field field, Long versionValue) throws Exception {
+			field.set(paramObj, versionValue + 1);
 		}
 
-		public Expression getPlusExpression(Object param) {
-			return new StringValue(new Timestamp(new Date().getTime()).toString());
+	}
+
+	// ***************************** 时间类型处理器*****************************
+	private static class DateTypeHandler implements VersionHandler<Date> {
+
+		@Override
+		public Class<?>[] handleType() {
+			return new Class<?>[] { Date.class };
 		}
 
+		@Override
+		public void plusVersion(Object paramObj, Field field, Date versionValue) throws Exception {
+			field.set(paramObj, new Date());
+
+		}
 	}
 
-	private static class VersionExpSimpleTypeVisitor extends ExpressionVisitorAdapter {
-		private boolean longValue = false;
+	private static class TimestampTypeHandler implements VersionHandler<Timestamp> {
 
 		@Override
-		public void visit(LongValue value) {
-			longValue = true;
+		public Class<?>[] handleType() {
+			return new Class<?>[] { Timestamp.class };
 		}
 
-		public boolean isLongValue() {
-			return longValue;
+		@Override
+		public void plusVersion(Object paramObj, Field field, Timestamp versionValue) throws Exception {
+			field.set(paramObj, new Timestamp(new Date().getTime()));
+
 		}
 	}
 

+ 6 - 11
mybatis-plus/src/main/java/com/baomidou/mybatisplus/plugins/VersionHandler.java

@@ -1,26 +1,21 @@
 package com.baomidou.mybatisplus.plugins;
 
-import net.sf.jsqlparser.expression.Expression;
+import java.lang.reflect.Field;
 
 /**
  * 乐观锁处理器,底层接口
  *
  * @author TaoYu
  */
-public interface VersionHandler {
-	
-	/**
-	 * 返回需要处理的类型
-	 */
-	Class<?>[] handleType();
+public interface VersionHandler<T> {
 
 	/**
-	 * 根据类型得到equalTo右侧的表达式
+	 * 需要处理类型
 	 */
-	Expression getRightExpression(Object param);
+	Class<?>[] handleType();
 
 	/**
-	 * 根据类型得到+1后的表达式
+	 * 根据类型,使得对象对应的字段+1
 	 */
-	Expression getPlusExpression(Object param);
+	void plusVersion(Object paramObj, Field field, T versionValue) throws Exception;
 }

+ 3 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/CreateDB.sql

@@ -18,5 +18,7 @@ CREATE TABLE time_version_user (
 	PRIMARY KEY (`id`)
 ) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8;
 
-insert into version_user (id,name,version) values(1,"zhangsan",1);
+insert into version_user (id,name,version) values(1,"zhangsan",15);
+insert into version_user (id,name,version) values(2,"lisi",null);
+insert into version_user (id,name,version) values(3,"wangwu",109);
 

+ 72 - 5
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/OptimisticLockerInterceptorJUnitTest.java

@@ -2,17 +2,28 @@ package com.baomidou.mybatisplus.test.plugin.OptimisticLocker;
 
 import java.io.Reader;
 import java.sql.Connection;
+import java.sql.Timestamp;
+import java.util.Date;
 
 import org.apache.ibatis.io.Resources;
 import org.apache.ibatis.jdbc.ScriptRunner;
 import org.apache.ibatis.session.SqlSession;
 import org.apache.ibatis.session.SqlSessionFactory;
+import org.junit.Assert;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
 import com.baomidou.mybatisplus.MybatisSessionFactoryBuilder;
-import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.VersionUser;
-import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.VersionUserMapper;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.DateVersionUser;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.IntVersionUser;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.LongVersionUser;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.ShortVersionUser;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.TimestampVersionUser;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.DateVersionUserMapper;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.IntVersionUserMapper;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.LongVersionUserMapper;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.ShortVersionUserMapper;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.TimestampVersionUserMapper;
 
 public class OptimisticLockerInterceptorJUnitTest {
 
@@ -33,14 +44,70 @@ public class OptimisticLockerInterceptorJUnitTest {
 		session.close();
 	}
 
+	@Test
+	public void shorttVersionTest() {
+		SqlSession sqlSession = sqlSessionFactory.openSession();
+		ShortVersionUserMapper mapper = sqlSession.getMapper(ShortVersionUserMapper.class);
+		// 查到数据
+		ShortVersionUser versionUser = mapper.selectById(1);
+		// 根据Id更新
+		Assert.assertTrue(mapper.updateById(versionUser) == 1);
+		sqlSession.close();
+	}
+
 	@Test
 	public void intVersionTest() {
 		SqlSession sqlSession = sqlSessionFactory.openSession();
-		VersionUserMapper mapper = sqlSession.getMapper(VersionUserMapper.class);
+		IntVersionUserMapper mapper = sqlSession.getMapper(IntVersionUserMapper.class);
+		// 查到数据
+		IntVersionUser versionUser = mapper.selectById(1);
+		// 根据Id更新
+		Assert.assertTrue(mapper.updateById(versionUser) == 1);
+		sqlSession.close();
+	}
+
+	@Test
+	public void longVersionTest() {
+		SqlSession sqlSession = sqlSessionFactory.openSession();
+		LongVersionUserMapper mapper = sqlSession.getMapper(LongVersionUserMapper.class);
 		// 查到数据
-		VersionUser versionUser = mapper.selectById(1);
+		LongVersionUser versionUser = mapper.selectById(1);
+		// 根据Id更新
+		Assert.assertTrue(mapper.updateById(versionUser) == 1);
+		sqlSession.close();
+	}
+
+	@Test
+	public void dateVersionTest() {
+		SqlSession sqlSession = sqlSessionFactory.openSession();
+		DateVersionUserMapper mapper = sqlSession.getMapper(DateVersionUserMapper.class);
+		DateVersionUser dateVersionUser = new DateVersionUser();
+		dateVersionUser.setName("zhangsan");
+		dateVersionUser.setVersion(new Timestamp(new Date().getTime()));
+		// 插入数据
+		mapper.insert(dateVersionUser);
+		// 查找出来
+		DateVersionUser dbUser = mapper.selectById(dateVersionUser.getId());
+		// 根据Id更新
+		dbUser.setName("lisi");
+		Assert.assertTrue(mapper.updateById(dbUser) == 1);
+		sqlSession.close();
+	}
+
+	@Test
+	public void timestampVersionTest() {
+		SqlSession sqlSession = sqlSessionFactory.openSession();
+		TimestampVersionUserMapper mapper = sqlSession.getMapper(TimestampVersionUserMapper.class);
+		TimestampVersionUser timeVersionUser = new TimestampVersionUser();
+		timeVersionUser.setName("zhangsan");
+		timeVersionUser.setVersion(new Timestamp(new Date().getTime()));
+		// 插入数据
+		mapper.insert(timeVersionUser);
+		// 查找出来
+		TimestampVersionUser dbUser = mapper.selectById(timeVersionUser.getId());
 		// 根据Id更新
-		mapper.updateById(versionUser);
+		dbUser.setName("lisi");
+		Assert.assertTrue(mapper.updateById(dbUser) == 1);
 		sqlSession.close();
 	}
 

+ 1 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/TimeVersionUser.java → mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/DateVersionUser.java

@@ -8,7 +8,7 @@ import com.baomidou.mybatisplus.annotations.TableName;
 import com.baomidou.mybatisplus.annotations.Version;
 
 @TableName("time_version_user")
-public class TimeVersionUser implements Serializable {
+public class DateVersionUser implements Serializable {
 
 	@TableField(exist = false)
 	private static final long serialVersionUID = 1L;

+ 1 - 1
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/VersionUser.java → mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/IntVersionUser.java

@@ -7,7 +7,7 @@ import com.baomidou.mybatisplus.annotations.TableName;
 import com.baomidou.mybatisplus.annotations.Version;
 
 @TableName("version_user")
-public class VersionUser implements Serializable {
+public class IntVersionUser implements Serializable {
 
 	@TableField(exist = false)
 	private static final long serialVersionUID = 1L;

+ 46 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/LongVersionUser.java

@@ -0,0 +1,46 @@
+package com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity;
+
+import java.io.Serializable;
+
+import com.baomidou.mybatisplus.annotations.TableField;
+import com.baomidou.mybatisplus.annotations.TableName;
+import com.baomidou.mybatisplus.annotations.Version;
+
+@TableName("version_user")
+public class LongVersionUser implements Serializable {
+
+	@TableField(exist = false)
+	private static final long serialVersionUID = 1L;
+
+	private Long id;
+
+	private String name;
+
+	@Version
+	private Long version;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Long getVersion() {
+		return version;
+	}
+
+	public void setVersion(Long version) {
+		this.version = version;
+	}
+
+}

+ 46 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/ShortVersionUser.java

@@ -0,0 +1,46 @@
+package com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity;
+
+import java.io.Serializable;
+
+import com.baomidou.mybatisplus.annotations.TableField;
+import com.baomidou.mybatisplus.annotations.TableName;
+import com.baomidou.mybatisplus.annotations.Version;
+
+@TableName("version_user")
+public class ShortVersionUser implements Serializable {
+
+	@TableField(exist = false)
+	private static final long serialVersionUID = 1L;
+
+	private Long id;
+
+	private String name;
+
+	@Version
+	private Short version;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Short getVersion() {
+		return version;
+	}
+
+	public void setVersion(Short version) {
+		this.version = version;
+	}
+
+}

+ 47 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/entity/TimestampVersionUser.java

@@ -0,0 +1,47 @@
+package com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity;
+
+import java.io.Serializable;
+import java.sql.Timestamp;
+
+import com.baomidou.mybatisplus.annotations.TableField;
+import com.baomidou.mybatisplus.annotations.TableName;
+import com.baomidou.mybatisplus.annotations.Version;
+
+@TableName("time_version_user")
+public class TimestampVersionUser implements Serializable {
+
+	@TableField(exist = false)
+	private static final long serialVersionUID = 1L;
+
+	private Long id;
+
+	private String name;
+
+	@Version
+	private Timestamp version;
+
+	public Long getId() {
+		return id;
+	}
+
+	public void setId(Long id) {
+		this.id = id;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	public Timestamp getVersion() {
+		return version;
+	}
+
+	public void setVersion(Timestamp version) {
+		this.version = version;
+	}
+
+}

+ 2 - 2
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/TimeVersionUserMapper.java → mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/DateVersionUserMapper.java

@@ -1,8 +1,8 @@
 package com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper;
 
 import com.baomidou.mybatisplus.mapper.BaseMapper;
-import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.TimeVersionUser;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.DateVersionUser;
 
-public interface TimeVersionUserMapper extends BaseMapper<TimeVersionUser> {
+public interface DateVersionUserMapper extends BaseMapper<DateVersionUser> {
 
 }

+ 2 - 2
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/VersionUserMapper.java → mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/IntVersionUserMapper.java

@@ -1,8 +1,8 @@
 package com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper;
 
 import com.baomidou.mybatisplus.mapper.BaseMapper;
-import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.VersionUser;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.IntVersionUser;
 
-public interface VersionUserMapper extends BaseMapper<VersionUser> {
+public interface IntVersionUserMapper extends BaseMapper<IntVersionUser> {
 	
 }

+ 8 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/LongVersionUserMapper.java

@@ -0,0 +1,8 @@
+package com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.LongVersionUser;
+
+public interface LongVersionUserMapper extends BaseMapper<LongVersionUser> {
+
+}

+ 8 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/ShortVersionUserMapper.java

@@ -0,0 +1,8 @@
+package com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.ShortVersionUser;
+
+public interface ShortVersionUserMapper extends BaseMapper<ShortVersionUser> {
+	
+}

+ 8 - 0
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mapper/TimestampVersionUserMapper.java

@@ -0,0 +1,8 @@
+package com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper;
+
+import com.baomidou.mybatisplus.mapper.BaseMapper;
+import com.baomidou.mybatisplus.test.plugin.OptimisticLocker.entity.TimestampVersionUser;
+
+public interface TimestampVersionUserMapper extends BaseMapper<TimestampVersionUser> {
+
+}

+ 5 - 4
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugin/OptimisticLocker/mybatis-config.xml

@@ -26,10 +26,11 @@
 	</environments>
 
 	<mappers>
-		<mapper
-			class="com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.VersionUserMapper" />
-		<mapper
-			class="com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.TimeVersionUserMapper" />
+		<mapper class="com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.ShortVersionUserMapper" />
+		<mapper class="com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.IntVersionUserMapper" />
+		<mapper class="com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.LongVersionUserMapper" />
+		<mapper class="com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.DateVersionUserMapper" />
+		<mapper class="com.baomidou.mybatisplus.test.plugin.OptimisticLocker.mapper.TimestampVersionUserMapper" />
 	</mappers>
 
 </configuration>