提要

本文是 小小商城-SSM 版的 细节详解系列 之一,项目 github:https://github.com/xenv/S-mall-ssm 本文代码大部分在 github 中 可以找到。

我们在开发的过程中,往往会使用到软删除,即删除时不真正删除还是打标记,但是这样在查询的时候往往会遇到一些麻烦,特别是使用 mybatis-generator 的时候,因为不好自定义生成的 mapper ,这样在查询的时候很容易把已经打标的数据又查出来,非常不安全。

那么,我们怎么让 mybatis-generator 生成的 mapper 支持软删除呢,还好,我们可以通过开发自定义插件实现。

具体实现

完整实现代码见:DeleteAtPlugin.java

  1. 新建插件类,继承 PluginAdapter,重写 validate(..)方法,让其直接 return true; 不进行参数校验

  2. 重写 sqlMapExampleWhereClauseElementGenerated(…)方法,这个是 生成 selectByExample 部分的 mapper 代码的钩子,我们在合适的地方(我是 debug 找的),加入一个软删除标记 is null 即可

  3. 重写 sqlMapSelectByPrimaryKeyElementGenerated(…)方法,我们在合适的地方,加入一个软删除标记 is null 即可

完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class DeleteAtPlugin extends PluginAdapter {

@Override
public boolean sqlMapExampleWhereClauseElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {

for (Element child : element.getElements()) {
if (child instanceof XmlElement && ((XmlElement) child).getName().equals("where")) {
TextElement element1 = new TextElement("and deleteAt is NULL");
((XmlElement) child).getElements().add(element1);
break;
}
}
return true;
}

@Override
public boolean sqlMapSelectByPrimaryKeyElementGenerated(XmlElement element, IntrospectedTable introspectedTable) {
TextElement element1 = new TextElement("and deleteAt is NULL");
element.getElements().add(element1);
return true;
}

@Override
public boolean validate(List<String> list) {
return true;
}


}
  1. 配置 mybatis-generator 插件
1
2
3
4
5
6
7
8
9
<generatorConfiguration>
<context id="Mysql" targetRuntime="MyBatis3" >
<!--给select增加deleteAt is null属性-->
<plugin type="tmall.util.MBGPlugins.DeleteAtPlugin">
</plugin>
....
</context>
...
</generatorConfiguration>
  1. 在 Service 删除时候,调用 update 方法而不是 delete 方法 ,使软删除标记不为空即可。

OK,大功告成