AutoSqlInjector.java 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790
  1. /**
  2. * Copyright (c) 2011-2014, hubin (jobob@qq.com).
  3. *
  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. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  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.lang.reflect.ParameterizedType;
  18. import java.lang.reflect.Type;
  19. import java.util.List;
  20. import java.util.Map;
  21. import java.util.Set;
  22. import java.util.logging.Logger;
  23. import org.apache.ibatis.builder.MapperBuilderAssistant;
  24. import org.apache.ibatis.executor.keygen.Jdbc3KeyGenerator;
  25. import org.apache.ibatis.executor.keygen.KeyGenerator;
  26. import org.apache.ibatis.executor.keygen.NoKeyGenerator;
  27. import org.apache.ibatis.mapping.MappedStatement;
  28. import org.apache.ibatis.mapping.SqlCommandType;
  29. import org.apache.ibatis.mapping.SqlSource;
  30. import org.apache.ibatis.mapping.StatementType;
  31. import org.apache.ibatis.scripting.LanguageDriver;
  32. import org.apache.ibatis.scripting.defaults.RawSqlSource;
  33. import org.apache.ibatis.session.Configuration;
  34. import com.baomidou.mybatisplus.MybatisConfiguration;
  35. import com.baomidou.mybatisplus.annotations.FieldStrategy;
  36. import com.baomidou.mybatisplus.annotations.IdType;
  37. import com.baomidou.mybatisplus.toolkit.TableFieldInfo;
  38. import com.baomidou.mybatisplus.toolkit.TableInfo;
  39. import com.baomidou.mybatisplus.toolkit.TableInfoHelper;
  40. /**
  41. * <p>
  42. * SQL 自动注入器
  43. * </p>
  44. *
  45. * @author hubin sjy
  46. * @Date 2016-09-09
  47. */
  48. public class AutoSqlInjector implements ISqlInjector {
  49. protected static final Logger logger = Logger.getLogger("AutoSqlInjector");
  50. protected Configuration configuration;
  51. protected LanguageDriver languageDriver;
  52. protected MapperBuilderAssistant builderAssistant;
  53. protected DBType dbType = DBType.MYSQL;
  54. /**
  55. * CRUD注入后给予标识 注入过后不再注入
  56. *
  57. * @param configuration
  58. * @param builderAssistant
  59. * @param mapperClass
  60. */
  61. public void inspectInject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
  62. String className = mapperClass.toString();
  63. Set<String> mapperRegistryCache = MybatisConfiguration.MAPPER_REGISTRY_CACHE;
  64. if (!mapperRegistryCache.contains(className)) {
  65. inject(configuration, builderAssistant, mapperClass);
  66. mapperRegistryCache.add(className);
  67. }
  68. }
  69. /**
  70. * 注入单点 crudSql
  71. */
  72. public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass) {
  73. this.configuration = configuration;
  74. this.builderAssistant = builderAssistant;
  75. this.languageDriver = configuration.getDefaultScriptingLanuageInstance();
  76. this.dbType = MybatisConfiguration.DB_TYPE;
  77. if (configuration.isMapUnderscoreToCamelCase()) {
  78. /* 开启驼峰配置 */
  79. MybatisConfiguration.DB_COLUMN_UNDERLINE = true;
  80. }
  81. Class<?> modelClass = extractModelClass(mapperClass);
  82. TableInfo table = TableInfoHelper.initTableInfo(modelClass);
  83. /**
  84. * 没有指定主键,默认方法不能使用
  85. */
  86. if (null != table && null != table.getKeyProperty()) {
  87. /* 插入 */
  88. this.injectInsertOneSql(false, mapperClass, modelClass, table);
  89. this.injectInsertOneSql(true, mapperClass, modelClass, table);
  90. this.injectInsertBatchSql(mapperClass, modelClass, table);
  91. /* 删除 */
  92. this.injectDeleteSelectiveSql(mapperClass, modelClass, table);
  93. this.injectDeleteByMapSql(mapperClass, table);
  94. this.injectDeleteSql(false, mapperClass, modelClass, table);
  95. this.injectDeleteSql(true, mapperClass, modelClass, table);
  96. /* 修改 */
  97. this.injectUpdateByIdSql(false, mapperClass, modelClass, table);
  98. this.injectUpdateByIdSql(true, mapperClass, modelClass, table);
  99. this.injectUpdateSql(false, mapperClass, modelClass, table);
  100. this.injectUpdateSql(true, mapperClass, modelClass, table);
  101. this.injectUpdateBatchById(mapperClass, modelClass, table);
  102. /* 查询 */
  103. this.injectSelectSql(false, mapperClass, modelClass, table);
  104. this.injectSelectSql(true, mapperClass, modelClass, table);
  105. this.injectSelectByMapSql(mapperClass, modelClass, table);
  106. this.injectSelectOneSql(mapperClass, modelClass, table);
  107. this.injectSelectCountSql(mapperClass, modelClass, table);
  108. this.injectSelectCountByEWSql(SqlMethod.SELECT_COUNT_EW, mapperClass, modelClass, table);
  109. this.injectSelectListSql(SqlMethod.SELECT_LIST, mapperClass, modelClass, table);
  110. this.injectSelectListSql(SqlMethod.SELECT_PAGE, mapperClass, modelClass, table);
  111. /* 自定义方法 */
  112. this.inject(configuration, builderAssistant, mapperClass, modelClass, table);
  113. } else {
  114. /**
  115. * 警告
  116. */
  117. logger.warning(String.format("%s ,Not found @TableId annotation, cannot use mybatis-plus curd method.",
  118. modelClass.toString()));
  119. }
  120. }
  121. /**
  122. * 自定义方法,注入点(子类需重写该方法)
  123. */
  124. public void inject(Configuration configuration, MapperBuilderAssistant builderAssistant, Class<?> mapperClass,
  125. Class<?> modelClass, TableInfo table) {
  126. // to do nothing
  127. }
  128. protected Class<?> extractModelClass(Class<?> mapperClass) {
  129. Type[] types = mapperClass.getGenericInterfaces();
  130. ParameterizedType target = null;
  131. for (Type type : types) {
  132. if (type instanceof ParameterizedType && BaseMapper.class.isAssignableFrom(mapperClass)) {
  133. target = (ParameterizedType) type;
  134. break;
  135. }
  136. }
  137. Type[] parameters = target.getActualTypeArguments();
  138. Class<?> modelClass = (Class<?>) parameters[0];
  139. return modelClass;
  140. }
  141. /**
  142. * <p>
  143. * 注入插入 SQL 语句
  144. * </p>
  145. *
  146. * @param selective
  147. * 是否选择插入
  148. * @param mapperClass
  149. * @param modelClass
  150. * @param table
  151. */
  152. protected void injectInsertOneSql(boolean selective, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  153. /*
  154. * INSERT INTO table <trim prefix="(" suffix=")" suffixOverrides=",">
  155. * <if test="xx != null">xx,</if> </trim> <trim prefix="values ("
  156. * suffix=")" suffixOverrides=","> <if test="xx != null">#{xx},</if>
  157. * </trim>
  158. */
  159. KeyGenerator keyGenerator = new NoKeyGenerator();
  160. StringBuilder fieldBuilder = new StringBuilder();
  161. StringBuilder placeholderBuilder = new StringBuilder();
  162. SqlMethod sqlMethod = SqlMethod.INSERT_ONE;
  163. if (selective) {
  164. sqlMethod = SqlMethod.INSERT_ONE_SELECTIVE;
  165. }
  166. fieldBuilder.append("\n<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">\n");
  167. placeholderBuilder.append("\n<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">\n");
  168. String keyProperty = null;
  169. String keyColumn = null;
  170. if (table.getIdType() == IdType.AUTO) {
  171. /* 自增主键 */
  172. keyGenerator = new Jdbc3KeyGenerator();
  173. keyProperty = table.getKeyProperty();
  174. keyColumn = table.getKeyColumn();
  175. } else {
  176. /* 用户输入自定义ID */
  177. fieldBuilder.append(table.getKeyColumn()).append(",");
  178. placeholderBuilder.append("#{").append(table.getKeyProperty()).append("},");
  179. }
  180. List<TableFieldInfo> fieldList = table.getFieldList();
  181. for (TableFieldInfo fieldInfo : fieldList) {
  182. if (selective) {
  183. fieldBuilder.append(convertIfTagInsert(fieldInfo, false));
  184. placeholderBuilder.append(convertIfTagInsert(fieldInfo, false));
  185. }
  186. fieldBuilder.append(fieldInfo.getColumn()).append(",");
  187. placeholderBuilder.append("#{").append(fieldInfo.getEl()).append("},");
  188. if (selective) {
  189. fieldBuilder.append(convertIfTagInsert(fieldInfo, true));
  190. placeholderBuilder.append(convertIfTagInsert(fieldInfo, true));
  191. }
  192. }
  193. fieldBuilder.append("\n</trim>");
  194. placeholderBuilder.append("\n</trim>");
  195. String sql = String.format(sqlMethod.getSql(), table.getTableName(), fieldBuilder.toString(),
  196. placeholderBuilder.toString());
  197. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  198. this.addInsertMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource, keyGenerator, keyProperty,
  199. keyColumn);
  200. }
  201. /**
  202. * <p>
  203. * 注入批量插入 SQL 语句
  204. * </p>
  205. *
  206. * @param mapperClass
  207. * @param modelClass
  208. * @param table
  209. */
  210. protected void injectInsertBatchSql(Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  211. KeyGenerator keyGenerator = new NoKeyGenerator();
  212. StringBuilder fieldBuilder = new StringBuilder();
  213. StringBuilder placeholderBuilder = new StringBuilder();
  214. SqlMethod sqlMethod = SqlMethod.INSERT_BATCH_MYSQL;
  215. if (DBType.ORACLE == dbType) {
  216. sqlMethod = SqlMethod.INSERT_BATCH_ORACLE;
  217. placeholderBuilder.append("\n<trim prefix=\"(SELECT \" suffix=\" FROM DUAL)\" suffixOverrides=\",\">\n");
  218. } else {
  219. placeholderBuilder.append("\n<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">\n");
  220. }
  221. fieldBuilder.append("\n<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">\n");
  222. String keyProperty = null;
  223. String keyColumn = null;
  224. if (table.getIdType() == IdType.AUTO) {
  225. /* 自增主键 */
  226. keyGenerator = new Jdbc3KeyGenerator();
  227. keyProperty = table.getKeyProperty();
  228. keyColumn = table.getKeyColumn();
  229. } else {
  230. /* 用户输入自定义ID */
  231. fieldBuilder.append(table.getKeyColumn()).append(",");
  232. placeholderBuilder.append("#{item.").append(table.getKeyProperty()).append("},");
  233. }
  234. List<TableFieldInfo> fieldList = table.getFieldList();
  235. for (TableFieldInfo fieldInfo : fieldList) {
  236. fieldBuilder.append(fieldInfo.getColumn()).append(",");
  237. placeholderBuilder.append("#{item.").append(fieldInfo.getEl()).append("},");
  238. }
  239. fieldBuilder.append("\n</trim>");
  240. placeholderBuilder.append("\n</trim>");
  241. String sql = String.format(sqlMethod.getSql(), table.getTableName(), fieldBuilder.toString(),
  242. placeholderBuilder.toString());
  243. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  244. this.addInsertMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource, keyGenerator, keyProperty,
  245. keyColumn);
  246. }
  247. /**
  248. * <p>
  249. * 注入 entity 条件删除 SQL 语句
  250. * </p>
  251. *
  252. * @param mapperClass
  253. * @param modelClass
  254. * @param table
  255. */
  256. protected void injectDeleteSelectiveSql(Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  257. SqlMethod sqlMethod = SqlMethod.DELETE_SELECTIVE;
  258. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlWhere(table, false));
  259. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  260. this.addDeleteMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource);
  261. }
  262. /**
  263. * <p>
  264. * 注入 map 条件删除 SQL 语句
  265. * </p>
  266. *
  267. * @param mapperClass
  268. * @param table
  269. */
  270. protected void injectDeleteByMapSql(Class<?> mapperClass, TableInfo table) {
  271. SqlMethod sqlMethod = SqlMethod.DELETE_BY_MAP;
  272. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlWhereByMap());
  273. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Map.class);
  274. this.addDeleteMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource);
  275. }
  276. /**
  277. * <p>
  278. * 注入删除 SQL 语句
  279. * </p>
  280. *
  281. * @param batch
  282. * 是否为批量插入
  283. * @param mapperClass
  284. * @param modelClass
  285. * @param table
  286. */
  287. protected void injectDeleteSql(boolean batch, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  288. SqlMethod sqlMethod = SqlMethod.DELETE_BY_ID;
  289. SqlSource sqlSource = null;
  290. if (batch) {
  291. sqlMethod = SqlMethod.DELETE_BATCH;
  292. StringBuilder ids = new StringBuilder();
  293. ids.append("\n<foreach item=\"item\" index=\"index\" collection=\"list\" separator=\",\">");
  294. ids.append("#{item}");
  295. ids.append("\n</foreach>");
  296. String sql = String.format(sqlMethod.getSql(), table.getTableName(), table.getKeyColumn(), ids.toString());
  297. sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  298. } else {
  299. String sql = String.format(sqlMethod.getSql(), table.getTableName(), table.getKeyColumn(), table.getKeyColumn());
  300. sqlSource = new RawSqlSource(configuration, sql, Object.class);
  301. }
  302. this.addDeleteMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource);
  303. }
  304. /**
  305. * <p>
  306. * 注入更新 SQL 语句
  307. * </p>
  308. *
  309. * @param selective
  310. * 是否选择更新
  311. * @param mapperClass
  312. * @param modelClass
  313. * @param table
  314. */
  315. protected void injectUpdateByIdSql(boolean selective, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  316. SqlMethod sqlMethod = SqlMethod.UPDATE_BY_ID;
  317. if (selective) {
  318. sqlMethod = SqlMethod.UPDATE_SELECTIVE_BY_ID;
  319. }
  320. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlSet(selective, table), table.getKeyColumn(),
  321. table.getKeyProperty());
  322. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  323. this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
  324. }
  325. /**
  326. * <p>
  327. * 注入批量更新 SQL 语句
  328. * </p>
  329. *
  330. * @param mapperClass
  331. * @param modelClass
  332. * @param table
  333. */
  334. protected void injectUpdateBatchById(Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  335. StringBuilder set = new StringBuilder();
  336. set.append("<trim prefix=\"SET\" suffixOverrides=\",\">\n");
  337. SqlMethod sqlMethod = SqlMethod.UPDATE_BATCH_BY_ID_MYSQL;
  338. if (DBType.ORACLE == dbType) {
  339. sqlMethod = SqlMethod.UPDATE_BATCH_BY_ID_ORACLE;
  340. List<TableFieldInfo> fieldList = table.getFieldList();
  341. for (TableFieldInfo fieldInfo : fieldList) {
  342. set.append(fieldInfo.getColumn()).append("=#{item.").append(fieldInfo.getEl()).append("},");
  343. }
  344. } else if (DBType.MYSQL == dbType) {
  345. List<TableFieldInfo> fieldList = table.getFieldList();
  346. for (TableFieldInfo fieldInfo : fieldList) {
  347. set.append("\n<trim prefix=\"").append(fieldInfo.getColumn()).append("=CASE ");
  348. set.append(table.getKeyColumn()).append("\" suffix=\"END,\">");
  349. set.append("\n<foreach collection=\"list\" item=\"i\" index=\"index\">");
  350. set.append(convertIfTag(fieldInfo, "i.", false));
  351. set.append("\nWHEN ").append("#{i.").append(table.getKeyProperty());
  352. set.append("} THEN #{i.").append(fieldInfo.getEl()).append("}");
  353. set.append(convertIfTag(fieldInfo, true));
  354. set.append("\n</foreach>");
  355. set.append("\n</trim>");
  356. }
  357. }
  358. set.append("\n</trim>");
  359. String sql = String.format(sqlMethod.getSql(), table.getTableName(), set.toString(), table.getKeyColumn(),
  360. table.getKeyProperty());
  361. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  362. this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
  363. }
  364. /**
  365. * <p>
  366. * 注入批量更新 SQL 语句
  367. * </p>
  368. *
  369. * @param selective
  370. * 是否选择更新
  371. * @param mapperClass
  372. * @param modelClass
  373. * @param table
  374. */
  375. protected void injectUpdateSql(boolean selective, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  376. SqlMethod sqlMethod = SqlMethod.UPDATE;
  377. if (selective) {
  378. sqlMethod = SqlMethod.UPDATE_SELECTIVE;
  379. }
  380. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlSet(selective, table), sqlWhere(table, true));
  381. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  382. this.addUpdateMappedStatement(mapperClass, modelClass, sqlMethod.getMethod(), sqlSource);
  383. }
  384. /**
  385. * <p>
  386. * 注入查询 SQL 语句
  387. * </p>
  388. *
  389. * @param batch
  390. * 是否为批量插入
  391. * @param mapperClass
  392. * @param modelClass
  393. * @param table
  394. */
  395. protected void injectSelectSql(boolean batch, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  396. SqlMethod sqlMethod = SqlMethod.SELECT_BY_ID;
  397. SqlSource sqlSource = null;
  398. if (batch) {
  399. sqlMethod = SqlMethod.SELECT_BATCH;
  400. StringBuilder ids = new StringBuilder();
  401. ids.append("\n<foreach item=\"item\" index=\"index\" collection=\"list\" separator=\",\">");
  402. ids.append("#{item}");
  403. ids.append("\n</foreach>");
  404. sqlSource = languageDriver.createSqlSource(configuration, String.format(sqlMethod.getSql(),
  405. sqlSelectColumns(table, false), table.getTableName(), table.getKeyColumn(), ids.toString()), modelClass);
  406. } else {
  407. sqlSource = new RawSqlSource(configuration, String.format(sqlMethod.getSql(), sqlSelectColumns(table, false),
  408. table.getTableName(), table.getKeyColumn(), table.getKeyProperty()), Object.class);
  409. }
  410. this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource, modelClass, table);
  411. }
  412. /**
  413. * <p>
  414. * 注入 map 查询 SQL 语句
  415. * </p>
  416. *
  417. * @param mapperClass
  418. * @param modelClass
  419. * @param table
  420. */
  421. protected void injectSelectByMapSql(Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  422. SqlMethod sqlMethod = SqlMethod.SELECT_BY_MAP;
  423. String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(table, false), table.getTableName(), sqlWhereByMap());
  424. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, Map.class);
  425. this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource, modelClass, table);
  426. }
  427. /**
  428. * <p>
  429. * 注入实体查询一条记录 SQL 语句
  430. * </p>
  431. *
  432. * @param mapperClass
  433. * @param modelClass
  434. * @param table
  435. */
  436. protected void injectSelectOneSql(Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  437. SqlMethod sqlMethod = SqlMethod.SELECT_ONE;
  438. String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(table, false), table.getTableName(),
  439. sqlWhere(table, false));
  440. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  441. this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource, modelClass, table);
  442. }
  443. /**
  444. * <p>
  445. * 注入实体查询总记录数 SQL 语句
  446. * </p>
  447. *
  448. * @param mapperClass
  449. * @param modelClass
  450. * @param table
  451. */
  452. protected void injectSelectCountSql(Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  453. SqlMethod sqlMethod = SqlMethod.SELECT_COUNT;
  454. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlWhere(table, true));
  455. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  456. this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource, Integer.class, null);
  457. }
  458. /**
  459. * <p>
  460. * 注入EntityWrapper方式查询记录列表 SQL 语句
  461. * </p>
  462. *
  463. * @param sqlMethod
  464. * @param mapperClass
  465. * @param modelClass
  466. * @param table
  467. */
  468. protected void injectSelectListSql(SqlMethod sqlMethod, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  469. String sql = String.format(sqlMethod.getSql(), sqlSelectColumns(table, true), table.getTableName(), sqlWhereEntityWrapper(table));
  470. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  471. this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource, modelClass, table);
  472. }
  473. /**
  474. * <p>
  475. * 注入EntityWrapper查询总记录数 SQL 语句
  476. * </p>
  477. *
  478. * @param sqlMethod
  479. * @param mapperClass
  480. * @param modelClass
  481. * @param table
  482. */
  483. protected void injectSelectCountByEWSql(SqlMethod sqlMethod, Class<?> mapperClass, Class<?> modelClass, TableInfo table) {
  484. String sql = String.format(sqlMethod.getSql(), table.getTableName(), sqlWhereEntityWrapper(table));
  485. SqlSource sqlSource = languageDriver.createSqlSource(configuration, sql, modelClass);
  486. this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource, Integer.class, null);
  487. }
  488. /**
  489. * <p>
  490. * EntityWrapper方式获取select where
  491. * </p>
  492. *
  493. * @param table
  494. * @return String
  495. */
  496. protected String sqlWhereEntityWrapper(TableInfo table) {
  497. StringBuilder where = new StringBuilder("\n<if test=\"ew!=null\">");
  498. where.append("\n<if test=\"ew.entity!=null\">\n<where>");
  499. where.append("\n<if test=\"ew.entity.").append(table.getKeyProperty()).append("!=null\">\n");
  500. where.append(table.getKeyColumn()).append("=#{ew.entity.").append(table.getKeyProperty()).append("}");
  501. where.append("\n</if>");
  502. List<TableFieldInfo> fieldList = table.getFieldList();
  503. for (TableFieldInfo fieldInfo : fieldList) {
  504. where.append(convertIfTag(fieldInfo, "ew.entity.", false));
  505. where.append(" AND ").append(fieldInfo.getColumn()).append("=#{ew.entity.").append(fieldInfo.getEl()).append("}");
  506. where.append(convertIfTag(fieldInfo, true));
  507. }
  508. where.append("\n</where>\n</if>");
  509. where.append("\n<if test=\"ew.sqlSegment!=null\">\n${ew.sqlSegment}\n</if>");
  510. where.append("\n</if>");
  511. return where.toString();
  512. }
  513. /**
  514. * <p>
  515. * SQL 更新 set 语句
  516. * </p>
  517. *
  518. * @param selective
  519. * 是否选择更新
  520. * @param table
  521. * @return
  522. */
  523. protected String sqlSet(boolean selective, TableInfo table) {
  524. StringBuilder set = new StringBuilder();
  525. set.append("<trim prefix=\"SET\" suffixOverrides=\",\">");
  526. List<TableFieldInfo> fieldList = table.getFieldList();
  527. for (TableFieldInfo fieldInfo : fieldList) {
  528. if (selective) {
  529. set.append(convertIfTag(fieldInfo, "et.", false));
  530. }
  531. set.append(fieldInfo.getColumn()).append("=#{et.").append(fieldInfo.getEl()).append("},");
  532. if (selective) {
  533. set.append(convertIfTag(fieldInfo, true));
  534. }
  535. }
  536. set.append("\n</trim>");
  537. return set.toString();
  538. }
  539. /**
  540. * <p>
  541. * SQL 查询所有表字段
  542. * </p>
  543. *
  544. * @param table
  545. * @param entityWrapper
  546. * 是否为包装类型查询
  547. * @return
  548. */
  549. protected String sqlSelectColumns(TableInfo table, boolean entityWrapper) {
  550. StringBuilder columns = new StringBuilder();
  551. if (null != table.getResultMap()) {
  552. /*
  553. * 存在 resultMap 映射返回
  554. */
  555. if (entityWrapper) {
  556. columns.append("<choose><when test=\"ew != null and ew.sqlSelect != null\">${ew.sqlSelect}</when><otherwise>");
  557. }
  558. columns.append("*");
  559. if (entityWrapper) {
  560. columns.append("</otherwise></choose>");
  561. }
  562. } else {
  563. /*
  564. * 普通查询
  565. */
  566. if (entityWrapper) {
  567. columns.append("<choose><when test=\"ew != null and ew.sqlSelect != null\">${ew.sqlSelect}</when><otherwise>");
  568. }
  569. if (table.isKeyRelated()) {
  570. columns.append(table.getKeyColumn()).append(" AS ").append(table.getKeyProperty());
  571. } else {
  572. columns.append(table.getKeyProperty());
  573. }
  574. List<TableFieldInfo> fieldList = table.getFieldList();
  575. for (TableFieldInfo fieldInfo : fieldList) {
  576. columns.append(",").append(fieldInfo.getColumn());
  577. if (fieldInfo.isRelated()) {
  578. columns.append(" AS ").append(fieldInfo.getProperty());
  579. }
  580. }
  581. if (entityWrapper) {
  582. columns.append("</otherwise></choose>");
  583. }
  584. }
  585. /*
  586. * 返回所有查询字段内容
  587. */
  588. return columns.toString();
  589. }
  590. /**
  591. * <p>
  592. * SQL 查询条件
  593. * </p>
  594. *
  595. * @param table
  596. * @param space
  597. * 是否为空判断
  598. * @return
  599. */
  600. protected String sqlWhere(TableInfo table, boolean space) {
  601. StringBuilder where = new StringBuilder();
  602. if (space) {
  603. where.append("\n<if test=\"ew!=null\">");
  604. }
  605. where.append("\n<where>");
  606. where.append("\n<if test=\"ew.").append(table.getKeyProperty()).append("!=null\">\n");
  607. where.append(table.getKeyColumn()).append("=#{ew.").append(table.getKeyProperty()).append("}");
  608. where.append("\n</if>");
  609. List<TableFieldInfo> fieldList = table.getFieldList();
  610. for (TableFieldInfo fieldInfo : fieldList) {
  611. where.append(convertIfTag(fieldInfo, "ew.", false));
  612. where.append(" AND ").append(fieldInfo.getColumn()).append("=#{ew.").append(fieldInfo.getEl()).append("}");
  613. where.append(convertIfTag(fieldInfo, true));
  614. }
  615. where.append("\n</where>");
  616. if (space) {
  617. where.append("\n</if>");
  618. }
  619. return where.toString();
  620. }
  621. /**
  622. * <p>
  623. * SQL map 查询条件
  624. * </p>
  625. */
  626. protected String sqlWhereByMap() {
  627. StringBuilder where = new StringBuilder();
  628. where.append("\n<foreach collection=\"cm.keys\" item=\"k\" separator=\"AND\"> ");
  629. where.append("\n${k}=#{cm[${k}]}");
  630. where.append("\n</foreach>");
  631. return where.toString();
  632. }
  633. /**
  634. * <p>
  635. * IF 条件转换方法
  636. * </p>
  637. *
  638. * @param sqlCommandType
  639. * SQL 操作类型
  640. * @param fieldInfo
  641. * 字段信息
  642. * @param prefix
  643. * 条件前缀
  644. * @param colse
  645. * 是否闭合标签
  646. * @return
  647. */
  648. protected String convertIfTag(SqlCommandType sqlCommandType, TableFieldInfo fieldInfo, String prefix,
  649. boolean colse) {
  650. /* 前缀处理 */
  651. String property = fieldInfo.getProperty();
  652. if (null != prefix) {
  653. property = prefix + property;
  654. }
  655. /* 判断策略 */
  656. if (sqlCommandType == SqlCommandType.INSERT && fieldInfo.getFieldStrategy() == FieldStrategy.FILL) {
  657. return "";
  658. }
  659. if (fieldInfo.getFieldStrategy() == FieldStrategy.IGNORED) {
  660. return "";
  661. } else if (fieldInfo.getFieldStrategy() == FieldStrategy.NOT_EMPTY) {
  662. if (colse) {
  663. return "</if>";
  664. } else {
  665. return String.format("\n\t<if test=\"%s!=null and %s!=''\">", property, property);
  666. }
  667. } else {
  668. //FieldStrategy.NOT_NULL
  669. if (colse) {
  670. return "</if>";
  671. } else {
  672. return String.format("\n\t<if test=\"%s!=null\">", property);
  673. }
  674. }
  675. }
  676. protected String convertIfTagInsert(TableFieldInfo fieldInfo, boolean colse) {
  677. return convertIfTag(SqlCommandType.INSERT, fieldInfo, null, colse);
  678. }
  679. protected String convertIfTag(TableFieldInfo fieldInfo, String prefix, boolean colse) {
  680. return convertIfTag(SqlCommandType.UNKNOWN, fieldInfo, prefix, colse);
  681. }
  682. protected String convertIfTag(TableFieldInfo fieldInfo, boolean colse) {
  683. return convertIfTag(fieldInfo, null, colse);
  684. }
  685. /*
  686. * 查询
  687. */
  688. public MappedStatement addSelectMappedStatement(Class<?> mapperClass, String id, SqlSource sqlSource, Class<?> resultType,
  689. TableInfo table) {
  690. if (null != table) {
  691. String resultMap = table.getResultMap();
  692. if (null != resultMap) {
  693. /* 返回 resultMap 映射结果集 */
  694. return this.addMappedStatement(mapperClass, id, sqlSource, SqlCommandType.SELECT, null, resultMap, null,
  695. new NoKeyGenerator(), null, null);
  696. }
  697. }
  698. /* 普通查询 */
  699. return this.addMappedStatement(mapperClass, id, sqlSource, SqlCommandType.SELECT, null, null, resultType,
  700. new NoKeyGenerator(), null, null);
  701. }
  702. /*
  703. * 插入
  704. */
  705. public MappedStatement addInsertMappedStatement(Class<?> mapperClass, Class<?> modelClass, String id, SqlSource sqlSource,
  706. KeyGenerator keyGenerator, String keyProperty, String keyColumn) {
  707. return this.addMappedStatement(mapperClass, id, sqlSource, SqlCommandType.INSERT, modelClass, null, Integer.class,
  708. keyGenerator, keyProperty, keyColumn);
  709. }
  710. /*
  711. * 删除
  712. */
  713. public MappedStatement addDeleteMappedStatement(Class<?> mapperClass, String id, SqlSource sqlSource) {
  714. return this.addMappedStatement(mapperClass, id, sqlSource, SqlCommandType.DELETE, null, null, Integer.class,
  715. new NoKeyGenerator(), null, null);
  716. }
  717. /*
  718. * 更新
  719. */
  720. public MappedStatement addUpdateMappedStatement(Class<?> mapperClass, Class<?> modelClass, String id, SqlSource sqlSource) {
  721. return this.addMappedStatement(mapperClass, id, sqlSource, SqlCommandType.UPDATE, modelClass, null, Integer.class,
  722. new NoKeyGenerator(), null, null);
  723. }
  724. public MappedStatement addMappedStatement(Class<?> mapperClass, String id, SqlSource sqlSource,
  725. SqlCommandType sqlCommandType, Class<?> parameterClass, String resultMap, Class<?> resultType,
  726. KeyGenerator keyGenerator, String keyProperty, String keyColumn) {
  727. String statementName = mapperClass.getName() + "." + id;
  728. if (configuration.hasStatement(statementName)) {
  729. System.err.println("{" + statementName
  730. + "} Has been loaded by XML or SqlProvider, ignoring the injection of the SQL.");
  731. return null;
  732. }
  733. /* 缓存逻辑处理 */
  734. boolean isSelect = false;
  735. if (sqlCommandType == SqlCommandType.SELECT) {
  736. isSelect = true;
  737. }
  738. return builderAssistant.addMappedStatement(id, sqlSource, StatementType.PREPARED, sqlCommandType, null, null, null,
  739. parameterClass, resultMap, resultType, null, !isSelect, isSelect, false, keyGenerator, keyProperty, keyColumn,
  740. configuration.getDatabaseId(), languageDriver, null);
  741. }
  742. }