MybatisGenerator外掛開發六【邏輯刪除】
邏輯刪除在專案中也是很常見的,比較常見的方式是新增一個deleted
的標記位,當然也有其他的實現方式。本章節的外掛針對的是新增標記位的方式來實現邏輯刪除的。如果說沒有和deleted
標記位一起的唯一聯合索引,那是很容易實現的,標誌位只要兩個值:0、1,然後通過updateByExampleSelective
修改就可以了。但是往往我們表中會有唯一索引在,比如說名字不能重複之類的。這個時候我們採取的簡單的處理方式是set deleted = deleted + 1
來避免刪除後不能再次新增同樣資料的問題。索性這個外掛就提供了兩個方法:logicDelete
和logicDeleteWithUIndex
。
修改Mapper介面和SqlMap檔案
public class LogicDeletePluginextends PluginAdapter{ @Override public boolean validate(List<String> list){ return true; } /** * 修改Mapper類 */ @Override public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable){ addLogicDeleteMethod(interfaze); return true; } private void addLogicDeleteMethod(Interface interfaze){ // 方法的返回值 FullyQualifiedJavaType returnTypeInt = FullyQualifiedJavaType.getIntInstance(); Method logicDeleteMethod = new Method(); // 1.設定方法可見性 logicDeleteMethod.setVisibility(JavaVisibility.PUBLIC); // 2.設定返回值型別 int型別 logicDeleteMethod.setReturnType(returnTypeInt); // 3.設定方法名 logicDeleteMethod.setName("logicDelete"); // 4.設定引數列表 FullyQualifiedJavaType paramType = PrimitiveTypeWrapper.getLongInstance(); logicDeleteMethod.addParameter(new Parameter(paramType, "id")); interfaze.addMethod(logicDeleteMethod); Method logicDeleteWithUIndexMethod = new Method(); // 1.設定方法可見性 logicDeleteWithUIndexMethod.setVisibility(JavaVisibility.PUBLIC); // 2.設定返回值型別 int型別 logicDeleteWithUIndexMethod.setReturnType(returnTypeInt); // 3.設定方法名 logicDeleteWithUIndexMethod.setName("logicDeleteWithUIndex"); // 4.設定引數列表 FullyQualifiedJavaType paramTypeSelective = PrimitiveTypeWrapper.getLongInstance(); logicDeleteWithUIndexMethod.addParameter(new Parameter(paramTypeSelective, "id", "@Param(\"id\")")); logicDeleteWithUIndexMethod.addParameter(new Parameter(FullyQualifiedJavaType.getStringInstance(), "uIndexes", "@Param(\"uIndexes\")", true)); interfaze.addMethod(logicDeleteWithUIndexMethod); } /** * 修改Mapper.xml */ @Override public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable){ addLogicDeleteXml(document, introspectedTable); addLogicDeleteWithUIndexXml(document, introspectedTable); return true; } private void addLogicDeleteXml(Document document, IntrospectedTable introspectedTable){ XmlElement logicDeleteElement = new XmlElement("update"); logicDeleteElement.addAttribute(new Attribute("id", "logicDelete")); logicDeleteElement.addAttribute(new Attribute("parameterType", "java.lang.Long")); logicDeleteElement.addElement(new TextElement("update " + introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime())); logicDeleteElement.addElement(new TextElement("set deleted = 1, update_time = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where id = #{id,jdbcType=BIGINT}")); document.getRootElement().addElement(logicDeleteElement); } private void addLogicDeleteWithUIndexXml(Document document, IntrospectedTable introspectedTable){ XmlElement logicDeleteWithUIndexElement = new XmlElement("update"); logicDeleteWithUIndexElement.addAttribute(new Attribute("id", "logicDeleteWithUIndex")); logicDeleteWithUIndexElement.addAttribute(new Attribute("parameterType", "map")); logicDeleteWithUIndexElement.addElement(new TextElement("update " + introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime() + " A,")); logicDeleteWithUIndexElement.addElement(new TextElement("(select C.deleted from " + introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime() + " C,")); logicDeleteWithUIndexElement.addElement(new TextElement("(select")); XmlElement foreachElement = new XmlElement("foreach"); foreachElement.addAttribute(new Attribute("collection", "uIndexes")); foreachElement.addAttribute(new Attribute("index", "index")); foreachElement.addAttribute(new Attribute("item", "column")); foreachElement.addAttribute(new Attribute("separator", ",")); foreachElement.addElement(new TextElement("${column}")); logicDeleteWithUIndexElement.addElement(foreachElement); logicDeleteWithUIndexElement.addElement(new TextElement("from " + introspectedTable.getAliasedFullyQualifiedTableNameAtRuntime() + " where id = #{id,jdbcType=BIGINT}) D")); XmlElement whereElement = new XmlElement("where"); XmlElement whereForachElement = new XmlElement("foreach"); whereForachElement.addAttribute(new Attribute("collection", "uIndexes")); whereForachElement.addAttribute(new Attribute("index", "index")); whereForachElement.addAttribute(new Attribute("item", "column")); whereForachElement.addElement(new TextElement(" and C.${column} = D.${column}")); whereElement.addElement(whereForachElement); logicDeleteWithUIndexElement.addElement(whereElement); logicDeleteWithUIndexElement.addElement(new TextElement("order by C.deleted desc limit 1) B")); logicDeleteWithUIndexElement.addElement(new TextElement("set A.deleted = B.deleted + 1, A.update_time = REPLACE(unix_timestamp(current_timestamp(3)),'.','')")); logicDeleteWithUIndexElement.addElement(new TextElement("where A.id = #{id,jdbcType=BIGINT}")); logicDeleteWithUIndexElement.addElement(new TextElement("and A.deleted = 0")); document.getRootElement().addElement(logicDeleteWithUIndexElement); } }
邏輯比較簡單,就是在Mapper介面和SqlMap檔案中新增方法和對應的sql語句就可以了。
檢視生成檔案
將外掛新增到專案中,並且執行完MybatisGenerator,我們來檢視下生成的相關檔案:
public interface AdministratorMapper{ ... int logicDelete(Long id); int logicDeleteWithUIndex(@Param("id")Long id, @Param("uIndexes")String ... uIndexes); }
<updateid="logicDelete"parameterType="java.lang.Long"> update administrator set deleted = 1, update_time = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where id = #{id,jdbcType=BIGINT} </update> <updateid="logicDeleteWithUIndex"parameterType="map"> update administrator A, (select C.deletedfrom administrator C, (select <foreachcollection="uIndexes"index="index"item="column"separator=","> ${column} </foreach> from administrator where id = #{id,jdbcType=BIGINT}) D <where> <foreachcollection="uIndexes"index="index"item="column"> and C.${column} = D.${column} </foreach> </where> order by C.deleted desc limit 1) B set A.deleted = B.deleted + 1, A.update_time = REPLACE(unix_timestamp(current_timestamp(3)),'.','') where A.id = #{id,jdbcType=BIGINT} and A.deleted = 0 </update>
如何使用
使用方式如下:
這裡同樣用到了之前新增到Model類中的表字段列舉。
administratorMapper.logicDeleteWithUIndex(id, Administrator.COLUMNS.MOBILE.getColumn()
本章節就到這裡了。以後要用外掛來實現一些特殊的Sql,應該可以舉一反三了。