Browse Source

1乐观锁多参数优化.完善测试,2修复乐观锁BUG TABLEFIELD ,3打印SQL修复DRUID包装不能打印,处理不是很优雅.

小锅盖 8 years ago
parent
commit
4aeeaf4f7c

+ 26 - 8
mybatis-plus/src/main/java/com/baomidou/mybatisplus/plugins/OptimisticLockerInterceptor.java

@@ -31,11 +31,13 @@ import org.apache.ibatis.session.Configuration;
 import org.apache.ibatis.type.TypeException;
 import org.apache.ibatis.type.UnknownTypeHandler;
 
-import com.baomidou.mybatisplus.annotations.TableName;
+import com.baomidou.mybatisplus.annotations.TableField;
 import com.baomidou.mybatisplus.annotations.Version;
+import com.baomidou.mybatisplus.mapper.EntityWrapper;
 import com.baomidou.mybatisplus.toolkit.PluginUtils;
 import com.baomidou.mybatisplus.toolkit.StringUtils;
 
+import net.sf.jsqlparser.JSQLParserException;
 import net.sf.jsqlparser.expression.BinaryExpression;
 import net.sf.jsqlparser.expression.Expression;
 import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
@@ -114,9 +116,9 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 						throw new TypeException("乐观锁不支持" + field.getType().getName() + "类型,请自定义实现");
 					}
 					versionField = field;
-					final TableName tableName = field.getAnnotation(TableName.class);
-					if (tableName != null) {
-						versionColumn = tableName.value();
+					final TableField tableField = field.getAnnotation(TableField.class);
+					if (tableField != null) {
+						versionColumn = tableField.value();
 					} else {
 						versionColumn = field.getName();
 					}
@@ -138,14 +140,28 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 
 	private static final Expression RIGHTEXPRESSION = new Column("?");
 
-	@SuppressWarnings({ "rawtypes", "unchecked" })
 	private void processChangeSql(MappedStatement ms, BoundSql boundSql, CachePo cachePo) throws Exception {
 		Field versionField = cachePo.versionField;
 		String versionColumn = cachePo.versionColumn;
 		Object parameterObject = boundSql.getParameterObject();
 		if (parameterObject instanceof ParamMap) {
-			parameterObject = ((ParamMap) parameterObject).get("et");
+			ParamMap<?> paramMap = (ParamMap<?>) parameterObject;
+			parameterObject = paramMap.get("et");
+			EntityWrapper<?> entityWrapper = (EntityWrapper<?>) paramMap.get("ew");
+			if (entityWrapper != null) {
+				Object entity = entityWrapper.getEntity();
+				if (entity != null && versionField.get(entity) == null) {
+					changSql(ms, boundSql, versionField, versionColumn, parameterObject);
+				}
+			}
+		} else {
+			changSql(ms, boundSql, versionField, versionColumn, parameterObject);
 		}
+	}
+
+	@SuppressWarnings({ "unchecked", "rawtypes" })
+	private void changSql(MappedStatement ms, BoundSql boundSql, Field versionField, String versionColumn, Object parameterObject)
+			throws IllegalAccessException, Exception, JSQLParserException {
 		final Object versionValue = versionField.get(parameterObject);
 		if (versionValue != null) {// 先判断传参是否携带version,没带跳过插件
 			Configuration configuration = ms.getConfiguration();
@@ -161,7 +177,7 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 				equalsTo.setRightExpression(RIGHTEXPRESSION);
 				jsqlSql.setWhere(new AndExpression(equalsTo, expression));
 				List<ParameterMapping> parameterMappings = new LinkedList<ParameterMapping>(boundSql.getParameterMappings());
-				parameterMappings.add(jsqlSql.getExpressions().size(), createVersionMapping(configuration));
+				parameterMappings.add(jsqlSql.getExpressions().size(), getVersionMappingInstance(configuration));
 				MetaObject boundSqlMeta = configuration.newMetaObject(boundSql);
 				boundSqlMeta.setValue("sql", jsqlSql.toString());
 				boundSqlMeta.setValue("parameterMappings", parameterMappings);
@@ -173,7 +189,7 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 
 	private volatile ParameterMapping parameterMapping;
 
-	private ParameterMapping createVersionMapping(Configuration configuration) {
+	private ParameterMapping getVersionMappingInstance(Configuration configuration) {
 		if (parameterMapping == null) {
 			synchronized (OptimisticLockerInterceptor.class) {
 				if (parameterMapping == null) {
@@ -184,6 +200,7 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 		return parameterMapping;
 	}
 
+	@Override
 	public Object plugin(Object target) {
 		if (target instanceof StatementHandler) {
 			return Plugin.wrap(target, this);
@@ -191,6 +208,7 @@ public final class OptimisticLockerInterceptor implements Interceptor {
 		return target;
 	}
 
+	@Override
 	public void setProperties(Properties properties) {
 		String versionHandlers = properties.getProperty("versionHandlers");
 		if (StringUtils.isNotEmpty(versionHandlers)) {

+ 4 - 3
mybatis-plus/src/main/java/com/baomidou/mybatisplus/plugins/PerformanceInterceptor.java

@@ -30,7 +30,6 @@ import org.apache.ibatis.reflection.MetaObject;
 import org.apache.ibatis.reflection.SystemMetaObject;
 import org.apache.ibatis.session.ResultHandler;
 
-import com.alibaba.druid.pool.DruidPooledPreparedStatement;
 import com.baomidou.mybatisplus.exceptions.MybatisPlusException;
 import com.baomidou.mybatisplus.toolkit.PluginUtils;
 import com.baomidou.mybatisplus.toolkit.SqlUtils;
@@ -65,9 +64,11 @@ public class PerformanceInterceptor implements Interceptor {
 		} else {
 			statement = (Statement) firstArg;
 		}
-		// TODO 这里不太对
-		if (statement instanceof DruidPooledPreparedStatement) {
+		try {
+			statement.getClass().getDeclaredField("stmt");
 			statement = (Statement) SystemMetaObject.forObject(statement).getValue("stmt.statement");
+		} catch (Exception e) {
+			// do nothing
 		}
 		String originalSql = statement.toString();
 		int index = originalSql.indexOf(':');

+ 36 - 20
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugins/optimisticLocker/OptimisticLockerInterceptorTest.java

@@ -71,7 +71,7 @@ public class OptimisticLockerInterceptorTest {
 		// 更新数据
 		versionUser.setName("苗神");
 		shortVersionUserMapper.updateById(versionUser);
-		Assert.assertTrue(versionUser.getVersion() == originVersion + 1);
+		Assert.assertTrue(shortVersionUserMapper.selectById(1).getVersion() == originVersion + 1);
 	}
 
 	@Test
@@ -82,7 +82,7 @@ public class OptimisticLockerInterceptorTest {
 		// 更新数据
 		versionUser.setName("苗神");
 		intVersionUserMapper.updateById(versionUser);
-		Assert.assertTrue(versionUser.getVersion() == originVersion + 1);
+		Assert.assertTrue(intVersionUserMapper.selectById(1).getVersion() == originVersion + 1);
 
 		// 重复测试一次,验证动态参数覆盖
 		// 查询数据
@@ -92,14 +92,14 @@ public class OptimisticLockerInterceptorTest {
 		// 更新数据
 		versionUser2.setName("苗神");
 		intVersionUserMapper.updateById(versionUser2);
-		Assert.assertTrue(versionUser2.getVersion() == originVersion2 + 1);
+		Assert.assertTrue(intVersionUserMapper.selectById(2).getVersion() == originVersion2 + 1);
 
 		// 测试一次数据库中version为null
 		IntVersionUser versionUser3 = intVersionUserMapper.selectById(3);
 		// 更新数据
 		versionUser3.setName("苗神");
 		intVersionUserMapper.updateById(versionUser3);
-		Assert.assertTrue(versionUser3.getVersion() == null);
+		Assert.assertTrue(intVersionUserMapper.selectById(3).getVersion() == null);
 
 	}
 
@@ -111,7 +111,7 @@ public class OptimisticLockerInterceptorTest {
 		// 更新数据
 		versionUser.setName("苗神");
 		longVersionUserMapper.updateById(versionUser);
-		Assert.assertTrue(versionUser.getVersion() == originVersion + 1);
+		Assert.assertTrue(longVersionUserMapper.selectById(1).getVersion() == originVersion + 1);
 	}
 
 	@Test
@@ -124,9 +124,10 @@ public class OptimisticLockerInterceptorTest {
 		versionUser.setVersion(originVersion);
 		dateVersionUserMapper.insert(versionUser);
 		// 更新数据
-		versionUser.setName("小锅盖");
-		dateVersionUserMapper.updateById(versionUser);
-		Assert.assertTrue(versionUser.getVersion().after(originVersion));
+		DateVersionUser q = dateVersionUserMapper.selectById(15);
+		q.setName("小锅盖");
+		dateVersionUserMapper.updateById(q);
+		Assert.assertTrue(dateVersionUserMapper.selectById(15L).getVersion().after(originVersion));
 	}
 
 	@Test
@@ -139,20 +140,21 @@ public class OptimisticLockerInterceptorTest {
 		versionUser.setVersion(originVersion);
 		timestampVersionUserMapper.insert(versionUser);
 		// 更新数据
-		versionUser.setName("小锅盖");
-		timestampVersionUserMapper.updateById(versionUser);
-		Assert.assertTrue(versionUser.getVersion().after(originVersion));
+		TimestampVersionUser q = timestampVersionUserMapper.selectById(15);
+		q.setName("小锅盖");
+		timestampVersionUserMapper.updateById(q);
+		Assert.assertTrue(timestampVersionUserMapper.selectById(15L).getVersion().after(originVersion));
 	}
 
 	@Test
 	public void stringVersionTest() {
 		// 查询数据
 		StringVersionUser versionUser = stringersionUserMapper.selectById(1);
-		String originVersion = versionUser.getVersion();
+		String originVersion = versionUser.getTt();
 		// 更新数据
 		versionUser.setName("苗神");
 		stringersionUserMapper.updateById(versionUser);
-		Assert.assertEquals(versionUser.getVersion(), String.valueOf(Long.parseLong(originVersion) + 1));
+		Assert.assertEquals(stringersionUserMapper.selectById(1).getTt(), String.valueOf(Long.parseLong(originVersion) + 1));
 	}
 
 	@Test
@@ -162,14 +164,15 @@ public class OptimisticLockerInterceptorTest {
 			new Thread(new Runnable() {
 				public void run() {
 					IntVersionUser intVersionUser = new IntVersionUser();
-					intVersionUser.setId(random.nextLong());
+					long id = random.nextLong();
+					intVersionUser.setId(id);
 					int version = random.nextInt();
 					intVersionUser.setName("改前" + version);
 					intVersionUser.setVersion(version);
 					intVersionUserMapper.insert(intVersionUser);
 					intVersionUser.setName("改后" + version);
 					intVersionUserMapper.updateById(intVersionUser);
-					Assert.assertTrue(intVersionUser.getVersion() == version + 1);
+					Assert.assertTrue(intVersionUserMapper.selectById(id).getVersion() == version + 1);
 				}
 			}, "编号" + i).start();
 		}
@@ -186,10 +189,23 @@ public class OptimisticLockerInterceptorTest {
 		// 查询数据
 		IntVersionUser versionUser = intVersionUserMapper.selectById(2);
 		Integer originVersion = versionUser.getVersion();
-		// 更新数据
-		IntVersionUser intVersionUser = new IntVersionUser();
-		intVersionUser.setName("苗神");
-		intVersionUserMapper.update(versionUser, new EntityWrapper<IntVersionUser>(versionUser));
-		Assert.assertTrue(versionUser.getVersion() == originVersion + 1);
+		// null条件
+		intVersionUserMapper.update(versionUser, null);
+		Assert.assertTrue(intVersionUserMapper.selectById(2).getVersion() == originVersion);
+		// 空条件
+		intVersionUserMapper.update(versionUser, new EntityWrapper<IntVersionUser>());
+		Assert.assertTrue(intVersionUserMapper.selectById(2).getVersion() == originVersion);
+		// 正常查询不带version
+		IntVersionUser wrapper = new IntVersionUser();
+		wrapper.setName("lisi");
+		intVersionUserMapper.update(versionUser, new EntityWrapper<IntVersionUser>(wrapper));
+		Assert.assertTrue(intVersionUserMapper.selectById(2).getVersion() == originVersion + 1);
+		// 原始条件带version按原始逻辑走
+		IntVersionUser wrapper2 = new IntVersionUser();
+		wrapper2.setName("lisi");
+		wrapper2.setVersion(originVersion + 1);
+		intVersionUserMapper.update(versionUser, new EntityWrapper<IntVersionUser>(wrapper2));
+		Assert.assertTrue(intVersionUserMapper.selectById(1).getVersion() == originVersion + 1);
+
 	}
 }

+ 6 - 5
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/plugins/optimisticLocker/entity/StringVersionUser.java

@@ -17,7 +17,8 @@ public class StringVersionUser implements Serializable {
 	private String name;
 
 	@Version
-	private String version;
+	@TableField("version")
+	private String tt;
 
 	public Long getId() {
 		return id;
@@ -35,12 +36,12 @@ public class StringVersionUser implements Serializable {
 		this.name = name;
 	}
 
-	public String getVersion() {
-		return version;
+	public String getTt() {
+		return tt;
 	}
 
-	public void setVersion(String version) {
-		this.version = version;
+	public void setTt(String tt) {
+		this.tt = tt;
 	}
 
 }