JdbcUtil.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. package jnpf.database.util;
  2. import jnpf.base.Pagination;
  3. import jnpf.constant.MsgCode;
  4. import jnpf.database.enums.DbAliasEnum;
  5. import jnpf.database.model.dbfield.JdbcColumnModel;
  6. import jnpf.database.model.dto.JdbcResult;
  7. import jnpf.database.model.dto.ModelDTO;
  8. import jnpf.database.model.dto.PrepSqlDTO;
  9. import jnpf.database.model.interfaces.JdbcCreUpDel;
  10. import jnpf.database.model.interfaces.JdbcGetMod;
  11. import jnpf.database.model.page.JdbcPageMod;
  12. import jnpf.database.sql.util.SqlFastUtil;
  13. import jnpf.exception.DataException;
  14. import jnpf.util.XSSEscape;
  15. import jnpf.util.context.SpringContext;
  16. import lombok.Cleanup;
  17. import lombok.extern.slf4j.Slf4j;
  18. import org.apache.ibatis.session.ResultHandler;
  19. import org.apache.ibatis.session.SqlSession;
  20. import org.apache.ibatis.session.SqlSessionFactory;
  21. import java.sql.*;
  22. import java.util.ArrayList;
  23. import java.util.HashMap;
  24. import java.util.List;
  25. import java.util.Map;
  26. /**
  27. * JDBC Dynamic
  28. *
  29. * @author JNPF开发平台组 YanYu
  30. * @version V3.4.3
  31. * @copyright 引迈信息技术有限公司
  32. * @date 2022/10/10
  33. */
  34. @Slf4j
  35. public class JdbcUtil {
  36. private final static String SELECT_MAPPER = "jnpf.database.mapper.JdbcMapper.getListSql";
  37. private final static String UPDATE_MAPPER = "jnpf.database.mapper.JdbcMapper.updateSql";
  38. private final static String UPDATE_MAPPERS = "jnpf.database.mapper.JdbcMapper.updatesSql";
  39. private final static String DELETE_MAPPER = "jnpf.database.mapper.JdbcMapper.deleteSql";
  40. private final static String INSERT_MAPPER = "jnpf.database.mapper.JdbcMapper.insertSql";
  41. private static SqlSessionFactory getSqlSessionFactory(){
  42. return SpringContext.getBean(SqlSessionFactory.class);
  43. }
  44. /**
  45. * 批量执行一条SQL语句(适合增、删、改)
  46. * CRUD:增加(Create)、检索(Retrieve)、更新(Update)、删除(Delete)
  47. * @return 返回值:i>0 成功条数,i=0 执行失败
  48. */
  49. public static int creUpDe(PrepSqlDTO dto) throws Exception {
  50. dto.switchConn();
  51. try{
  52. @Cleanup SqlSession sqlSession = getSqlSessionFactory().openSession();
  53. return sqlSession.update(UPDATE_MAPPER, dto.getMapParams());
  54. }finally{
  55. DynamicDataSourceUtil.clearSwitchDataSource();
  56. }
  57. }
  58. /**
  59. * update更新语句
  60. */
  61. public static int update(PrepSqlDTO dto) throws Exception {
  62. dto.switchConn();
  63. try{
  64. @Cleanup SqlSession sqlSession = getSqlSessionFactory().openSession();
  65. return sqlSession.update(UPDATE_MAPPERS, dto.getMapParams());
  66. }finally{
  67. DynamicDataSourceUtil.clearSwitchDataSource();
  68. }
  69. }
  70. public static int delete(PrepSqlDTO dto) throws Exception {
  71. dto.switchConn();
  72. try{
  73. @Cleanup SqlSession sqlSession = getSqlSessionFactory().openSession();
  74. return sqlSession.update(DELETE_MAPPER, dto.getMapParams());
  75. }finally{
  76. DynamicDataSourceUtil.clearSwitchDataSource();
  77. }
  78. }
  79. public static int insert(PrepSqlDTO dto) throws Exception {
  80. dto.switchConn();
  81. try{
  82. @Cleanup SqlSession sqlSession = getSqlSessionFactory().openSession();
  83. return sqlSession.update(INSERT_MAPPER, dto.getMapParams());
  84. }finally{
  85. DynamicDataSourceUtil.clearSwitchDataSource();
  86. }
  87. }
  88. /**
  89. * 同一条语句批量执行
  90. * 同数据源
  91. * @param dto SQL语句参数对象
  92. * @return 执行结果
  93. * @throws SQLException ignore
  94. */
  95. public static int[] creUpDeBatchOneSql(PrepSqlDTO dto) throws Exception {
  96. @Cleanup Connection conn = ConnUtil.getConnOrDefault(dto.getDbLinkEntity());
  97. return JdbcCreUpDel.get(conn, () -> {
  98. @Cleanup PreparedStatement statement = conn.prepareStatement(dto.getSql());
  99. for(List<?> data : dto.getMultiDataList()){
  100. JdbcCreUpDel.setData(statement, data);
  101. statement.addBatch();
  102. }
  103. return statement.executeBatch();
  104. });
  105. }
  106. /*========================query查询语句==============================*/
  107. /*============ 模式一:MapList ============*/
  108. /**
  109. * 通用:单字段多条查询
  110. */
  111. public static JdbcResult<List<Map<String, Object>>> queryList(PrepSqlDTO dto) throws Exception {
  112. return new JdbcResult<>((jdbcResult)-> JdbcUtil.getMybatisModel0(dto, jdbcResult.getIsLowerCase(), jdbcResult.getIsAlias()));
  113. }
  114. /**
  115. * 通用:单字段单条查询
  116. */
  117. public static Map<String, Object> queryOne(PrepSqlDTO dto) throws Exception {
  118. List<Map<String, Object>> mapList = queryList(dto).get();
  119. return mapList.size() > 0 ? mapList.get(0) : new HashMap<>();
  120. }
  121. /**
  122. * 查单条Int类型返回值
  123. */
  124. public static Integer queryOneInt(PrepSqlDTO dto, String keyWord) throws Exception {
  125. Map<String, Object> map = queryOne(dto);
  126. if (map != null && map.size() > 0) {
  127. for (Map.Entry<String, Object> mapEntity : map.entrySet()) {
  128. if(mapEntity.getKey().equalsIgnoreCase(keyWord)){
  129. return Integer.parseInt(String.valueOf(mapEntity.getValue()));
  130. }
  131. }
  132. }
  133. throw new DataException(MsgCode.FA020.get());
  134. }
  135. public static JdbcResult<JdbcPageMod> queryPage(PrepSqlDTO dto, String sortType, Integer currentPage, Integer pageSize) throws Exception {
  136. final String finalSortType = sortType;
  137. return new JdbcResult<>((jdbcResult)-> {
  138. String sortTypeStr = finalSortType;
  139. String orderSign = null;
  140. String dbEncode = dto.getDbLinkEntity().getDbType();
  141. String[] split = sortTypeStr.split(",");
  142. if (split.length > 1) {
  143. sortTypeStr = split[0];
  144. orderSign = split[1];
  145. }
  146. String selectSql = "";
  147. JdbcPageMod pageModel = new JdbcPageMod();
  148. try {
  149. String[] sqlArray = SqlFastUtil.getPageSql(dbEncode, dto.getSql(), sortTypeStr, orderSign, currentPage, pageSize);
  150. selectSql = sqlArray[0];
  151. //方便测试打印到控制台
  152. System.out.println("列表sql语句为:" + selectSql);
  153. dto.setSql(selectSql);
  154. List<?> resultData = getMybatisModel0(dto, jdbcResult.getIsLowerCase(), jdbcResult.getIsAlias());
  155. pageModel.setDataList(resultData);
  156. selectSql = sqlArray[1];
  157. dto.setSql(selectSql);
  158. pageModel.setTotalRecord(queryOneInt(dto, DbAliasEnum.TOTAL_RECORD.getAlias(dbEncode)));
  159. pageModel.setCurrentPage(currentPage);
  160. pageModel.setPageSize(pageSize);
  161. } catch (Exception e) {
  162. log.error("在线列表sql语句错误:" + selectSql);
  163. throw new DataException(MsgCode.DB017.get(selectSql));
  164. }
  165. return pageModel;
  166. });
  167. }
  168. public static <T extends JdbcGetMod>JdbcResult<Pagination> queryModelPage(PrepSqlDTO dto, Pagination pagination, Class<T> modType) throws Exception {
  169. return new JdbcResult<>((jdbcResult)-> {
  170. String dbEncode = dto.getDbLinkEntity().getDbType();
  171. String[] sqlArray = SqlFastUtil.getPageSql(dbEncode, dto.getSql(), pagination);
  172. pagination.setData(
  173. getMybatisModel2(dto.setSql(sqlArray[0]), modType),
  174. queryOneInt(dto.setSql(sqlArray[1]), DbAliasEnum.TOTAL_RECORD.getAlias(dbEncode)));
  175. return pagination;
  176. });
  177. }
  178. /*============ 模式二:JdbcColumnModel ============*/
  179. /**
  180. * 专用:查询模板
  181. * 说明:DbJdbcModel对象,为通用的数据返回对象,每条信息不同字段对应的数据,包含此相应字段的信息
  182. */
  183. public static JdbcResult<List<List<JdbcColumnModel>>> queryJdbcColumns(PrepSqlDTO dto) throws Exception {
  184. return new JdbcResult<>((jdbcResult)-> getMybatisModel1(dto, jdbcResult.getIsLowerCase(), jdbcResult.getIsValue()));
  185. }
  186. /*============ 模式三:JdbcColumnModel ============*/
  187. /**
  188. * 自定义模板查询
  189. */
  190. public static <T extends JdbcGetMod> List<T> queryCustomMods(PrepSqlDTO dto, Class<T> modType) throws Exception {
  191. return getMybatisModel2(dto, modType);
  192. }
  193. /*=========================== 基础方法 ==========================*/
  194. /**
  195. * 模式一:
  196. * ResultSet转Map
  197. *
  198. * @return 结果集的Map集合
  199. */
  200. public static List<Map<String, Object>> getMybatisModel0(PrepSqlDTO dto, Boolean isLowercase, Boolean isAlias) throws Exception {
  201. dto.switchConn();
  202. try {
  203. List<Map<String, Object>> mapMods = new ArrayList<>();
  204. ResultHandler<?> handler = (handle) -> {
  205. try {
  206. ResultSet rs = ResetSetHolder.getResultSet();
  207. ResultSetMetaData md = rs.getMetaData();
  208. Map<String, Object> map = new HashMap<>();
  209. //获取字段集合信息
  210. int columnCount = md.getColumnCount();
  211. for (int i = 1; i <= columnCount; i++) {
  212. String fieldName = isAlias ? md.getColumnLabel(i) : md.getColumnName(i);
  213. fieldName = isLowercase ? fieldName.toLowerCase() : fieldName;
  214. map.put(fieldName, XSSEscape.escapeObj(rs.getObject(i)));
  215. }
  216. mapMods.add(map);
  217. } catch (Exception e) {
  218. e.printStackTrace();
  219. }
  220. };
  221. @Cleanup SqlSession sqlSession = getSqlSessionFactory().openSession();
  222. sqlSession.select(SELECT_MAPPER, dto.getMapParams(), handler);
  223. return mapMods;
  224. }finally {
  225. DynamicDataSourceUtil.clearSwitchDataSource();
  226. }
  227. }
  228. /**
  229. * 模式二:
  230. * 内置基础结果对象 (包含类型)
  231. *
  232. * @return 包含字段信息的结果集对象
  233. */
  234. public static List<List<JdbcColumnModel>> getMybatisModel1(PrepSqlDTO dto, Boolean isLowercase, Boolean isValue) throws Exception {
  235. dto.switchConn();
  236. try {
  237. List<List<JdbcColumnModel>> includeFieldMods = new ArrayList<>();
  238. ResultHandler<?> handler = (handle) -> {
  239. try {
  240. ResultSet rs = ResetSetHolder.getResultSet();
  241. do{
  242. includeFieldMods.add(JdbcColumnModel.getList(rs, isLowercase, isValue));
  243. }while (rs.next());
  244. } catch (Exception e) {
  245. e.printStackTrace();
  246. }
  247. };
  248. @Cleanup SqlSession sqlSession = getSqlSessionFactory().openSession();
  249. sqlSession.select(SELECT_MAPPER, dto.getMapParams(), handler);
  250. return includeFieldMods;
  251. }finally {
  252. DynamicDataSourceUtil.clearSwitchDataSource();
  253. }
  254. }
  255. /**
  256. * 模式三:
  257. * 获取自定义对象模型集合
  258. *
  259. * @param <T> 自定义对象模型类型
  260. * @return 自定义对象集合
  261. * @throws SQLException ignore
  262. */
  263. public static <T extends JdbcGetMod> List<T> getMybatisModel2(PrepSqlDTO dto, Class<T> modType) throws Exception {
  264. dto.switchConn();
  265. try {
  266. List<T> customMods = new ArrayList<>();
  267. String dbEncode = dto.getDbLinkEntity().getDbType();
  268. ResultHandler<?> handler = (handle) -> {
  269. try {
  270. T t = modType.newInstance();
  271. t.setMod(new ModelDTO(ResetSetHolder.getResultSet(), dbEncode));
  272. t = XSSEscape.escapeObj(t);
  273. customMods.add(t);
  274. } catch (Exception e) {
  275. e.printStackTrace();
  276. }
  277. };
  278. @Cleanup SqlSession sqlSession = getSqlSessionFactory().openSession();
  279. sqlSession.select(SELECT_MAPPER, dto.getMapParams(), handler);
  280. //返回值:自定义jdbc模型对象
  281. return customMods;
  282. }finally{
  283. DynamicDataSourceUtil.clearSwitchDataSource();
  284. }
  285. }
  286. }