Skip to content

Commit

Permalink
修复正常场景下逻辑删除注解会出现的严重Bug
Browse files Browse the repository at this point in the history
  • Loading branch information
duwey committed Nov 29, 2018
1 parent c32b74f commit 8dde462
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public String deleteByExample(MappedStatement ms) {
if (getConfig().isSafeDelete()) {
sql.append(SqlHelper.exampleHasAtLeastOneCriteriaCheck("_parameter"));
}
if (SqlHelper.hasLogicDeleteAndCheckRepeated(entityClass)) {
if (SqlHelper.hasLogicDeleteColumn(entityClass)) {
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
sql.append("<set>");
sql.append(SqlHelper.logicDeleteColumnEqualsValue(entityClass, true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public String delete(MappedStatement ms) {
sql.append(SqlHelper.notAllNullParameterCheck("_parameter", EntityHelper.getColumns(entityClass)));
}
// 如果是逻辑删除,则修改为更新表,修改逻辑删除字段的值
if (SqlHelper.hasLogicDeleteAndCheckRepeated(entityClass)) {
if (SqlHelper.hasLogicDeleteColumn(entityClass)) {
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
sql.append("<set>");
sql.append(SqlHelper.logicDeleteColumnEqualsValue(entityClass, true));
Expand All @@ -78,7 +78,7 @@ public String delete(MappedStatement ms) {
public String deleteByPrimaryKey(MappedStatement ms) {
final Class<?> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
if (SqlHelper.hasLogicDeleteAndCheckRepeated(entityClass)) {
if (SqlHelper.hasLogicDeleteColumn(entityClass)) {
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
sql.append("<set>");
sql.append(SqlHelper.logicDeleteColumnEqualsValue(entityClass, true));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ public BaseInsertProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
public String insert(MappedStatement ms) {
Class<?> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
boolean hasLogicDelete = false;
//获取全部列
Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
EntityColumn logicDeleteColumn = SqlHelper.getLogicDeleteColumn(entityClass);
processKey(sql, entityClass, ms, columnList);
sql.append(SqlHelper.insertIntoTable(entityClass, tableName(entityClass)));
sql.append(SqlHelper.insertColumns(entityClass, false, false, false));
Expand All @@ -56,8 +56,7 @@ public String insert(MappedStatement ms) {
if (!column.isInsertable()) {
continue;
}
hasLogicDelete = SqlHelper.isLogicDeleteColumn(entityClass, column, hasLogicDelete);
if (hasLogicDelete) {
if (logicDeleteColumn != null && logicDeleteColumn == column) {
sql.append(SqlHelper.getLogicDeletedValue(column, false)).append(",");
continue;
}
Expand All @@ -84,9 +83,9 @@ public String insert(MappedStatement ms) {
public String insertSelective(MappedStatement ms) {
Class<?> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
boolean hasLogicDelete = false;
//获取全部列
Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
EntityColumn logicDeleteColumn = SqlHelper.getLogicDeleteColumn(entityClass);
processKey(sql, entityClass, ms, columnList);
sql.append(SqlHelper.insertIntoTable(entityClass, tableName(entityClass)));
sql.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
Expand All @@ -95,10 +94,9 @@ public String insertSelective(MappedStatement ms) {
continue;
}
if (column.isIdentity()) {
sql.append(column.getColumn() + ",");
sql.append(column.getColumn()).append(",");
} else {
hasLogicDelete = SqlHelper.isLogicDeleteColumn(entityClass, column, hasLogicDelete);
if (hasLogicDelete) {
if (logicDeleteColumn != null && logicDeleteColumn == column) {
sql.append(column.getColumn()).append(",");
continue;
}
Expand All @@ -107,15 +105,12 @@ public String insertSelective(MappedStatement ms) {
}
sql.append("</trim>");

// 上面column遍历结束,重置是否有逻辑删除注解的判断值
hasLogicDelete = false;
sql.append("<trim prefix=\"VALUES(\" suffix=\")\" suffixOverrides=\",\">");
for (EntityColumn column : columnList) {
if (!column.isInsertable()) {
continue;
}
hasLogicDelete = SqlHelper.isLogicDeleteColumn(entityClass, column, hasLogicDelete);
if (hasLogicDelete) {
if (logicDeleteColumn != null && logicDeleteColumn == column) {
sql.append(SqlHelper.getLogicDeletedValue(column, false)).append(",");
continue;
}
Expand Down
34 changes: 34 additions & 0 deletions base/src/test/java/tk/mybatis/mapper/model/BaseLogicDelete.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package tk.mybatis.mapper.model;

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import tk.mybatis.mapper.annotation.LogicDelete;

public class BaseLogicDelete {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Integer id;

@LogicDelete(isDeletedValue = 0, notDeletedValue = 1)
@Column(name = "is_valid")
protected Integer isValid;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public Integer getIsValid() {
return isValid;
}

public void setIsValid(Integer isValid) {
this.isValid = isValid;
}
}
30 changes: 3 additions & 27 deletions base/src/test/java/tk/mybatis/mapper/model/TbUserLogicDelete.java
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
package tk.mybatis.mapper.model;

import tk.mybatis.mapper.annotation.LogicDelete;

import javax.persistence.*;
import javax.persistence.Column;
import javax.persistence.Table;

@Table(name = "tb_user")
public class TbUserLogicDelete {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
public class TbUserLogicDelete extends BaseLogicDelete {

@Column(name = "username")
private String username;

@Column(name = "password")
private String password;

@LogicDelete(isDeletedValue = 0, notDeletedValue = 1)
@Column(name = "is_valid")
private Integer isValid;

@Override
public String toString() {
return "TbUser{" +
Expand All @@ -31,14 +22,6 @@ public String toString() {
'}';
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getUsername() {
return username;
}
Expand All @@ -55,11 +38,4 @@ public void setPassword(String password) {
this.password = password;
}

public Integer getIsValid() {
return isValid;
}

public void setIsValid(Integer isValid) {
this.isValid = isValid;
}
}
50 changes: 17 additions & 33 deletions core/src/main/java/tk/mybatis/mapper/mapperhelper/SqlHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -562,7 +562,7 @@ public static String wherePKColumns(Class<?> entityClass, boolean useVersion) {
*/
public static String wherePKColumns(Class<?> entityClass,String entityName, boolean useVersion) {
StringBuilder sql = new StringBuilder();
boolean hasLogicDelete = hasLogicDeleteAndCheckRepeated(entityClass);
boolean hasLogicDelete = hasLogicDeleteColumn(entityClass);

sql.append("<where>");
//获取全部列
Expand Down Expand Up @@ -609,12 +609,13 @@ public static String whereAllIfColumns(Class<?> entityClass, boolean empty, bool
sql.append("<where>");
//获取全部列
Set<EntityColumn> columnSet = EntityHelper.getColumns(entityClass);
EntityColumn logicDeleteColumn = SqlHelper.getLogicDeleteColumn(entityClass);
//当某个列有主键策略时,不需要考虑他的属性是否为空,因为如果为空,一定会根据主键策略给他生成一个值
for (EntityColumn column : columnSet) {
hasLogicDelete = isLogicDeleteColumn(entityClass, column, hasLogicDelete);
if (!useVersion || !column.getEntityField().isAnnotationPresent(Version.class)) {
// 逻辑删除,后面拼接逻辑删除字段的未删除条件
if (hasLogicDelete) {
if (logicDeleteColumn != null && logicDeleteColumn == column) {
hasLogicDelete = true;
continue;
}
sql.append(getIfNotNull(column, " AND " + column.getColumnEqualsHolder(), empty));
Expand Down Expand Up @@ -679,16 +680,13 @@ public static String whereLogicDelete(Class<?> entityClass, boolean isDeleted) {
* @param isDeleted true 已经逻辑删除 false 未逻辑删除
*/
public static String logicDeleteColumnEqualsValue(Class<?> entityClass, boolean isDeleted) {
Set<EntityColumn> columnSet = EntityHelper.getColumns(entityClass);
boolean hasLogicDelete = false;
String result = "";
for (EntityColumn column : columnSet) {
hasLogicDelete = isLogicDeleteColumn(entityClass, column, hasLogicDelete);
if (hasLogicDelete) {
result = logicDeleteColumnEqualsValue(column, isDeleted);
}
EntityColumn logicDeleteColumn = SqlHelper.getLogicDeleteColumn(entityClass);

if (logicDeleteColumn != null) {
return logicDeleteColumnEqualsValue(logicDeleteColumn, isDeleted);
}
return result;

return "";
}

/**
Expand Down Expand Up @@ -729,11 +727,11 @@ public static int getLogicDeletedValue(EntityColumn column, boolean isDeleted) {
}

/**
* 是否有逻辑删除的注解,并且检查重复注解
* 是否有逻辑删除的注解
* @param entityClass
* @return
*/
public static boolean hasLogicDeleteAndCheckRepeated(Class<?> entityClass) {
public static boolean hasLogicDeleteColumn(Class<?> entityClass) {
return getLogicDeleteColumn(entityClass) != null;
}

Expand All @@ -747,31 +745,17 @@ public static EntityColumn getLogicDeleteColumn(Class<?> entityClass) {
Set<EntityColumn> columnSet = EntityHelper.getColumns(entityClass);
boolean hasLogicDelete = false;
for (EntityColumn column: columnSet) {
hasLogicDelete = isLogicDeleteColumn(entityClass, column, hasLogicDelete);
if (hasLogicDelete) {
if (column.getEntityField().isAnnotationPresent(LogicDelete.class)) {
if (hasLogicDelete) {
throw new LogicDeleteException(entityClass.getCanonicalName() + " 中包含多个带有 @LogicDelete 注解的字段,一个类中只能存在一个带有 @LogicDelete 注解的字段!");
}
hasLogicDelete = true;
logicDeleteColumn = column;
}
}
return logicDeleteColumn;
}

/**
* column是否为逻辑删除注解的列
* @param entityClass
* @param column
* @param hasLogicDelete 当前是否已经有逻辑删除的列,主要用来在循环column中判断重复抛异常,直接调用传false即可
* @return
*/
public static boolean isLogicDeleteColumn(Class<?> entityClass, EntityColumn column, boolean hasLogicDelete) {
if (column.getEntityField().isAnnotationPresent(LogicDelete.class)) {
if (hasLogicDelete) {
throw new LogicDeleteException(entityClass.getCanonicalName() + " 中包含多个带有 @LogicDelete 注解的字段,一个类中只能存在一个带有 @LogicDelete 注解的字段!");
}
hasLogicDelete = true;
}
return hasLogicDelete;
}

/**
* 获取默认的orderBy,通过注解设置的
*
Expand Down

0 comments on commit 8dde462

Please sign in to comment.