All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.acyou.leo.framework.mybatis.OptimistLockCheckInterceptor Maven / Gradle / Ivy

package cn.acyou.leo.framework.mybatis;

import cn.acyou.leo.framework.exception.ModifiedByAnotherUserException;
import cn.acyou.leo.framework.exception.RemovedByAnotherUserException;
import cn.acyou.leo.framework.mapper.tkMapper.CommonMapper;
import cn.acyou.leo.framework.util.ReflectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

/**
 * 乐观锁检查
 * 

* 1. 实体的属性中要有: * 主键注解:{@link Id} * 版本号注解:{@link Version} * 2. 适用方法: * {@link tk.mybatis.mapper.common.base.update.UpdateByPrimaryKeyMapper#updateByPrimaryKey(Object)} * {@link tk.mybatis.mapper.common.base.update.UpdateByPrimaryKeySelectiveMapper#updateByPrimaryKeySelective(Object)} * {@link CommonMapper#updateByPrimaryKeySelectiveCustom(Object)} * {@link tk.mybatis.mapper.common.base.delete.DeleteMapper#delete(Object)} * 在使用这些方法时,当主键和版本号都不为空的时候,检查乐观锁版本 *

* 3. 检查乐观锁版本,抛出异常: * 被修改:{@link ModifiedByAnotherUserException} * 被删除:{@link RemovedByAnotherUserException} * * @author youfang * @version [1.0.0, 2020/7/7] **/ @Intercepts({ @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}) }) public class OptimistLockCheckInterceptor implements Interceptor { private static final Logger log = LoggerFactory.getLogger(OptimistLockCheckInterceptor.class); private static final String SUCCESS_FLAG = "1"; private static final String ERROR_FLAG = "0"; @Override public Object intercept(Invocation invocation) throws Throwable { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; if (SqlCommandType.UPDATE == mappedStatement.getSqlCommandType() || SqlCommandType.DELETE == mappedStatement.getSqlCommandType()) { if (invocation.getArgs().length > 1) { Object parameterObject = invocation.getArgs()[1]; Class entityClass = parameterObject.getClass(); if (entityClass.isAnnotationPresent(Table.class)) { Table annotation = entityClass.getAnnotation(Table.class); String tableName = annotation.name(); Field idField = ReflectUtils.recursiveFieldFinder(entityClass, Id.class); Field versionEntityField = ReflectUtils.recursiveFieldFinder(entityClass, Version.class); if (idField != null && versionEntityField != null) { String idColumnName = idField.getAnnotation(Column.class).name(); String versionColumnName = versionEntityField.getAnnotation(Column.class).name(); Object idColumnValue = ReflectUtils.getFieldValue(parameterObject, idField); Object versionColumnValue = ReflectUtils.getFieldValue(parameterObject, versionEntityField); if (!StringUtils.EMPTY.equals(idColumnName) && !StringUtils.EMPTY.equals(versionColumnName) && idColumnValue != null && versionColumnValue != null) { Executor executor = (Executor) invocation.getTarget(); Connection connection = executor.getTransaction().getConnection(); Object databaseVersionCheck = null; //select version = 35 from table WHERE id = 1; result - 正确:1,错误:0,不存在:null PreparedStatement stmt = connection.prepareStatement(String.format("SELECT %s = ? FROM %s WHERE %s = ?", versionColumnName, tableName, idColumnName)); stmt.setObject(1, versionColumnValue); stmt.setObject(2, idColumnValue); log.info(stmt.toString()); stmt.execute(); ResultSet rs = stmt.getResultSet(); if (rs.first()) { databaseVersionCheck = rs.getObject(1); rs.close(); } stmt.close(); //adjust if (databaseVersionCheck == null) { throw new RemovedByAnotherUserException(); } if (ERROR_FLAG.equals(databaseVersionCheck.toString())) { throw new ModifiedByAnotherUserException(); } if (SqlCommandType.UPDATE == mappedStatement.getSqlCommandType()) { Integer version = Integer.parseInt(versionColumnValue.toString()) + 1; ReflectUtils.setFieldValue(versionColumnName, parameterObject, version); } } } } } } return invocation.proceed(); } @Override public Object plugin(Object target) { if (target instanceof Executor) { return Plugin.wrap(target, this); } return target; } @Override public void setProperties(Properties properties) { } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy