Commit 40d40a63 authored by KeYong's avatar KeYong

提交脚本执行后端逻辑

parent b145a12a
...@@ -41,6 +41,11 @@ ...@@ -41,6 +41,11 @@
<groupId>mysql</groupId> <groupId>mysql</groupId>
</dependency> </dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies> </dependencies>
<build> <build>
......
...@@ -4,6 +4,7 @@ import org.slf4j.Logger; ...@@ -4,6 +4,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
...@@ -25,7 +26,7 @@ import java.net.UnknownHostException; ...@@ -25,7 +26,7 @@ import java.net.UnknownHostException;
* @author amos * @author amos
* @version $Id: AmosBootUtilsAdpterApplication, v 0.1 2024年5月7日 下午4:56:29 amos Exp $ * @version $Id: AmosBootUtilsAdpterApplication, v 0.1 2024年5月7日 下午4:56:29 amos Exp $
*/ */
@SpringBootApplication @SpringBootApplication(exclude=DataSourceAutoConfiguration.class)
@EnableConfigurationProperties @EnableConfigurationProperties
@ServletComponentScan @ServletComponentScan
@EnableDiscoveryClient @EnableDiscoveryClient
......
package com.yeejoin.amos.adpter.controller; package com.yeejoin.amos.adpter.controller;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.adpter.service.AdpterService; import com.yeejoin.amos.adpter.service.AdpterService;
import io.swagger.annotations.Api; import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.util.Map; import java.util.Map;
...@@ -41,4 +43,17 @@ public class AdpterController { ...@@ -41,4 +43,17 @@ public class AdpterController {
return handle; return handle;
} }
/**
* 数据库脚本执行Api
*
* @return
*/
@PostMapping(value = "/execute/file")
@ApiOperation(httpMethod = "POST", value = "脚本执行接口Api", notes = "脚本执行接口Api")
public void executeSqlFile(HttpServletRequest request, HttpServletResponse response, @RequestParam(value = "dbHost") String dbHost, @RequestParam(value = "port") String port,
@RequestParam(value = "dbName") String dbName, @RequestParam(value = "userName") String userName,
@RequestParam(value = "dbPwd") String dbPwd, @RequestPart(value = "file") MultipartFile file) throws UnsupportedEncodingException {
adpterService.executeSqlFile(request, response, dbHost, port, dbName, userName, dbPwd, file);
}
} }
\ No newline at end of file
package com.yeejoin.amos.adpter.service; package com.yeejoin.amos.adpter.service;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.RuntimeSqlException;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
...@@ -17,9 +29,9 @@ public class AdpterService { ...@@ -17,9 +29,9 @@ public class AdpterService {
private final static Logger log = LoggerFactory.getLogger(AdpterService.class); private final static Logger log = LoggerFactory.getLogger(AdpterService.class);
//开始时间 //开始时间
private static Long startTime = 0L; private static Long startTime = 0L;
//结束时间 //结束时间
private static Long endTime =0L; private static Long endTime = 0L;
@Value("${source.jdbc.ip}") @Value("${source.jdbc.ip}")
...@@ -49,9 +61,8 @@ public class AdpterService { ...@@ -49,9 +61,8 @@ public class AdpterService {
String pwd; String pwd;
public Map<String, String> handle() { public Map<String, String> handle() {
Map<String,String> rMap = new HashMap<>(); Map<String, String> rMap = new HashMap<>();
// 处理common库 // 处理common库
copy(sourceJdbc, goalJdbc, "cb_firefighters", "cb_firefighters", "sequence_nbr", rMap); copy(sourceJdbc, goalJdbc, "cb_firefighters", "cb_firefighters", "sequence_nbr", rMap);
...@@ -101,14 +112,55 @@ public class AdpterService { ...@@ -101,14 +112,55 @@ public class AdpterService {
return rMap; return rMap;
} }
public void executeSqlFile(HttpServletRequest request, HttpServletResponse response, String dbHost, String port, String dbName, String userName, String dbPwd, MultipartFile file) throws UnsupportedEncodingException {
String fileName = file.getOriginalFilename();
if (!fileName.endsWith(".sql")) {
throw new RuntimeException("文件格式错误");
}
String filePath = "output.txt";
PrintWriter printWriter = null;
File logFile = new File(filePath);
if (logFile.exists()) {
deleteFile(filePath);
}
try {
printWriter = new PrintWriter(logFile, "UTF-8");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
initAndExecute(dbHost, port, dbName, userName, dbPwd, file, printWriter);
String outPutFileName = "脚本执行结果.txt";
response.setCharacterEncoding("UTF-8");
response.setContentType("text/plain");
response.setHeader("Content-Disposition", "attachment; filename=\"" + URLEncoder.encode(outPutFileName, "UTF-8") + "\"");
//输入流
InputStream in = null;
try {
in = new FileInputStream(filePath);
ServletOutputStream os = response.getOutputStream();
//缓冲区
int len =1;
byte[] b = new byte[1024];
while ((len = in.read(b))!=-1){
os.write(b,0,len);
in.close();
os.close();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception Ignored) {
} finally {
deleteFile(filePath);
}
}
/** /**
* 获取数据库连接 * 获取数据库连接
*
* @param * @param
* @return * @return
*/ */
public Connection getConnection(String jdbc) { public Connection getConnection(String jdbc) {
//加载驱动 //加载驱动
try { try {
Class.forName(driver); Class.forName(driver);
...@@ -118,7 +170,7 @@ public class AdpterService { ...@@ -118,7 +170,7 @@ public class AdpterService {
String jdbcUrl = jdbc; String jdbcUrl = jdbc;
String user = userName; String user = userName;
String password = pwd; String password = pwd;
//接数据库 //接数据库
try { try {
return DriverManager.getConnection(jdbcUrl, user, password); return DriverManager.getConnection(jdbcUrl, user, password);
} catch (SQLException e) { } catch (SQLException e) {
...@@ -129,11 +181,12 @@ public class AdpterService { ...@@ -129,11 +181,12 @@ public class AdpterService {
/** /**
* 将查询的数据复制到另一个数据库的表中,要求两张表的字段名,字段类型完全相同。 * 将查询的数据复制到另一个数据库的表中,要求两张表的字段名,字段类型完全相同。
* @param srcTableName 要查询的表 *
* @param srcTableName 要查询的表
* @param destTableName 目标表名称 * @param destTableName 目标表名称
* @return * @return
*/ */
public int[] copy(String source, String goal, String srcTableName, String destTableName ,String id, Map rMap) { public int[] copy(String source, String goal, String srcTableName, String destTableName, String id, Map rMap) {
startTime = System.currentTimeMillis(); startTime = System.currentTimeMillis();
Connection conn = null; Connection conn = null;
...@@ -146,9 +199,9 @@ public class AdpterService { ...@@ -146,9 +199,9 @@ public class AdpterService {
//查询数据 //查询数据
String sql = String.format("select * from %s ", srcTableName); String sql = String.format("select * from %s ", srcTableName);
//查询数据 //查询数据
String sqlGoal = "select count(*) as num from "+ destTableName +" where "+id+" = "; String sqlGoal = "select count(*) as num from " + destTableName + " where " + id + " = ";
List<Map<String,Object>> queryOld = query(source, sql); List<Map<String, Object>> queryOld = query(source, sql);
List<Map<String,Object>> query = new ArrayList<>(); List<Map<String, Object>> query = new ArrayList<>();
//插入数据 //插入数据
String insertSql = "insert into %s(%s) values(%s)"; String insertSql = "insert into %s(%s) values(%s)";
StringBuilder key = new StringBuilder(); StringBuilder key = new StringBuilder();
...@@ -157,16 +210,16 @@ public class AdpterService { ...@@ -157,16 +210,16 @@ public class AdpterService {
List<List<Object>> params = new ArrayList<>(); List<List<Object>> params = new ArrayList<>();
// 剔除已存在的数据 // 剔除已存在的数据
for (Map map:queryOld for (Map map : queryOld
) { ) {
try { try {
pst = conn.prepareStatement(sqlGoal+map.get(id)); pst = conn.prepareStatement(sqlGoal + map.get(id));
ResultSet resultSet = pst.executeQuery(); ResultSet resultSet = pst.executeQuery();
while (resultSet.next()) { while (resultSet.next()) {
int num = resultSet.getInt("num"); int num = resultSet.getInt("num");
if(num < 1) { if (num < 1) {
query.add(map); query.add(map);
} else { } else {
list.add(map.get(id).toString()); list.add(map.get(id).toString());
} }
} }
...@@ -183,16 +236,16 @@ public class AdpterService { ...@@ -183,16 +236,16 @@ public class AdpterService {
} }
} }
if(query.size() > 0) { if (query.size() > 0) {
for(String column : query.get(0).keySet()) { for (String column : query.get(0).keySet()) {
key.append(column).append(","); key.append(column).append(",");
value.append("?,"); value.append("?,");
columns.add(column); columns.add(column);
} }
insertSql = String.format(insertSql, insertSql = String.format(insertSql,
destTableName, destTableName,
key.substring(0, key.length()-1).toString(), key.substring(0, key.length() - 1).toString(),
value.substring(0, value.length()-1).toString()); value.substring(0, value.length() - 1).toString());
for (Map<String, Object> map : query) { for (Map<String, Object> map : query) {
List<Object> param = new ArrayList<>(); List<Object> param = new ArrayList<>();
...@@ -203,23 +256,24 @@ public class AdpterService { ...@@ -203,23 +256,24 @@ public class AdpterService {
} }
count = executeBatch(goal, insertSql, params, destTableName); count = executeBatch(goal, insertSql, params, destTableName);
endTime = System.currentTimeMillis(); endTime = System.currentTimeMillis();
log.debug("复制表"+destTableName+"成功"+"用时"+(endTime-startTime)+"ms"); log.debug("复制表" + destTableName + "成功" + "用时" + (endTime - startTime) + "ms");
} }
if(list.size()>0) { if (list.size() > 0) {
rMap.put(destTableName, String.join(",", list)); rMap.put(destTableName, String.join(",", list));
} else { } else {
rMap.put(destTableName, "复制表"+destTableName+"成功"+"用时"+(endTime-startTime)+"ms"); rMap.put(destTableName, "复制表" + destTableName + "成功" + "用时" + (endTime - startTime) + "ms");
} }
return count; return count;
} }
/** /**
* 批量执行一个 SQL 语句,可以传不同的参数 * 批量执行一个 SQL 语句,可以传不同的参数
* @param sql SQL 语句 *
* @param sql SQL 语句
* @param params 参数列表 * @param params 参数列表
* @return * @return
*/ */
public int[] executeBatch(String goal, String sql, List<List<Object>> params, String destTableName) { public int[] executeBatch(String goal, String sql, List<List<Object>> params, String destTableName) {
int count[] = new int[0]; int count[] = new int[0];
Connection conn = null; Connection conn = null;
PreparedStatement pst = null; PreparedStatement pst = null;
...@@ -230,7 +284,7 @@ public class AdpterService { ...@@ -230,7 +284,7 @@ public class AdpterService {
pst = conn.prepareStatement(sql); pst = conn.prepareStatement(sql);
for (List<Object> list : params) { for (List<Object> list : params) {
for(int i = 0; i < list.size(); i++) { for (int i = 0; i < list.size(); i++) {
pst.setObject(i + 1, list.get(i)); pst.setObject(i + 1, list.get(i));
} }
pst.addBatch(); pst.addBatch();
...@@ -239,8 +293,8 @@ public class AdpterService { ...@@ -239,8 +293,8 @@ public class AdpterService {
conn.commit(); conn.commit();
conn.setAutoCommit(autoCommit); conn.setAutoCommit(autoCommit);
} catch (Exception e) { } catch (Exception e) {
log.error("插入数据失败"+e.getMessage()+"========"+destTableName); log.error("插入数据失败" + e.getMessage() + "========" + destTableName);
throw new RuntimeException("插入数据失败"+e.getMessage()); throw new RuntimeException("插入数据失败" + e.getMessage());
} finally { } finally {
closeStatement(pst); closeStatement(pst);
closeConnection(conn); closeConnection(conn);
...@@ -251,11 +305,12 @@ public class AdpterService { ...@@ -251,11 +305,12 @@ public class AdpterService {
/** /**
* 查询数据并封装到 List 集合中 * 查询数据并封装到 List 集合中
* @param sql SQL 语句 *
* @param sql SQL 语句
* @param args 参数列表 * @param args 参数列表
* @return List<Map<字段名, 值>> * @return List<Map < 字段名, 值>>
*/ */
public List<Map<String, Object>> query(String source, String sql, Object...args) { public List<Map<String, Object>> query(String source, String sql, Object... args) {
List<Map<String, Object>> result = new ArrayList<>(); List<Map<String, Object>> result = new ArrayList<>();
Connection conn = null; Connection conn = null;
PreparedStatement pst = null; PreparedStatement pst = null;
...@@ -263,7 +318,7 @@ public class AdpterService { ...@@ -263,7 +318,7 @@ public class AdpterService {
try { try {
conn = getConnection(source); conn = getConnection(source);
pst = conn.prepareStatement(sql); pst = conn.prepareStatement(sql);
for(int i = 0; i < args.length; i++) { for (int i = 0; i < args.length; i++) {
pst.setObject(i + 1, args[i]); pst.setObject(i + 1, args[i]);
} }
rs = pst.executeQuery(); rs = pst.executeQuery();
...@@ -273,11 +328,11 @@ public class AdpterService { ...@@ -273,11 +328,11 @@ public class AdpterService {
int columnCount = rsmd.getColumnCount(); int columnCount = rsmd.getColumnCount();
List<String> columns = new ArrayList<>(columnCount); List<String> columns = new ArrayList<>(columnCount);
for(int i = 1; i <= columnCount; i++) { for (int i = 1; i <= columnCount; i++) {
columns.add(rsmd.getColumnName(i)); // 字段名 columns.add(rsmd.getColumnName(i)); // 字段名
} }
//封装数据 //封装数据
while(rs.next()) { while (rs.next()) {
Map<String, Object> map = new HashMap<>(); Map<String, Object> map = new HashMap<>();
for (String column : columns) { for (String column : columns) {
map.put(column, rs.getObject(column)); map.put(column, rs.getObject(column));
...@@ -285,7 +340,7 @@ public class AdpterService { ...@@ -285,7 +340,7 @@ public class AdpterService {
result.add(map); result.add(map);
} }
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("查询异常"+e.getMessage()); throw new RuntimeException("查询异常" + e.getMessage());
} finally { } finally {
closeStatement(pst); closeStatement(pst);
closeConnection(conn); closeConnection(conn);
...@@ -294,16 +349,15 @@ public class AdpterService { ...@@ -294,16 +349,15 @@ public class AdpterService {
return result; return result;
} }
/** /**
* 关闭 Statement * 关闭 Statement
*
* @param stmt * @param stmt
* @return * @return
*/ */
public static boolean closeStatement(Statement stmt) { public static boolean closeStatement(Statement stmt) {
boolean flag = true; boolean flag = true;
if(stmt != null) { if (stmt != null) {
try { try {
stmt.close(); stmt.close();
} catch (SQLException e) { } catch (SQLException e) {
...@@ -313,16 +367,15 @@ public class AdpterService { ...@@ -313,16 +367,15 @@ public class AdpterService {
return flag; return flag;
} }
/** /**
* 关闭 ResultSet * 关闭 ResultSet
*
* @param rs * @param rs
* @return * @return
*/ */
public static boolean closeResultSet(ResultSet rs) { public static boolean closeResultSet(ResultSet rs) {
boolean flag = true; boolean flag = true;
if(rs != null) { if (rs != null) {
try { try {
rs.close(); rs.close();
} catch (SQLException e) { } catch (SQLException e) {
...@@ -332,16 +385,15 @@ public class AdpterService { ...@@ -332,16 +385,15 @@ public class AdpterService {
return flag; return flag;
} }
/** /**
* 关闭 Connection * 关闭 Connection
*
* @param conn * @param conn
* @return * @return
*/ */
public static boolean closeConnection(Connection conn) { public static boolean closeConnection(Connection conn) {
boolean flag = true; boolean flag = true;
if(conn != null) { if (conn != null) {
try { try {
conn.close(); conn.close();
} catch (SQLException e) { } catch (SQLException e) {
...@@ -351,4 +403,108 @@ public class AdpterService { ...@@ -351,4 +403,108 @@ public class AdpterService {
return flag; return flag;
} }
private PrintWriter initAndExecute(String dbHost, String port, String dbName, String userName, String dbPwd, MultipartFile file, PrintWriter printWriter) {
Connection conn = getManagerConnection(dbHost, port, dbName, userName, dbPwd, printWriter);
if (ObjectUtils.isEmpty(conn)) {
return printWriter;
}
FileReader reader = null;
try {
reader = new FileReader(convertMultipartFileToFile(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
ScriptRunner scriptRunner = new ScriptRunner(conn);
// 设置编码,防止中文乱码
Resources.setCharset(Charset.forName("UTF-8"));
// 获取整个脚本再执行
// scriptRunner.setSendFullScript(true);
// 执行报错时,true 则回滚, false 则会继续执行
scriptRunner.setStopOnError(false);
scriptRunner.setErrorLogWriter(printWriter);
try {
// 执行
scriptRunner.runScript(reader);
} catch (RuntimeSqlException e) {
throw new RuntimeSqlException(e);
}
scriptRunner.closeConnection();
try {
reader.close();
printWriter.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
closeConnection(conn);
}
return printWriter;
}
public File convertMultipartFileToFile(MultipartFile file) {
File convertedFile = null;
try {
convertedFile = Files.createTempFile("temp-", "-" + file.getOriginalFilename()).toFile();
file.transferTo(convertedFile);
} catch (IOException e) {
e.printStackTrace();
}
return convertedFile;
}
private Connection getManagerConnection(String dbHost, String port, String dbName, String userName, String dbPwd, PrintWriter printWriter) {
String jdbcUrl = "jdbc:mysql://" + dbHost + ":" + port + "/" + dbName + "?useUnicode=true&allowMultiQueries=true&characterEncoding=utf-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai";
//加载驱动
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//连接数据库
try {
return DriverManager.getConnection(jdbcUrl, userName, dbPwd);
} catch (SQLException e) {
String errorMsg = "连接数据库失败,请检查数据库连接信息是否有误!";
if (printWriter.checkError()) {
try
{
File logFile = new File("output.txt");
printWriter = new PrintWriter(logFile, "UTF-8");
printWriter.write(errorMsg);
if (printWriter.checkError())
{
log.error("文件写入异常:" + errorMsg);
}
}
catch (Exception exception)
{
log.error("日志写入异常!" + errorMsg, exception);
}
} else {
printWriter.write(errorMsg);
}
printWriter.flush();
printWriter.close();
e.printStackTrace();
return null;
}
}
public static boolean deleteFile(String path) {
boolean flag = false;
try {
File file = new File(path);
// 路径为文件且不为空则进行删除
if (file.isFile()) {
file.delete();
flag = true;
}
}catch (Exception e){
e.printStackTrace();
}
return flag;
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment