Browse Source

feat: 通过前端执行sql

370774330@qq.com 5 years ago
parent
commit
7811f7a81e

+ 41 - 0
web/src/main/java/cn/seecoder/web/controller/sql/SqlController.java

@@ -0,0 +1,41 @@
+package cn.seecoder.web.controller.sql;
+
+import cn.seecoder.web.model.vo.Response;
+import cn.seecoder.web.model.vo.sql.SqlExecVO;
+import cn.seecoder.web.service.sql.SqlService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiImplicitParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author Chenyz
+ * @date 2021/3/10
+ * @description:
+ * 由于目前阿里云集群无法直接暴露TCP端口
+ * 因此需要一个前端输入sql并指定数据库,由此后段代替执行返回结果的模块
+ */
+@Api(tags = "SQL执行相关 API")
+@RestController
+@RequestMapping("/sql")
+public class SqlController {
+
+
+    private SqlService sqlService;
+
+    @Autowired
+    public SqlController(SqlService sqlService) {
+        this.sqlService = sqlService;
+    }
+
+    @ApiOperation(value = "执行sql", httpMethod = "POST")
+    @PostMapping("/exec")
+    @ApiImplicitParam(name = "projectCreateVO",dataType = "object", paramType = "body")
+    public Response<String> exec(@RequestBody SqlExecVO sqlExecVO) {
+        return Response.buildSuccess(sqlService.execute(sqlExecVO.getUrl(), sqlExecVO.getDb(),sqlExecVO.getUsername(),sqlExecVO.getPassword(),sqlExecVO.getSql()));
+    }
+}

+ 28 - 0
web/src/main/java/cn/seecoder/web/model/vo/sql/SqlExecVO.java

@@ -0,0 +1,28 @@
+package cn.seecoder.web.model.vo.sql;
+
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@Data
+@ApiModel("SQL执行表达")
+public class SqlExecVO {
+
+    @ApiModelProperty("数据库url,例子: 192.123.13.11")
+    String url;
+
+    @ApiModelProperty("连接的db名称, 默认为空")
+    String db = "";
+
+    @ApiModelProperty("用户名")
+    String username;
+
+    @ApiModelProperty("密码")
+    String password;
+
+    @ApiModelProperty("执行sql")
+    String sql;
+
+
+}

+ 56 - 0
web/src/main/java/cn/seecoder/web/service/impl/sql/SqlServiceImpl.java

@@ -0,0 +1,56 @@
+package cn.seecoder.web.service.impl.sql;
+
+import cn.seecoder.web.service.sql.SqlService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Locale;
+
+@Service
+@Slf4j
+public class SqlServiceImpl implements SqlService {
+
+    private static final String DB_URL_PREFIX = "jdbc:mysql://";
+
+    private static final String DB_URL_SUFFIX = "?allowPublicKeyRetrieval=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false";
+
+    @Override
+    public String execute(String url, String db,String username, String password, String sql) {
+        String dbUrl = DB_URL_PREFIX + url + "/" + db + DB_URL_SUFFIX;
+        try(Connection conn = DriverManager.getConnection(dbUrl, username, password);
+            Statement stmt = conn.createStatement();
+        ) {
+            //只有select语句需要解析 resultset
+            if ("select".equals(sql.trim().substring(0,6).toLowerCase(Locale.ROOT))){
+                ResultSet rs = stmt.executeQuery(sql);
+                return "Boolean\n"+ convertResultSet2List(rs);
+            } else {
+                return "Boolean\n";
+            }
+
+        } catch (SQLException e) {
+            e.printStackTrace();
+            log.error("url: {}\nsql: {}\nsql state: {}", dbUrl,sql,e.getMessage());
+            return "False\n"+e.getMessage();
+        }
+
+    }
+
+
+    private List<List<String>> convertResultSet2List(ResultSet rs) throws SQLException {
+        ResultSetMetaData meta = rs.getMetaData();
+        List<List<String>> list = new ArrayList<>();
+        while(rs.next()){
+            List<String> row = new ArrayList<>(meta.getColumnCount());
+            for (int i = 0; i < meta.getColumnCount(); i++) {
+                row.add(rs.getString(i+1));
+            }
+            list.add(row);
+        }
+        return list;
+    }
+
+}

+ 9 - 0
web/src/main/java/cn/seecoder/web/service/sql/SqlService.java

@@ -0,0 +1,9 @@
+package cn.seecoder.web.service.sql;
+
+
+
+public interface SqlService {
+
+    String execute(String url, String db, String username, String password,String sql);
+
+}