LogicSqlInjector.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /**
  2. * Copyright (c) 2011-2014, hubin (jobob@qq.com).
  3. * <p>
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. * <p>
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. * <p>
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.baomidou.mybatisplus.mapper;
  17. import java.util.List;
  18. import java.util.Map;
  19. import org.apache.ibatis.mapping.SqlSource;
  20. import org.apache.ibatis.scripting.defaults.RawSqlSource;
  21. import com.baomidou.mybatisplus.entity.TableFieldInfo;
  22. import com.baomidou.mybatisplus.entity.TableInfo;
  23. import com.baomidou.mybatisplus.enums.SqlMethod;
  24. import com.baomidou.mybatisplus.toolkit.SqlReservedWords;
  25. import com.baomidou.mybatisplus.toolkit.StringUtils;
  26. /**
  27. * <p>
  28. * SQL 自动注入逻辑处理器<br>
  29. * 1、支持逻辑删除
  30. * </p>
  31. *
  32. * @author hubin willenfoo
  33. * @Date 2017-09-09
  34. */
  35. public class LogicSqlInjector extends AutoSqlInjector {
  36. /**
  37. * 根据 ID 删除
  38. */
  39. @Override
  40. protected void injectDeleteByIdSql(boolean batch, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  41. if (table.isLogicDelete()) {
  42. // 逻辑删除注入
  43. SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE_BY_ID;
  44. SqlSource sqlSource;
  45. String idStr = table.getKeyColumn();
  46. if (batch) {
  47. sqlMethod = SqlMethod.LOGIC_DELETE_BATCH_BY_IDS;
  48. StringBuilder ids = new StringBuilder();
  49. ids.append("\n<foreach item=\"item\" index=\"index\" collection=\"list\" separator=\",\">");
  50. ids.append("#{item}");
  51. ids.append("\n</foreach>");
  52. idStr = ids.toString();
  53. }
  54. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlLogicSet(table),
  55. table.getKeyColumn(), idStr);
  56. sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  57. this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
  58. } else {
  59. // 正常删除
  60. super.injectDeleteByIdSql(batch, mapperClass, modelClass, table);
  61. }
  62. }
  63. /**
  64. * 根据 SQL 删除
  65. */
  66. @Override
  67. protected void injectDeleteSql(Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  68. if (table.isLogicDelete()) {
  69. // 逻辑删除注入
  70. SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE;
  71. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlLogicSet(table),
  72. sqlWhereEntityWrapper(table));
  73. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  74. this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
  75. } else {
  76. // 正常删除
  77. super.injectDeleteSql(mapperClass, modelClass, table);
  78. }
  79. }
  80. /**
  81. * 根据 MAP 删除
  82. */
  83. @Override
  84. protected void injectDeleteByMapSql(Class<?> mapperClass, TableInfo table) {
  85. if (table.isLogicDelete()) {
  86. // 逻辑删除注入
  87. SqlMethod sqlMethod = SqlMethod.LOGIC_DELETE_BY_MAP;
  88. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlLogicSet(table),
  89. sqlWhereByMap(table));
  90. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Map.class);
  91. this.addUpdateMappedStatement(mapperClass, Map.class, sqlMethod.getMethod(), sqlSource);
  92. } else {
  93. // 正常删除
  94. super.injectDeleteByMapSql(mapperClass, table);
  95. }
  96. }
  97. /**
  98. * <p>
  99. * 注入查询 SQL 语句
  100. * </p>
  101. *
  102. * @param batch 是否为批量插入
  103. * @param mapperClass
  104. * @param modelClass
  105. * @param table
  106. */
  107. protected void injectSelectByIdSql(boolean batch, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  108. if (table.isLogicDelete()) {
  109. SqlMethod sqlMethod = SqlMethod.LOGIC_SELECT_BY_ID;
  110. SqlSource sqlSource;
  111. if (batch) {
  112. sqlMethod = SqlMethod.LOGIC_SELECT_BATCH_BY_IDS;
  113. StringBuilder ids = new StringBuilder();
  114. ids.append("\n<foreach item=\"item\" index=\"index\" collection=\"list\" separator=\",\">");
  115. ids.append("#{item}");
  116. ids.append("\n</foreach>");
  117. sqlSource = languageDriver.createSqlSource(configuration, String.format(sqlMethod.getSql(), sqlSelectColumns(table, false),
  118. table.getTableName(), table.getKeyColumn(), ids.toString(), getLogicDeleteSql(table)), modelClass);
  119. } else {
  120. sqlSource = new RawSqlSource(configuration, String.format(sqlMethod.getSql(), sqlSelectColumns(table, false), table.getTableName(),
  121. table.getKeyColumn(), table.getKeyProperty(), getLogicDeleteSql(table)), Object.class);
  122. }
  123. this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource, modelClass, table);
  124. } else {
  125. // 正常查询
  126. super.injectSelectByIdSql(batch, mapperClass, modelClass, table);
  127. }
  128. }
  129. /**
  130. * <p>
  131. * 注入更新 SQL 语句
  132. * </p>
  133. *
  134. * @param mapperClass
  135. * @param modelClass
  136. * @param table
  137. */
  138. protected void injectUpdateByIdSql(boolean selective, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  139. if (table.isLogicDelete()) {
  140. SqlMethod sqlMethod = selective ? SqlMethod.LOGIC_UPDATE_BY_ID : SqlMethod.LOGIC_UPDATE_ALL_COLUMN_BY_ID;
  141. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlSet(selective, table, "et."),
  142. table.getKeyColumn(),
  143. "et." + table.getKeyProperty(),
  144. "<if test=\"et instanceof java.util.Map\">" +
  145. "<if test=\"et.MP_OPTLOCK_VERSION_ORIGINAL!=null\">"
  146. + "and ${et.MP_OPTLOCK_VERSION_COLUMN}=#{et.MP_OPTLOCK_VERSION_ORIGINAL}"
  147. + "</if>"
  148. + "</if>" +
  149. getLogicDeleteSql(table)
  150. );
  151. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  152. this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
  153. } else {
  154. super.injectUpdateByIdSql(selective, mapperClass, modelClass, table);
  155. }
  156. }
  157. /**
  158. * <p>
  159. * SQL 更新 set 语句
  160. * </p>
  161. *
  162. * @param table 表信息
  163. * @return sql and 片段
  164. */
  165. public String getLogicDeleteSql(TableInfo table) {
  166. StringBuilder sql = new StringBuilder();
  167. List<TableFieldInfo> fieldList = table.getFieldList();
  168. for (TableFieldInfo fieldInfo : fieldList) {
  169. if (fieldInfo.isLogicDelete()) {
  170. sql.append(" AND ").append(fieldInfo.getColumn());
  171. if (StringUtils.isCharSequence(fieldInfo.getPropertyType())) {
  172. sql.append("='").append(fieldInfo.getLogicNotDeleteValue()).append("'");
  173. } else {
  174. sql.append("=").append(fieldInfo.getLogicNotDeleteValue());
  175. }
  176. }
  177. }
  178. return sql.toString();
  179. }
  180. /**
  181. * <p>
  182. * SQL 更新 set 语句
  183. * </p>
  184. *
  185. * @param table 表信息
  186. * @return sql set 片段
  187. */
  188. protected String sqlLogicSet(TableInfo table) {
  189. List<TableFieldInfo> fieldList = table.getFieldList();
  190. StringBuilder set = new StringBuilder("SET ");
  191. int i = 0;
  192. for (TableFieldInfo fieldInfo : fieldList) {
  193. if (fieldInfo.isLogicDelete()) {
  194. if (++i > 1) {
  195. set.append(",");
  196. }
  197. set.append(fieldInfo.getColumn()).append("=");
  198. if (StringUtils.isCharSequence(fieldInfo.getPropertyType())) {
  199. set.append("'").append(fieldInfo.getLogicDeleteValue()).append("'");
  200. } else {
  201. set.append(fieldInfo.getLogicDeleteValue());
  202. }
  203. }
  204. }
  205. return set.toString();
  206. }
  207. // ------------ 处理逻辑删除条件过滤 ------------
  208. @Override
  209. protected String sqlWhere(TableInfo table) {
  210. if (table.isLogicDelete()) {
  211. StringBuilder where = new StringBuilder("\n<where>");
  212. // 过滤逻辑
  213. List<TableFieldInfo> fieldList = table.getFieldList();
  214. // EW 逻辑
  215. if (StringUtils.isNotEmpty(table.getKeyProperty())) {
  216. where.append("\n<if test=\"ew.").append(table.getKeyProperty()).append("!=null\">");
  217. where.append(" AND ").append(table.getKeyColumn()).append("=#{ew.");
  218. where.append(table.getKeyProperty()).append("}");
  219. where.append("</if>");
  220. }
  221. for (TableFieldInfo fieldInfo : fieldList) {
  222. where.append(convertIfTag(fieldInfo, "ew.", false));
  223. where.append(" AND ").append(fieldInfo.getColumn()).append("=#{ew.");
  224. where.append(fieldInfo.getEl()).append("}");
  225. where.append(convertIfTag(fieldInfo, true));
  226. }
  227. // 过滤逻辑
  228. where.append("\n").append(getLogicDeleteSql(table));
  229. where.append("\n</where>");
  230. return where.toString();
  231. }
  232. // 正常逻辑
  233. return super.sqlWhere(table);
  234. }
  235. @Override
  236. protected String sqlWhereEntityWrapper(TableInfo table) {
  237. if (table.isLogicDelete()) {
  238. StringBuilder where = new StringBuilder(128);
  239. where.append("\n<where>");
  240. where.append("\n<if test=\"ew!=null\">");
  241. where.append("\n<if test=\"ew.entity!=null\">");
  242. if (StringUtils.isNotEmpty(table.getKeyProperty())) {
  243. where.append("\n<if test=\"ew.entity.").append(table.getKeyProperty()).append("!=null\">");
  244. where.append(" AND ").append(table.getKeyColumn()).append("=#{ew.entity.");
  245. where.append(table.getKeyProperty()).append("}");
  246. where.append("</if>");
  247. }
  248. List<TableFieldInfo> fieldList = table.getFieldList();
  249. for (TableFieldInfo fieldInfo : fieldList) {
  250. where.append(convertIfTag(fieldInfo, "ew.entity.", false));
  251. where.append(" AND ").append(fieldInfo.getColumn()).append("=#{ew.entity.");
  252. where.append(fieldInfo.getEl()).append("}");
  253. where.append(convertIfTag(fieldInfo, true));
  254. }
  255. where.append("\n</if>");
  256. where.append("\n").append(getLogicDeleteSql(table));
  257. where.append("\n<if test=\"ew.sqlSegment!=null\">${ew.sqlSegment}\n</if>");
  258. where.append("\n</if>");
  259. where.append("\n</where>");
  260. return where.toString();
  261. }
  262. // 正常逻辑
  263. return super.sqlWhereEntityWrapper(table);
  264. }
  265. @Override
  266. protected String sqlWhereByMap(TableInfo table) {
  267. if (table.isLogicDelete()) {
  268. StringBuilder where = new StringBuilder();
  269. where.append("\n<where>");
  270. // MAP 逻辑
  271. where.append("\n<if test=\"cm!=null and !cm.isEmpty\">");
  272. where.append("\n<foreach collection=\"cm.keys\" item=\"k\" separator=\"AND\">");
  273. where.append("\n<if test=\"cm[k] != null\">");
  274. where.append(SqlReservedWords.convert(getGlobalConfig(), "\n${k}")).append(" = #{cm[${k}]}");
  275. where.append("</if>");
  276. where.append("\n</foreach>");
  277. where.append("\n</if>");
  278. // 过滤逻辑
  279. where.append("\n").append(getLogicDeleteSql(table));
  280. where.append("\n</where>");
  281. return where.toString();
  282. }
  283. // 正常逻辑
  284. return super.sqlWhereByMap(table);
  285. }
  286. }