diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/dao/DataSourceContextHolder.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DataSourceContextHolder.java similarity index 92% rename from boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/dao/DataSourceContextHolder.java rename to boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DataSourceContextHolder.java index f59faf3..49b088a 100644 --- a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/dao/DataSourceContextHolder.java +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DataSourceContextHolder.java @@ -1,6 +1,5 @@ -package com.micro.fast.common.dao; +package com.micro.fast.common.datasource.dynamic; -import com.micro.fast.common.config.DynamicDataSourceConfig; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/config/DruidDataSourceConfig.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DruidDataSourceConfig.java similarity index 75% rename from boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/config/DruidDataSourceConfig.java rename to boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DruidDataSourceConfig.java index 77e1195..16053b0 100644 --- a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/config/DruidDataSourceConfig.java +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DruidDataSourceConfig.java @@ -1,6 +1,7 @@ -package com.micro.fast.common.config; +package com.micro.fast.common.datasource.dynamic; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; +import com.micro.fast.common.datasource.dynamic.condition.MasterDataSourceCondition; import org.springframework.boot.autoconfigure.AutoConfigureBefore; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -13,12 +14,12 @@ import javax.sql.DataSource; * @author lsy */ @Configuration -@AutoConfigureBefore(com.micro.fast.common.config.DynamicDataSourceConfig.class) +@AutoConfigureBefore(DynamicDataSourceConfig.class) public class DruidDataSourceConfig { @Bean(name = DynamicDataSourceConfig.MASTER_DATA_SOURCE) @ConfigurationProperties("spring.datasource.druid.master") - @Conditional(com.micro.fast.common.condition.MasterDataSourceCondition.class) + @Conditional(MasterDataSourceCondition.class) public DataSource masterDataSource(){ return DruidDataSourceBuilder.create().build(); } diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/dao/DynamicDataSource.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DynamicDataSource.java similarity index 81% rename from boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/dao/DynamicDataSource.java rename to boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DynamicDataSource.java index 439833b..b2bba50 100644 --- a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/dao/DynamicDataSource.java +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DynamicDataSource.java @@ -1,4 +1,4 @@ -package com.micro.fast.common.dao; +package com.micro.fast.common.datasource.dynamic; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -18,7 +18,7 @@ public class DynamicDataSource extends AbstractRoutingDataSource{ @Override public Object determineCurrentLookupKey() { - log.debug("数据源{}",DataSourceContextHolder.getDatdasourceName()); + log.debug("数据源{}", DataSourceContextHolder.getDatdasourceName()); return DataSourceContextHolder.getDatdasourceName(); } } diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/config/DynamicDataSourceConfig.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DynamicDataSourceConfig.java similarity index 96% rename from boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/config/DynamicDataSourceConfig.java rename to boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DynamicDataSourceConfig.java index e221250..019820a 100644 --- a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/config/DynamicDataSourceConfig.java +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/DynamicDataSourceConfig.java @@ -1,7 +1,7 @@ -package com.micro.fast.common.config; +package com.micro.fast.common.datasource.dynamic; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure; -import com.micro.fast.common.dao.DynamicDataSource; +import com.micro.fast.common.config.SqlSessionFactoryConfig; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.AutoConfigureAfter; diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/annotation/SwitchDataSource.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/annotation/SwitchDataSource.java similarity index 87% rename from boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/annotation/SwitchDataSource.java rename to boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/annotation/SwitchDataSource.java index 60bedcd..7fa469f 100644 --- a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/annotation/SwitchDataSource.java +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/annotation/SwitchDataSource.java @@ -1,4 +1,4 @@ -package com.micro.fast.common.annotation; +package com.micro.fast.common.datasource.dynamic.annotation; import java.lang.annotation.*; diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/annotation/package-info.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/annotation/package-info.java similarity index 66% rename from boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/annotation/package-info.java rename to boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/annotation/package-info.java index 82dea4d..47e8c7b 100644 --- a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/annotation/package-info.java +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/annotation/package-info.java @@ -4,4 +4,4 @@ * @version 1.0 * @since 1.0 */ -package com.micro.fast.common.annotation; \ No newline at end of file +package com.micro.fast.common.datasource.dynamic.annotation; \ No newline at end of file diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/aspect/DynamicDataSourceAspect.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/aspect/DynamicDataSourceAspect.java similarity index 84% rename from boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/aspect/DynamicDataSourceAspect.java rename to boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/aspect/DynamicDataSourceAspect.java index 51ae081..86f7f05 100644 --- a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/aspect/DynamicDataSourceAspect.java +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/aspect/DynamicDataSourceAspect.java @@ -1,7 +1,7 @@ -package com.micro.fast.common.aspect; +package com.micro.fast.common.datasource.dynamic.aspect; -import com.micro.fast.common.annotation.SwitchDataSource; -import com.micro.fast.common.dao.DataSourceContextHolder; +import com.micro.fast.common.datasource.dynamic.annotation.SwitchDataSource; +import com.micro.fast.common.datasource.dynamic.DataSourceContextHolder; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.Aspect; @@ -22,13 +22,13 @@ import java.lang.reflect.Method; @Component public class DynamicDataSourceAspect { - @Pointcut("@annotation(com.micro.fast.common.annotation.SwitchDataSource)") + @Pointcut("@annotation(com.micro.fast.common.datasource.dynamic.annotation.SwitchDataSource)") public void mybatisExecutionSqlPointcut(){ } /** * 在SwitchDataSource注解的方法之前执行 - * @see com.micro.fast.common.annotation.SwitchDataSource + * @see SwitchDataSource */ @Before("mybatisExecutionSqlPointcut()") public void beforeMybatisExecutionSql(JoinPoint joinPoint){ @@ -58,7 +58,7 @@ public class DynamicDataSourceAspect { /** * 在SwitchDataSource注解的方法之后执行 - * @see com.micro.fast.common.annotation.SwitchDataSource + * @see SwitchDataSource */ @After("mybatisExecutionSqlPointcut()") public void afterMybatisExecutionSql(){ diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/aspect/package-info.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/aspect/package-info.java similarity index 67% rename from boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/aspect/package-info.java rename to boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/aspect/package-info.java index 7173ed4..3ec5e21 100644 --- a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/aspect/package-info.java +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/aspect/package-info.java @@ -4,4 +4,4 @@ * @version 1.0 * @since 1.0 */ -package com.micro.fast.common.aspect; \ No newline at end of file +package com.micro.fast.common.datasource.dynamic.aspect; \ No newline at end of file diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/condition/MasterDataSourceCondition.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/condition/MasterDataSourceCondition.java similarity index 94% rename from boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/condition/MasterDataSourceCondition.java rename to boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/condition/MasterDataSourceCondition.java index ce44c78..87d240b 100644 --- a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/condition/MasterDataSourceCondition.java +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/condition/MasterDataSourceCondition.java @@ -1,4 +1,4 @@ -package com.micro.fast.common.condition; +package com.micro.fast.common.datasource.dynamic.condition; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/package-info.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/package-info.java new file mode 100644 index 0000000..7418f59 --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/dynamic/package-info.java @@ -0,0 +1 @@ +package com.micro.fast.common.datasource.dynamic; \ No newline at end of file diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/package-info.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/package-info.java new file mode 100644 index 0000000..3a9f58c --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/datasource/package-info.java @@ -0,0 +1 @@ +package com.micro.fast.common.datasource; \ No newline at end of file diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/MetaObjectKey.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/MetaObjectKey.java new file mode 100644 index 0000000..4b4eb20 --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/MetaObjectKey.java @@ -0,0 +1,10 @@ +package com.micro.fast.common.plugin; + +/** + * @author lsy + */ +public interface MetaObjectKey { + String DELEGATE_MAPPED_STATEMENT = "delegate.mappedStatement"; + String DELEGATE_PARAMETER_HANDLER = "delegate.parameterHandler"; + String DELEGATE_BOUND_SQL_SQL = "delegate.boundSql.sql"; +} diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/PluginUtils.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/PluginUtils.java new file mode 100644 index 0000000..aec827c --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/PluginUtils.java @@ -0,0 +1,35 @@ +package com.micro.fast.common.plugin; + +/** + * mybatis插件工具类 + * @author lsy + */ +public class PluginUtils { + + /** + * 不能被实例化 + */ + private PluginUtils(){ + + } + + /** + * 根据语句id获取方法名 + * @param statementId + * @return + */ + public static String getMethodName(String statementId){ + int i = statementId.lastIndexOf("."); + return statementId.substring(i + 1); + } + + /** + * 根据语句id获取全类名 + * @param statementId + * @return + */ + public static String getClassName(String statementId){ + int i = statementId.lastIndexOf("."); + return statementId.substring(0,i); + } +} diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/CacheOptimisticLock.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/CacheOptimisticLock.java new file mode 100644 index 0000000..7fbc302 --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/CacheOptimisticLock.java @@ -0,0 +1,18 @@ +package com.micro.fast.common.plugin.lock.optimistic; + +import lombok.Getter; +import lombok.Setter; + +import java.lang.reflect.Field; + +/** + * @author lsy + */ +@Getter +@Setter +public class CacheOptimisticLock { + + private String fieldName; + + private Field field; +} diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/OptimisticException.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/OptimisticException.java new file mode 100644 index 0000000..66b5c34 --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/OptimisticException.java @@ -0,0 +1,11 @@ +package com.micro.fast.common.plugin.lock.optimistic; + +/** + * 乐观锁插件运行时异常 + * @author lsy + */ +public class OptimisticException extends RuntimeException { + public OptimisticException(String message) { + + } +} diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/OptimisticLock.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/OptimisticLock.java new file mode 100644 index 0000000..edd8431 --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/OptimisticLock.java @@ -0,0 +1,14 @@ +package com.micro.fast.common.plugin.lock.optimistic; + +import java.lang.annotation.*; + +/** + * @author lsy + * 加在方法上,表示方法使用乐观锁 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.METHOD) +@Documented +public @interface OptimisticLock { + +} diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/Version.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/Version.java new file mode 100644 index 0000000..08f738a --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/Version.java @@ -0,0 +1,17 @@ +package com.micro.fast.common.plugin.lock.optimistic; + +import java.lang.annotation.*; + +/** + * @author lsy + * 运行时注解 + * 可以加载字段和参数上 + * 可以被继承 + * 标识实体类哪个字段是乐观锁 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD,ElementType.PARAMETER}) +@Documented +public @interface Version { + String value() default ""; +} diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/VersionLock.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/VersionLock.java new file mode 100644 index 0000000..b60b2b7 --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/lock/optimistic/VersionLock.java @@ -0,0 +1,172 @@ +package com.micro.fast.common.plugin.lock.optimistic; + +import com.micro.fast.common.plugin.MetaObjectKey; +import com.micro.fast.common.plugin.PluginUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.ibatis.executor.parameter.ParameterHandler; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.mapping.BoundSql; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.plugin.*; +import org.apache.ibatis.reflection.DefaultReflectorFactory; +import org.apache.ibatis.reflection.MetaObject; +import org.apache.ibatis.reflection.SystemMetaObject; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Parameter; +import java.sql.Connection; +import java.util.Properties; +import java.util.concurrent.ConcurrentHashMap; + +/** + * mybatis简单的乐观锁插件,不支持级联,不支持批量更新,仅支持单条数据的更新。 + * 使用方式: + * 1. 给实体类上版本字段加上@Version + * 2. 给想要使用乐观锁的dao方法上加上@OptimisticLock注解 + * 3. 使用dao方法的时候,更新对象要以实体类的对象为参数。 + * 拦截StatementHandler类的prepare(Connection.class,Integer.class)方法 + * @author lsy + */ +@Intercepts({@Signature(type= StatementHandler.class,method = "prepare",args = {Connection.class,Integer.class})}) +public class VersionLock implements Interceptor { + + /** + * 存储已经获取过的statementId 和 fieldName + */ + private static final ConcurrentHashMap cache = new ConcurrentHashMap<>(); + + /** + * 需要拦截的方法名 + */ + public static final String PREPARE = "prepare"; + /** + * sql 中的条件查询符号 + */ + public static final String WHERE = "where"; + + /** + * 拦截器主体方法 + * @param invocation 被拦截的方法的代理 + * @return + * @throws Throwable + */ + @Override + public Object intercept(Invocation invocation) throws Throwable { + String interceptMethodName = invocation.getMethod().getName(); + if (!PREPARE.equals(interceptMethodName)){ + return invocation.proceed(); + } + // 获取语句对象 + StatementHandler statementHandler = (StatementHandler)invocation.getTarget(); + // MetaObject是mybatis提供的简化插件开发的类 + MetaObject metaObject = MetaObject.forObject(statementHandler, + SystemMetaObject.DEFAULT_OBJECT_FACTORY, + SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, + new DefaultReflectorFactory()); + // 获取mapper接口实例,是否指定了乐观锁 + MappedStatement mappedStatement = (MappedStatement)metaObject.getValue(MetaObjectKey.DELEGATE_MAPPED_STATEMENT); + String statementId = mappedStatement.getId(); + // 是否已经获取过这个语句的对应的实体类的版本对象 + StringBuilder fieldName = new StringBuilder(); + BoundSql boundSql = statementHandler.getBoundSql(); + // 获取原始的sql update tableName set a=123,b=234,c=345 where id = 123 + String sql = boundSql.getSql(); + // 获取参数对象实例,检查实体类是不是只有一个参数加了@Version注解 + ParameterHandler parameterHandler = (ParameterHandler)metaObject.getValue(MetaObjectKey.DELEGATE_PARAMETER_HANDLER); + Object params = parameterHandler.getParameterObject(); + String versionFieldValue = null; + // 已经获取过,肯定是乐观锁的语句 + if(cache.contains(statementId)){ + CacheOptimisticLock cacheOptimisticLock = cache.get(statementId); + Field field = cacheOptimisticLock.getField(); + fieldName.append(cacheOptimisticLock.getFieldName()); + field.setAccessible(true); + versionFieldValue = (String)field.get(params); + // 修改原本的sql + sql += " and" + fieldName.toString() + "=" + versionFieldValue; + int indexOfWhere = sql.indexOf(WHERE); + String begin = sql.substring(0, indexOfWhere); + String end = sql.substring(indexOfWhere); + String optimistVersionSql = begin + " ," + fieldName + "=" + (versionFieldValue+1) + " " + end; + metaObject.setValue(MetaObjectKey.DELEGATE_BOUND_SQL_SQL,optimistVersionSql); + return invocation.proceed(); + }else{ + String className = PluginUtils.getClassName(statementId); + String methodName = PluginUtils.getMethodName(statementId); + Class aClass = Class.forName(className); + Method[] methods = aClass.getMethods(); + // 获取实体类的全类名 + String nameDO = ""; + for (Method method : methods) { + if (method.getName().equals(methodName)) { + // 找到mapper接口方法 + Annotation[] annotations = method.getAnnotations(); + boolean optimisticLock = false; + for (Annotation annotation : annotations) { + if (annotation.getClass() == OptimisticLock.class){ + Parameter[] parameters = method.getParameters(); + Parameter parameter = parameters[0]; + nameDO = parameter.getName(); + optimisticLock = true; + } + } + if (!optimisticLock){ + return invocation.proceed(); + } + break; + } + } + // 获取参数对象实例,检查实体类是不是只有一个参数加了@Version注解 + Class aClassDO = Class.forName(nameDO); + Field[] fields = aClassDO.getFields(); + int haveOneVersionFlagfield = 0; + Field versionField = null; + for (Field field : fields) { + Annotation[] annotations = field.getAnnotations(); + for (Annotation annotation : annotations) { + if (annotation.annotationType() == Version.class){ + ++ haveOneVersionFlagfield; + String name = field.getName(); + fieldName.append(name); + versionField = field; + } + } + } + if (haveOneVersionFlagfield != 1){ + throw new OptimisticException("请保证实体类有且只有一个属性加乐观锁版本注解"); + } + // 突破属性的访问权限 + versionField.setAccessible(true); + versionFieldValue = (String)versionField.get(params); + if (StringUtils.isBlank(versionFieldValue)){ + throw new OptimisticException("请给版本控制属性赋值"); + } + // 存储乐观锁 + CacheOptimisticLock cacheOptimisticLock = new CacheOptimisticLock(); + cacheOptimisticLock.setField(versionField); + cacheOptimisticLock.setFieldName(fieldName.toString()); + cache.put(statementId,cacheOptimisticLock); + // 修改原本的sql + sql += " and" + fieldName.toString() + "=" + versionFieldValue; + int indexOfWhere = sql.indexOf(WHERE); + String begin = sql.substring(0, indexOfWhere); + String end = sql.substring(indexOfWhere); + String optimistVersionSql = begin + " ," + fieldName + "=" + (versionFieldValue+1) + " " + end; + metaObject.setValue(MetaObjectKey.DELEGATE_BOUND_SQL_SQL,optimistVersionSql); + return invocation.proceed(); + } + } + + @Override + public Object plugin(Object target) { + // 封装拦截器为插件,此拦截器只对StatementHandler和ParameterHandler生效,对执行器和ResultSetHandler不生效 + return Plugin.wrap(target,this); + } + + @Override + public void setProperties(Properties properties) { + // 给插件传递参数 + } +} diff --git a/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/package-info.java b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/package-info.java new file mode 100644 index 0000000..07398a1 --- /dev/null +++ b/boot-starter/boot-starter-ssm/src/main/java/com/micro/fast/common/plugin/package-info.java @@ -0,0 +1,4 @@ +/** + * mybatis扩展插件 + */ +package com.micro.fast.common.plugin; \ No newline at end of file