PrepSqlDTO.java 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. package jnpf.database.model.dto;
  2. import jnpf.database.model.entity.DbLinkEntity;
  3. import jnpf.database.util.ConnUtil;
  4. import jnpf.database.util.DataSourceUtil;
  5. import jnpf.database.util.DynamicDataSourceUtil;
  6. import jnpf.exception.DataException;
  7. import jnpf.util.XSSEscape;
  8. import jnpf.util.context.SpringContext;
  9. import lombok.Data;
  10. import lombok.NoArgsConstructor;
  11. import lombok.experimental.Accessors;
  12. import javax.sql.DataSource;
  13. import java.sql.Connection;
  14. import java.sql.SQLException;
  15. import java.util.*;
  16. import java.util.function.Function;
  17. /**
  18. * Dynamic SQL参数传输对象
  19. *
  20. * @author JNPF开发平台组 GuanMengYu,YanYu
  21. * @version V3.2.0
  22. * @copyright 引迈信息技术有限公司
  23. * @date 2021/6/21
  24. */
  25. @Data
  26. @NoArgsConstructor
  27. @Accessors(chain = true)
  28. public class PrepSqlDTO {
  29. private static DataSource getDataSource(){
  30. return SpringContext.getBean(DataSource.class);
  31. }
  32. /**
  33. * 数据连接方法接口函数
  34. */
  35. public static Function<String, DbLinkEntity> DB_LINK_FUN;
  36. /**
  37. * conn连接
  38. */
  39. // @Getter(value = AccessLevel.NONE)
  40. // @Setter(value = AccessLevel.NONE)
  41. // private Connection connection;
  42. private DbLinkEntity dbLinkEntity;
  43. private Connection preConnection;
  44. /**
  45. * 执行的sql语句用占位符代替
  46. * 注意:一个对象只对应一条SQL
  47. */
  48. private String sql;
  49. /**
  50. * sql对应占位符的值
  51. */
  52. private List<?> dataList = new ArrayList<>();
  53. /**
  54. * 批量参数
  55. */
  56. private List<List<?>> multiDataList = new ArrayList<>();
  57. /**
  58. * SQL命令类型
  59. */
  60. private String sqlCommandType;
  61. public final static String INSERT = "insert";
  62. public final static String DELETE = "delete";
  63. public final static String UPDATE = "update";
  64. public final static String SELECT = "select";
  65. public final static String CRE_UP_DE = "creUpDe";
  66. /**
  67. * 获取切源后的数据源连接, 并清除自动切源记录
  68. * @param dbLinkEntity
  69. * @return
  70. * @throws DataException
  71. */
  72. public static Connection getConn(DbLinkEntity dbLinkEntity) throws DataException {
  73. try{
  74. return new PrepSqlDTO().withConn(dbLinkEntity).switchConn().getConnection();
  75. }catch (SQLException d){
  76. d.printStackTrace();
  77. throw new DataException(d.getMessage());
  78. }
  79. }
  80. /**
  81. * 获取切源后的数据源连接, 并清除自动切源记录
  82. * @return
  83. * @throws SQLException
  84. */
  85. private Connection getConnection() throws SQLException {
  86. try {
  87. Connection conn = DynamicDataSourceUtil.getCurrentConnection();
  88. ConnUtil.switchConnectionSchema(conn);
  89. return conn;
  90. } finally{
  91. DynamicDataSourceUtil.clearSwitchDataSource();
  92. }
  93. }
  94. /**
  95. * 该方法会自动将数据源切换至配置的目标源
  96. * 调用完后若没有使用获取Connection方法需要手动调用 DynamicDataSourceUtil.clearSwitchDataSource()清除切源记录
  97. *
  98. * @return
  99. * @throws SQLException
  100. * @throws DataException
  101. */
  102. public PrepSqlDTO switchConn() throws SQLException, DataException {
  103. if(preConnection == null){
  104. if (this.dbLinkEntity != null) {
  105. if (this.dbLinkEntity.getId() != null && !"0".equals(this.dbLinkEntity.getId())) {
  106. // 增加并切换数据源
  107. DynamicDataSourceUtil.switchToDataSource(dbLinkEntity);
  108. } else {
  109. if (dbLinkEntity.getUrl() != null) {
  110. DynamicDataSourceUtil.switchToDataSource(dbLinkEntity.getUserName(), dbLinkEntity.getPassword(), dbLinkEntity.getUrl(), dbLinkEntity.getDbType());
  111. } else {
  112. //切换只主库
  113. DynamicDataSourceUtil.switchToDataSource(null);
  114. }
  115. }
  116. } else {
  117. throw new SQLException("dbLinkEntity数据库连接对象不能为空");
  118. }
  119. }
  120. return this;
  121. }
  122. /* =============================== 构造方法 ============================== */
  123. /**
  124. * 无参数SQL语句
  125. */
  126. public PrepSqlDTO(String sql){
  127. this.sql = sql;
  128. }
  129. /**
  130. * 快捷有参SQL语句
  131. */
  132. public PrepSqlDTO(String sql, Object ...objs){
  133. this.sql = sql;
  134. this.dataList = Arrays.asList(objs);
  135. }
  136. /**
  137. * 有参SQL语句
  138. */
  139. public PrepSqlDTO(String sql, List<?> prepareDataList){
  140. this.sql = sql;
  141. this.dataList = prepareDataList;
  142. }
  143. // public PrepSqlDTO withConn(Connection conn){
  144. // this.connection = conn;
  145. // return this;
  146. // }
  147. public PrepSqlDTO withConn(String dbLinkId){
  148. this.dbLinkEntity = DB_LINK_FUN.apply(dbLinkId);
  149. return this;
  150. }
  151. public PrepSqlDTO withConn(DbLinkEntity dbLinkEntity){
  152. this.dbLinkEntity = dbLinkEntity;
  153. return this;
  154. }
  155. public PrepSqlDTO withConn(DataSourceUtil dataSourceUtil, String dbName){
  156. this.dbLinkEntity = dataSourceUtil.init(dbName);
  157. return this;
  158. }
  159. public PrepSqlDTO withConn(String user, String password, String url){
  160. this.dbLinkEntity = new DbLinkEntity();
  161. dbLinkEntity.setUserName(user);
  162. dbLinkEntity.setPassword(password);
  163. dbLinkEntity.setUrl(url);
  164. return this;
  165. }
  166. public PrepSqlDTO withConn(Connection conn){
  167. preConnection = conn;
  168. return this;
  169. }
  170. /* =================== 同一条语句,多个组参数 ======================== */
  171. public void addMultiData(List<?> prepareDataList){
  172. this.multiDataList.add(prepareDataList);
  173. }
  174. public void addMultiData(Object ...objs){
  175. this.multiDataList.add(Arrays.asList(objs));
  176. }
  177. public Map<String, Object> getMapParams() {
  178. String sql = XSSEscape.escapeEmpty(this.sql);
  179. int index = 0;
  180. while (sql.contains("?") && index <= this.dataList.size()){
  181. sql = sql.replaceFirst("\\?", "\\#{param_" + index + "}");
  182. index++;
  183. }
  184. Map<String, Object> params = new HashMap<>();
  185. params.put("sql", sql);
  186. for (int i = 0 ; i < this.dataList.size() ; i++) {
  187. Object dataObject = this.dataList.get(i);
  188. params.put("param_" + i, dataObject);
  189. }
  190. return params;
  191. }
  192. }