Showing
9 changed files
with
245 additions
and
9 deletions
@@ -74,4 +74,10 @@ public class TkDbConnectController extends BaseController { | @@ -74,4 +74,10 @@ public class TkDbConnectController extends BaseController { | ||
74 | public ResponseEntity<TkDbConnectDTO> get(@RequestParam("id") String id) throws ThingsboardException { | 74 | public ResponseEntity<TkDbConnectDTO> get(@RequestParam("id") String id) throws ThingsboardException { |
75 | return ResponseEntity.ok(tkDbConnectService.get(id)); | 75 | return ResponseEntity.ok(tkDbConnectService.get(id)); |
76 | } | 76 | } |
77 | + | ||
78 | + @PostMapping("/dataView") | ||
79 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN','CUSTOMER_USER')") | ||
80 | + public ResponseEntity<Object> dataView(@RequestBody TkDbConnectDTO tkDbConnectDTO) throws ThingsboardException { | ||
81 | + return ResponseEntity.ok(tkDbConnectService.connectResult(tkDbConnectDTO)); | ||
82 | + } | ||
77 | } | 83 | } |
@@ -59,4 +59,7 @@ public class TkDbConnectDTO extends TenantDTO { | @@ -59,4 +59,7 @@ public class TkDbConnectDTO extends TenantDTO { | ||
59 | 59 | ||
60 | @ApiModelProperty("SSL通道配置信息") | 60 | @ApiModelProperty("SSL通道配置信息") |
61 | private TkDbConnectSslDTO ssl; | 61 | private TkDbConnectSslDTO ssl; |
62 | + | ||
63 | + @ApiModelProperty("预览sql") | ||
64 | + private String sql; | ||
62 | } | 65 | } |
@@ -305,7 +305,12 @@ | @@ -305,7 +305,12 @@ | ||
305 | <artifactId>data-ext</artifactId> | 305 | <artifactId>data-ext</artifactId> |
306 | <scope>compile</scope> | 306 | <scope>compile</scope> |
307 | </dependency> | 307 | </dependency> |
308 | - | 308 | + <!-- MySQL JDBC 驱动 --> |
309 | + <dependency> | ||
310 | + <groupId>mysql</groupId> | ||
311 | + <artifactId>mysql-connector-java</artifactId> | ||
312 | + <version>8.0.28</version> | ||
313 | + </dependency> | ||
309 | </dependencies> | 314 | </dependencies> |
310 | <build> | 315 | <build> |
311 | <plugins> | 316 | <plugins> |
@@ -16,16 +16,12 @@ public class TkDbConnectSslEntity extends TenantBaseEntity { | @@ -16,16 +16,12 @@ public class TkDbConnectSslEntity extends TenantBaseEntity { | ||
16 | 16 | ||
17 | private String connectId; | 17 | private String connectId; |
18 | 18 | ||
19 | - private String ip; | 19 | + private String caCert; |
20 | 20 | ||
21 | - private String port; | 21 | + private boolean verifyCaCert; |
22 | 22 | ||
23 | - private String sshName; | 23 | + private String clientKey; |
24 | 24 | ||
25 | - private String sshPassword; | ||
26 | - | ||
27 | - private String verifyMethod; | ||
28 | - | ||
29 | - private String privateKey; | 25 | + private String clientCert; |
30 | 26 | ||
31 | } | 27 | } |
dao/src/main/java/org/thingsboard/server/dao/yunteng/factory/DbConnectServiceFactory.java
0 → 100644
1 | +package org.thingsboard.server.dao.yunteng.factory; | ||
2 | + | ||
3 | +import org.springframework.beans.factory.annotation.Autowired; | ||
4 | +import org.springframework.stereotype.Service; | ||
5 | +import org.thingsboard.server.dao.yunteng.service.BaseDbConnectService; | ||
6 | + | ||
7 | +import java.util.Map; | ||
8 | + | ||
9 | +@Service | ||
10 | +public class DbConnectServiceFactory { | ||
11 | + | ||
12 | + @Autowired | ||
13 | + private Map<String, BaseDbConnectService> serviceMap; | ||
14 | + | ||
15 | + public BaseDbConnectService getService(String key) { | ||
16 | + BaseDbConnectService service = serviceMap.get(key); | ||
17 | + if (service == null) { | ||
18 | + throw new IllegalArgumentException("未知数据库链接类型: " + key); | ||
19 | + } | ||
20 | + | ||
21 | + return service; | ||
22 | + } | ||
23 | +} |
1 | +package org.thingsboard.server.dao.yunteng.impl; | ||
2 | + | ||
3 | +import com.zaxxer.hikari.HikariConfig; | ||
4 | +import com.zaxxer.hikari.HikariDataSource; | ||
5 | +import org.apache.commons.lang3.BooleanUtils; | ||
6 | +import org.apache.commons.lang3.StringUtils; | ||
7 | +import org.springframework.stereotype.Service; | ||
8 | +import org.thingsboard.server.common.data.yunteng.dto.TkDbConnectDTO; | ||
9 | +import org.thingsboard.server.dao.yunteng.service.BaseDbConnectService; | ||
10 | + | ||
11 | +import java.sql.*; | ||
12 | +import java.util.ArrayList; | ||
13 | +import java.util.List; | ||
14 | + | ||
15 | +/** | ||
16 | + * mySql类型数据库连接查询 | ||
17 | + */ | ||
18 | +@Service("MySql") | ||
19 | +public class MySqlDbConnectServiceImpl implements BaseDbConnectService { | ||
20 | + @Override | ||
21 | + public Object connect(TkDbConnectDTO tkDbConnectDTO) { | ||
22 | + if (BooleanUtils.isNotTrue(tkDbConnectDTO.isOpenSsh()) && BooleanUtils.isNotTrue(tkDbConnectDTO.isOpenSsl())) { | ||
23 | + return commonConnect(tkDbConnectDTO); | ||
24 | + } | ||
25 | + | ||
26 | + return null; | ||
27 | + } | ||
28 | + | ||
29 | + private Object commonConnect(TkDbConnectDTO tkDbConnectDTO) { | ||
30 | + PreparedStatement statement = null; | ||
31 | + ResultSet resultSet = null; | ||
32 | + Connection connection = null; | ||
33 | + HikariDataSource dataSource = null; | ||
34 | + List<Object> resultList = new ArrayList<>(); | ||
35 | + try { | ||
36 | + HikariConfig config = new HikariConfig(); | ||
37 | + config.setJdbcUrl(tkDbConnectDTO.getUrl()); | ||
38 | + config.setUsername(tkDbConnectDTO.getUserName()); | ||
39 | + config.setPassword(tkDbConnectDTO.getPassword()); | ||
40 | + config.setDriverClassName("com.mysql.cj.jdbc.Driver"); | ||
41 | + | ||
42 | + // 连接池配置 | ||
43 | + config.setMaximumPoolSize(tkDbConnectDTO.getMaxPoolSize()); // 最大连接数 | ||
44 | + config.setMinimumIdle(tkDbConnectDTO.getMinIdle()); // 最小空闲连接数 | ||
45 | +// config.setIdleTimeout(600000); // 空闲连接超时时间(毫秒) | ||
46 | + config.setConnectionTimeout(tkDbConnectDTO.getConnectTimeout()); // 连接超时时间(毫秒) | ||
47 | +// config.setMaxLifetime(1800000); // 连接最大生命周期(毫秒) | ||
48 | + | ||
49 | + // 连接校验配置 | ||
50 | + config.setConnectionTestQuery(StringUtils.isNotBlank(tkDbConnectDTO.getConnectTestQuery()) ? | ||
51 | + tkDbConnectDTO.getConnectTestQuery() : "SELECT 1"); // 连接校验语句 | ||
52 | +// config.setValidationTimeout(5000); // 校验超时时间(毫秒) | ||
53 | + | ||
54 | + dataSource = new HikariDataSource(config); | ||
55 | + connection = dataSource.getConnection(); | ||
56 | + statement = connection.prepareStatement(tkDbConnectDTO.getSql()); | ||
57 | + resultSet = statement.executeQuery(); | ||
58 | + ResultSetMetaData metaData = resultSet.getMetaData(); | ||
59 | + List<String> columnNames = new ArrayList<>(); | ||
60 | + for (int index = 1; index <= metaData.getColumnCount(); index++) { | ||
61 | + columnNames.add(metaData.getColumnLabel(index)); | ||
62 | + } | ||
63 | + | ||
64 | + resultList.add(columnNames); | ||
65 | + // 处理结果集 | ||
66 | + while (resultSet.next()) { | ||
67 | + List<Object> result = new ArrayList<>(metaData.getColumnCount()); | ||
68 | + for (int index = 1; index <= metaData.getColumnCount(); index++) { | ||
69 | + int columnType = metaData.getColumnType(index); | ||
70 | + Object value = getTypedValue(resultSet, index, columnType); | ||
71 | + result.add(value); | ||
72 | + } | ||
73 | + | ||
74 | + resultList.add(result); | ||
75 | + } | ||
76 | + } catch (Exception e) { | ||
77 | + e.printStackTrace(); | ||
78 | + throw new RuntimeException(e.getMessage()); | ||
79 | + } finally { | ||
80 | + // 释放资源 | ||
81 | + try { | ||
82 | + if (resultSet != null) resultSet.close(); | ||
83 | + if (statement != null) statement.close(); | ||
84 | + if (connection != null) connection.close(); | ||
85 | + } catch (SQLException e) { | ||
86 | + e.printStackTrace(); | ||
87 | + } | ||
88 | + | ||
89 | + if (dataSource != null && !dataSource.isClosed()) { | ||
90 | + dataSource.close(); | ||
91 | + } | ||
92 | + } | ||
93 | + | ||
94 | + return resultList; | ||
95 | + } | ||
96 | + | ||
97 | + private Object getTypedValue(ResultSet rs, int index, int sqlType) throws SQLException { | ||
98 | + Object value; | ||
99 | + | ||
100 | + switch (sqlType) { | ||
101 | + case Types.BIT: | ||
102 | + case Types.BOOLEAN: | ||
103 | + value = rs.getBoolean(index); | ||
104 | + return rs.wasNull() ? null : value; | ||
105 | + | ||
106 | + case Types.TINYINT: | ||
107 | + case Types.SMALLINT: | ||
108 | + case Types.INTEGER: | ||
109 | + value = rs.getInt(index); | ||
110 | + return rs.wasNull() ? null : value; | ||
111 | + | ||
112 | + case Types.BIGINT: | ||
113 | + value = rs.getLong(index); | ||
114 | + return rs.wasNull() ? null : value; | ||
115 | + | ||
116 | + case Types.FLOAT: | ||
117 | + case Types.REAL: | ||
118 | + value = rs.getFloat(index); | ||
119 | + return rs.wasNull() ? null : value; | ||
120 | + | ||
121 | + case Types.DOUBLE: | ||
122 | + value = rs.getDouble(index); | ||
123 | + return rs.wasNull() ? null : value; | ||
124 | + | ||
125 | + case Types.NUMERIC: | ||
126 | + case Types.DECIMAL: | ||
127 | + value = rs.getBigDecimal(index); | ||
128 | + return rs.wasNull() ? null : value; | ||
129 | + | ||
130 | + case Types.CHAR: | ||
131 | + case Types.VARCHAR: | ||
132 | + case Types.LONGVARCHAR: | ||
133 | + case Types.NCHAR: | ||
134 | + case Types.NVARCHAR: | ||
135 | + case Types.LONGNVARCHAR: | ||
136 | + value = rs.getString(index); | ||
137 | + return rs.wasNull() ? null : value; | ||
138 | + | ||
139 | + case Types.DATE: | ||
140 | + Date date = rs.getDate(index); | ||
141 | + return date != null ? date.toLocalDate() : null; | ||
142 | + | ||
143 | + case Types.TIME: | ||
144 | + Time time = rs.getTime(index); | ||
145 | + return time != null ? time.toLocalTime() : null; | ||
146 | + | ||
147 | + case Types.TIMESTAMP: | ||
148 | + Timestamp timestamp = rs.getTimestamp(index); | ||
149 | + return timestamp != null ? timestamp.toLocalDateTime() : null; | ||
150 | + | ||
151 | + case Types.BINARY: | ||
152 | + case Types.VARBINARY: | ||
153 | + case Types.LONGVARBINARY: | ||
154 | + value = rs.getBytes(index); | ||
155 | + return rs.wasNull() ? null : value; | ||
156 | + | ||
157 | + case Types.BLOB: | ||
158 | + value = rs.getBlob(index); | ||
159 | + return rs.wasNull() ? null : value; | ||
160 | + | ||
161 | + case Types.CLOB: | ||
162 | + value = rs.getClob(index); | ||
163 | + return rs.wasNull() ? null : value; | ||
164 | + | ||
165 | + default: | ||
166 | + value = rs.getObject(index); | ||
167 | + return rs.wasNull() ? null : value; | ||
168 | + } | ||
169 | + } | ||
170 | +} |
@@ -13,6 +13,7 @@ import org.thingsboard.server.common.data.yunteng.dto.TkDbConnectSshDTO; | @@ -13,6 +13,7 @@ import org.thingsboard.server.common.data.yunteng.dto.TkDbConnectSshDTO; | ||
13 | import org.thingsboard.server.common.data.yunteng.dto.TkDbConnectSslDTO; | 13 | import org.thingsboard.server.common.data.yunteng.dto.TkDbConnectSslDTO; |
14 | import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; | 14 | import org.thingsboard.server.common.data.yunteng.utils.tools.TkPageData; |
15 | import org.thingsboard.server.dao.yunteng.entities.TkDbConnectEntity; | 15 | import org.thingsboard.server.dao.yunteng.entities.TkDbConnectEntity; |
16 | +import org.thingsboard.server.dao.yunteng.factory.DbConnectServiceFactory; | ||
16 | import org.thingsboard.server.dao.yunteng.mapper.TkDbConnectMapper; | 17 | import org.thingsboard.server.dao.yunteng.mapper.TkDbConnectMapper; |
17 | import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; | 18 | import org.thingsboard.server.dao.yunteng.service.AbstractBaseService; |
18 | import org.thingsboard.server.dao.yunteng.service.TkDbConnectService; | 19 | import org.thingsboard.server.dao.yunteng.service.TkDbConnectService; |
@@ -28,6 +29,7 @@ public class TkDbConnectServiceImpl extends AbstractBaseService<TkDbConnectMappe | @@ -28,6 +29,7 @@ public class TkDbConnectServiceImpl extends AbstractBaseService<TkDbConnectMappe | ||
28 | implements TkDbConnectService { | 29 | implements TkDbConnectService { |
29 | private final TkDbConnectSshService tkDbConnectSshService; | 30 | private final TkDbConnectSshService tkDbConnectSshService; |
30 | private final TkDbConnectSslService tkDbConnectSslService; | 31 | private final TkDbConnectSslService tkDbConnectSslService; |
32 | + private final DbConnectServiceFactory connectServiceFactory; | ||
31 | 33 | ||
32 | @Override | 34 | @Override |
33 | public TkPageData<TkDbConnectDTO> page(Map<String, Object> queryMap, String tenantId) { | 35 | public TkPageData<TkDbConnectDTO> page(Map<String, Object> queryMap, String tenantId) { |
@@ -104,4 +106,19 @@ public class TkDbConnectServiceImpl extends AbstractBaseService<TkDbConnectMappe | @@ -104,4 +106,19 @@ public class TkDbConnectServiceImpl extends AbstractBaseService<TkDbConnectMappe | ||
104 | tkDbConnectDTO.setSsl(ssl); | 106 | tkDbConnectDTO.setSsl(ssl); |
105 | return tkDbConnectDTO; | 107 | return tkDbConnectDTO; |
106 | } | 108 | } |
109 | + | ||
110 | + @Override | ||
111 | + public Object connectResult(TkDbConnectDTO tkDbConnectDTO) { | ||
112 | + if (tkDbConnectDTO == null || StringUtils.isBlank(tkDbConnectDTO.getSql()) || StringUtils.isBlank(tkDbConnectDTO.getId())) { | ||
113 | + return new Object(); | ||
114 | + } | ||
115 | + | ||
116 | + TkDbConnectDTO dbDto = get(tkDbConnectDTO.getId()); | ||
117 | + if (dbDto == null) { | ||
118 | + return new Object(); | ||
119 | + } | ||
120 | + | ||
121 | + dbDto.setSql(tkDbConnectDTO.getSql()); | ||
122 | + return connectServiceFactory.getService(dbDto.getType().toString()).connect(dbDto); | ||
123 | + } | ||
107 | } | 124 | } |
1 | +package org.thingsboard.server.dao.yunteng.service; | ||
2 | + | ||
3 | +import org.thingsboard.server.common.data.yunteng.dto.TkDbConnectDTO; | ||
4 | + | ||
5 | +public interface BaseDbConnectService { | ||
6 | + | ||
7 | + /** | ||
8 | + * 获取数据库连接结果 | ||
9 | + * | ||
10 | + * @param tkDbConnectDTO | ||
11 | + * @return | ||
12 | + */ | ||
13 | + Object connect(TkDbConnectDTO tkDbConnectDTO); | ||
14 | +} |
@@ -15,4 +15,6 @@ public interface TkDbConnectService extends BaseService<TkDbConnectEntity> { | @@ -15,4 +15,6 @@ public interface TkDbConnectService extends BaseService<TkDbConnectEntity> { | ||
15 | boolean delete(String id); | 15 | boolean delete(String id); |
16 | 16 | ||
17 | TkDbConnectDTO get(String id); | 17 | TkDbConnectDTO get(String id); |
18 | + | ||
19 | + Object connectResult(TkDbConnectDTO tkDbConnectDTO); | ||
18 | } | 20 | } |