Commit 40d40a63 authored by KeYong's avatar KeYong

提交脚本执行后端逻辑

parent b145a12a
......@@ -41,6 +41,11 @@
<groupId>mysql</groupId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
</dependencies>
<build>
......
......@@ -4,6 +4,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
......@@ -25,7 +26,7 @@ import java.net.UnknownHostException;
* @author amos
* @version $Id: AmosBootUtilsAdpterApplication, v 0.1 2024年5月7日 下午4:56:29 amos Exp $
*/
@SpringBootApplication
@SpringBootApplication(exclude=DataSourceAutoConfiguration.class)
@EnableConfigurationProperties
@ServletComponentScan
@EnableDiscoveryClient
......
package com.yeejoin.amos.adpter.controller;
import com.alibaba.fastjson.JSONObject;
import com.yeejoin.amos.adpter.service.AdpterService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
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;
......@@ -41,4 +43,17 @@ public class AdpterController {
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;
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.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
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.util.ArrayList;
import java.util.HashMap;
......@@ -19,7 +31,7 @@ public class AdpterService {
//开始时间
private static Long startTime = 0L;
//结束时间
private static Long endTime =0L;
private static Long endTime = 0L;
@Value("${source.jdbc.ip}")
......@@ -49,9 +61,8 @@ public class AdpterService {
String pwd;
public Map<String, String> handle() {
Map<String,String> rMap = new HashMap<>();
Map<String, String> rMap = new HashMap<>();
// 处理common库
copy(sourceJdbc, goalJdbc, "cb_firefighters", "cb_firefighters", "sequence_nbr", rMap);
......@@ -101,10 +112,51 @@ public class AdpterService {
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
* @return
*/
......@@ -118,7 +170,7 @@ public class AdpterService {
String jdbcUrl = jdbc;
String user = userName;
String password = pwd;
//接数据库
//接数据库
try {
return DriverManager.getConnection(jdbcUrl, user, password);
} catch (SQLException e) {
......@@ -129,11 +181,12 @@ public class AdpterService {
/**
* 将查询的数据复制到另一个数据库的表中,要求两张表的字段名,字段类型完全相同。
*
* @param srcTableName 要查询的表
* @param destTableName 目标表名称
* @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();
Connection conn = null;
......@@ -146,9 +199,9 @@ public class AdpterService {
//查询数据
String sql = String.format("select * from %s ", srcTableName);
//查询数据
String sqlGoal = "select count(*) as num from "+ destTableName +" where "+id+" = ";
List<Map<String,Object>> queryOld = query(source, sql);
List<Map<String,Object>> query = new ArrayList<>();
String sqlGoal = "select count(*) as num from " + destTableName + " where " + id + " = ";
List<Map<String, Object>> queryOld = query(source, sql);
List<Map<String, Object>> query = new ArrayList<>();
//插入数据
String insertSql = "insert into %s(%s) values(%s)";
StringBuilder key = new StringBuilder();
......@@ -157,14 +210,14 @@ public class AdpterService {
List<List<Object>> params = new ArrayList<>();
// 剔除已存在的数据
for (Map map:queryOld
for (Map map : queryOld
) {
try {
pst = conn.prepareStatement(sqlGoal+map.get(id));
pst = conn.prepareStatement(sqlGoal + map.get(id));
ResultSet resultSet = pst.executeQuery();
while (resultSet.next()) {
int num = resultSet.getInt("num");
if(num < 1) {
if (num < 1) {
query.add(map);
} else {
list.add(map.get(id).toString());
......@@ -183,16 +236,16 @@ public class AdpterService {
}
}
if(query.size() > 0) {
for(String column : query.get(0).keySet()) {
if (query.size() > 0) {
for (String column : query.get(0).keySet()) {
key.append(column).append(",");
value.append("?,");
columns.add(column);
}
insertSql = String.format(insertSql,
destTableName,
key.substring(0, key.length()-1).toString(),
value.substring(0, value.length()-1).toString());
key.substring(0, key.length() - 1).toString(),
value.substring(0, value.length() - 1).toString());
for (Map<String, Object> map : query) {
List<Object> param = new ArrayList<>();
......@@ -203,18 +256,19 @@ public class AdpterService {
}
count = executeBatch(goal, insertSql, params, destTableName);
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));
} else {
rMap.put(destTableName, "复制表"+destTableName+"成功"+"用时"+(endTime-startTime)+"ms");
rMap.put(destTableName, "复制表" + destTableName + "成功" + "用时" + (endTime - startTime) + "ms");
}
return count;
}
/**
* 批量执行一个 SQL 语句,可以传不同的参数
*
* @param sql SQL 语句
* @param params 参数列表
* @return
......@@ -230,7 +284,7 @@ public class AdpterService {
pst = conn.prepareStatement(sql);
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.addBatch();
......@@ -239,8 +293,8 @@ public class AdpterService {
conn.commit();
conn.setAutoCommit(autoCommit);
} catch (Exception e) {
log.error("插入数据失败"+e.getMessage()+"========"+destTableName);
throw new RuntimeException("插入数据失败"+e.getMessage());
log.error("插入数据失败" + e.getMessage() + "========" + destTableName);
throw new RuntimeException("插入数据失败" + e.getMessage());
} finally {
closeStatement(pst);
closeConnection(conn);
......@@ -251,11 +305,12 @@ public class AdpterService {
/**
* 查询数据并封装到 List 集合中
*
* @param sql SQL 语句
* @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<>();
Connection conn = null;
PreparedStatement pst = null;
......@@ -263,7 +318,7 @@ public class AdpterService {
try {
conn = getConnection(source);
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]);
}
rs = pst.executeQuery();
......@@ -273,11 +328,11 @@ public class AdpterService {
int columnCount = rsmd.getColumnCount();
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)); // 字段名
}
//封装数据
while(rs.next()) {
while (rs.next()) {
Map<String, Object> map = new HashMap<>();
for (String column : columns) {
map.put(column, rs.getObject(column));
......@@ -285,7 +340,7 @@ public class AdpterService {
result.add(map);
}
} catch (Exception e) {
throw new RuntimeException("查询异常"+e.getMessage());
throw new RuntimeException("查询异常" + e.getMessage());
} finally {
closeStatement(pst);
closeConnection(conn);
......@@ -294,16 +349,15 @@ public class AdpterService {
return result;
}
/**
* 关闭 Statement
*
* @param stmt
* @return
*/
public static boolean closeStatement(Statement stmt) {
boolean flag = true;
if(stmt != null) {
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
......@@ -313,16 +367,15 @@ public class AdpterService {
return flag;
}
/**
* 关闭 ResultSet
*
* @param rs
* @return
*/
public static boolean closeResultSet(ResultSet rs) {
boolean flag = true;
if(rs != null) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
......@@ -332,16 +385,15 @@ public class AdpterService {
return flag;
}
/**
* 关闭 Connection
*
* @param conn
* @return
*/
public static boolean closeConnection(Connection conn) {
boolean flag = true;
if(conn != null) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
......@@ -351,4 +403,108 @@ public class AdpterService {
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