JdbcTableModel.java 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255
  1. package jnpf.database.model.dbtable;
  2. import jnpf.constant.MsgCode;
  3. import jnpf.constant.TableFieldsNameConst;
  4. import jnpf.database.constant.RsColumnKeyConst;
  5. import jnpf.database.constant.RsTableKeyConst;
  6. import jnpf.database.model.dbfield.DbFieldModel;
  7. import jnpf.database.model.dbfield.JdbcColumnModel;
  8. import jnpf.database.model.entity.DbLinkEntity;
  9. import jnpf.database.model.interfaces.DbSourceOrDbLink;
  10. import jnpf.database.util.ConnUtil;
  11. import jnpf.exception.DataException;
  12. import lombok.Cleanup;
  13. import io.swagger.v3.oas.annotations.media.Schema;
  14. import lombok.Data;
  15. import lombok.NoArgsConstructor;
  16. import java.sql.Connection;
  17. import java.sql.ResultSet;
  18. import java.sql.SQLException;
  19. import java.util.ArrayList;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.stream.Collectors;
  24. /**
  25. * JDBC元数据字段模型类型
  26. *
  27. * @author JNPF开发平台组
  28. * @version V3.2.0
  29. * @copyright 引迈信息技术有限公司
  30. * @date 2021/10/21
  31. */
  32. @Data
  33. @NoArgsConstructor
  34. public class JdbcTableModel {
  35. /**
  36. * 数据库类型
  37. */
  38. private String dbEncode;
  39. /**
  40. * 表名
  41. */
  42. private String table;
  43. /**
  44. * 表类型
  45. */
  46. private String tableType;
  47. /**
  48. * 表注释
  49. */
  50. private String comment;
  51. /**
  52. * 主键字段
  53. */
  54. private String primaryField;
  55. /**
  56. * 主键字段列表
  57. */
  58. private List<String> primaryFields;
  59. /**
  60. * jdbc字段集合
  61. */
  62. private List<JdbcColumnModel> jdbcColumnModelList;
  63. /* ================== 构造方法 ================= */
  64. public JdbcTableModel(DbLinkEntity dbLinkEntity, String table) throws Exception {
  65. // @Cleanup Connection conn = PrepSqlDTO.getConn(dbLinkEntity);
  66. @Cleanup Connection conn = ConnUtil.ConnCommon.getConnRemarks(dbLinkEntity);
  67. @Cleanup ResultSet rs = getTableMetaDateRs(conn, table);
  68. List<String> primaryKeys = getPrimaryKeys(conn, table).stream().sorted((o1, o2) -> {
  69. return (TableFieldsNameConst.F_ID.equalsIgnoreCase(o2) || TableFieldsNameConst.ID.equalsIgnoreCase(o2)) ? 1 : 0;
  70. }).collect(Collectors.toList());
  71. if (rs.next()) {
  72. this.dbEncode = dbLinkEntity.getDbType();
  73. this.table = rs.getString(RsTableKeyConst.TABLE_NAME);
  74. this.tableType = rs.getString(RsTableKeyConst.TABLE_TYPE);
  75. this.comment = rs.getString(RsTableKeyConst.REMARKS);
  76. this.primaryField = primaryKeys.isEmpty() ? null : primaryKeys.get(0);
  77. this.primaryFields = primaryKeys;
  78. this.jdbcColumnModelList = JdbcColumnModel.getList(conn, table, primaryFields);
  79. }else {
  80. throw new DataException(MsgCode.DB009.get(table));
  81. }
  82. }
  83. /* ================== 内部方法 ================= */
  84. public DbTableFieldModel convertDbTableFieldModel() throws Exception {
  85. // 转换表
  86. DbTableFieldModel dbTableFieldModel = new DbTableFieldModel();
  87. dbTableFieldModel.setTable(this.table);
  88. dbTableFieldModel.setComment(this.comment);
  89. // 转换字段集合
  90. List<DbFieldModel> dbFieldModelList = new ArrayList<>();
  91. for (JdbcColumnModel jdbcColumnModel : this.jdbcColumnModelList) {
  92. dbFieldModelList.add(jdbcColumnModel.convertDbFieldModel(this.dbEncode));
  93. }
  94. dbTableFieldModel.setDbFieldModelList(dbFieldModelList);
  95. return dbTableFieldModel;
  96. }
  97. /* ================== 静态方法 ================= */
  98. /**
  99. * 获取表元数据对象(所有表)
  100. * @param conn 数据连接
  101. * @return ignore
  102. * @throws SQLException ignore
  103. */
  104. public static List<JdbcTableModel> getList(Connection conn) throws Exception {
  105. @Cleanup ResultSet rs = getTableMetaDateRs(conn);
  106. List<JdbcTableModel> list = new ArrayList<>();
  107. while (rs.next()) {
  108. JdbcTableModel jdbcTableModel = new JdbcTableModel();
  109. jdbcTableModel.setTable(rs.getString(RsTableKeyConst.TABLE_NAME));
  110. jdbcTableModel.setTableType(rs.getString(RsTableKeyConst.TABLE_TYPE));
  111. jdbcTableModel.setComment(rs.getString(RsTableKeyConst.REMARKS));
  112. jdbcTableModel.setJdbcColumnModelList(JdbcColumnModel.getList(conn, jdbcTableModel.getTable(), jdbcTableModel.getPrimaryFields()));
  113. list.add(jdbcTableModel);
  114. }
  115. return list;
  116. }
  117. public static String getPrimary(DbSourceOrDbLink dbSourceOrDbLink, String table) throws SQLException {
  118. @Cleanup Connection conn = ConnUtil.getConnOrDefault(dbSourceOrDbLink);
  119. return getPrimary(conn, table);
  120. }
  121. /**
  122. * 获取第一个主键, 排除某些主键
  123. */
  124. public static String getPrimaryExculde(Connection conn, String table, String... excludeField) throws SQLException {
  125. List<String> primaryKeys = getPrimaryKeys(conn, table);
  126. if(!primaryKeys.isEmpty()){
  127. for (String primaryKey : primaryKeys) {
  128. boolean exlude = false;
  129. for (String exclude : excludeField) {
  130. if(primaryKey.equalsIgnoreCase(exclude)){
  131. exlude = true;
  132. break;
  133. }
  134. }
  135. if(!exlude){
  136. return primaryKey;
  137. }
  138. }
  139. }
  140. return "";
  141. }
  142. /**
  143. * 获取第一个主键, 排除某些主键
  144. */
  145. public static String getPrimaryExculde(DbSourceOrDbLink dbSourceOrDbLink, String table, String... excludeField) throws SQLException {
  146. @Cleanup Connection conn = ConnUtil.getConnOrDefault(dbSourceOrDbLink);
  147. return getPrimaryExculde(conn, table, excludeField);
  148. }
  149. /**
  150. * 如有多个主键返回第一个主键
  151. */
  152. public static String getPrimary(Connection conn, String table) throws SQLException {
  153. List<String> primaryKeys = getPrimaryKeys(conn, table);
  154. return primaryKeys.isEmpty()? "" : primaryKeys.get(0);
  155. }
  156. public static String getPrimaryIdFirst(DbSourceOrDbLink dbSourceOrDbLink, String table) throws SQLException {
  157. @Cleanup Connection conn = ConnUtil.getConnOrDefault(dbSourceOrDbLink);
  158. return getPrimaryIdFirst(conn, table);
  159. }
  160. /**
  161. * 如有多个主键返回第一个主键, id优先返回
  162. */
  163. public static String getPrimaryIdFirst(Connection conn, String table) throws SQLException {
  164. List<String> primaryKeys = getPrimaryKeys(conn, table);
  165. String findedId = "";
  166. for (String primaryKey : primaryKeys) {
  167. findedId = primaryKey;
  168. // 联合主键优先返回f_id, id字段
  169. if(TableFieldsNameConst.F_ID.equalsIgnoreCase(findedId) || TableFieldsNameConst.ID.equalsIgnoreCase(findedId)){
  170. break;
  171. }
  172. }
  173. return findedId;
  174. }
  175. /**
  176. * 返回全部主键
  177. */
  178. public static List<String> getPrimaryKeys(DbSourceOrDbLink dbSourceOrDbLink, String table) throws SQLException {
  179. @Cleanup Connection conn = ConnUtil.getConnOrDefault(dbSourceOrDbLink);
  180. return getPrimaryKeys(conn, table);
  181. }
  182. /**
  183. * 返回全部主键
  184. */
  185. public static List<String> getPrimaryKeys(Connection conn, String table) throws SQLException {
  186. //获取表主键
  187. @Cleanup ResultSet rs = conn.getMetaData().getPrimaryKeys(conn.getCatalog(), null, table);
  188. List<String> primaryKeys = new ArrayList<>();
  189. while(rs.next()){
  190. primaryKeys.add(rs.getString(RsColumnKeyConst.COLUMN_NAME));
  191. }
  192. return primaryKeys;
  193. }
  194. /**
  195. * 返回全部表的主键信息
  196. * @return [{表名:主键名}]
  197. */
  198. public static List<Map<String, String>> getPrimaryMapList(Connection conn, String schema) throws SQLException {
  199. //获取表主键
  200. @Cleanup ResultSet rs = conn.getMetaData().getPrimaryKeys(conn.getCatalog(), schema, null);
  201. List<Map<String, String>> list = new ArrayList<>();
  202. while (rs.next()){
  203. Map<String, String> map = new HashMap<>();
  204. map.put(rs.getString(RsColumnKeyConst.TABLE_NAME), rs.getString(RsColumnKeyConst.COLUMN_NAME));
  205. list.add(map);
  206. }
  207. return list;
  208. }
  209. /* ================================== 结果集 ================================== */
  210. /**
  211. * 从conn中获取数据库的表元数据
  212. * @param conn 数据连接
  213. * @return 返回表元数据
  214. * @throws SQLException ignore
  215. */
  216. public static ResultSet getTableMetaDateRs(Connection conn, String table) throws SQLException {
  217. return conn.getMetaData().getTables(conn.getCatalog(), null, table, new String[]{"TABLE"});
  218. }
  219. private static ResultSet getTableMetaDateRs(Connection conn) throws SQLException {
  220. return getTableMetaDateRs(conn, null);
  221. }
  222. }