提交 116289a9 编写于 作者: E Elune

Merge branch '2.4opt' of gitee.com:elunez/eladmin into 2.4opt

......@@ -3,15 +3,23 @@ package me.zhengjie.modules.mnt.rest;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import me.zhengjie.aop.log.Log;
import me.zhengjie.exception.BadRequestException;
import me.zhengjie.modules.mnt.domain.Database;
import me.zhengjie.modules.mnt.service.DatabaseService;
import me.zhengjie.modules.mnt.service.dto.DatabaseDto;
import me.zhengjie.modules.mnt.service.dto.DatabaseQueryCriteria;
import me.zhengjie.modules.mnt.util.SqlUtils;
import me.zhengjie.utils.FileUtil;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
/**
* @author zhanghouying
......@@ -22,6 +30,8 @@ import org.springframework.web.bind.annotation.*;
@RequestMapping("/api/database")
public class DatabaseController {
private String fileSavePath = System.getProperty("java.io.tmpdir");
private final DatabaseService databaseService;
public DatabaseController(DatabaseService databaseService) {
......@@ -61,4 +71,32 @@ public class DatabaseController {
databaseService.delete(id);
return new ResponseEntity(HttpStatus.OK);
}
@Log("测试数据库链接")
@ApiOperation(value = "测试数据库链接")
@PostMapping("/testConnect")
@PreAuthorize("@el.check('database:testConnect')")
public ResponseEntity testConnect(@Validated @RequestBody Database resources){
return new ResponseEntity<>(databaseService.testConnection(resources),HttpStatus.CREATED);
}
@Log("执行SQL脚本")
@ApiOperation(value = "执行SQL脚本")
@PostMapping(value = "/upload")
@PreAuthorize("@el.check('database:add')")
public ResponseEntity upload(@RequestBody MultipartFile file, HttpServletRequest request)throws Exception{
String id = request.getParameter("id");
DatabaseDto database = databaseService.findById(id);
String fileName = "";
if(database != null){
fileName = file.getOriginalFilename();
File executeFile = new File(fileSavePath+fileName);
FileUtil.del(executeFile);
file.transferTo(executeFile);
String result = SqlUtils.executeFile(database.getJdbcUrl(), database.getUserName(), database.getPwd(), executeFile);
return new ResponseEntity<>(result,HttpStatus.OK);
}else{
throw new BadRequestException("Database not exist");
}
}
}
......@@ -51,4 +51,11 @@ public interface DatabaseService {
* @param id /
*/
void delete(String id);
/**
* 测试连接数据库
* @param resources
* @return
*/
boolean testConnection(Database resources);
}
package me.zhengjie.modules.mnt.service.impl;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.modules.mnt.domain.Database;
import me.zhengjie.modules.mnt.repository.DatabaseRepository;
import me.zhengjie.modules.mnt.service.DatabaseService;
import me.zhengjie.modules.mnt.service.dto.DatabaseDto;
import me.zhengjie.modules.mnt.service.dto.DatabaseQueryCriteria;
import me.zhengjie.modules.mnt.service.mapper.DatabaseMapper;
import me.zhengjie.modules.mnt.util.SqlUtils;
import me.zhengjie.utils.PageUtil;
import me.zhengjie.utils.QueryHelp;
import me.zhengjie.utils.ValidationUtil;
......@@ -21,6 +23,7 @@ import org.springframework.transaction.annotation.Transactional;
* @date 2019-08-24
*/
@Service
@Slf4j
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class DatabaseServiceImpl implements DatabaseService {
......@@ -72,4 +75,15 @@ public class DatabaseServiceImpl implements DatabaseService {
public void delete(String id) {
databaseRepository.deleteById(id);
}
@Override
public boolean testConnection(Database resources) {
try {
return SqlUtils.testConnection(resources.getJdbcUrl(), resources.getUserName(), resources.getPwd());
} catch (Exception e) {
log.error(e.getMessage());
return false;
}
}
}
/*
* <<
* Davinci
* ==
* Copyright (C) 2016 - 2019 EDP
* ==
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* >>
*
*/
package me.zhengjie.modules.mnt.util;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public enum DataTypeEnum {
MYSQL("mysql", "mysql", "com.mysql.jdbc.Driver", "`", "`", "'", "'"),
ORACLE("oracle", "oracle", "oracle.jdbc.driver.OracleDriver", "\"", "\"", "\"", "\""),
SQLSERVER("sqlserver", "sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "\"", "\"", "\"", "\""),
H2("h2", "h2", "org.h2.Driver", "`", "`", "\"", "\""),
PHOENIX("phoenix", "hbase phoenix", "org.apache.phoenix.jdbc.PhoenixDriver", "", "", "\"", "\""),
MONGODB("mongo", "mongodb", "mongodb.jdbc.MongoDriver", "`", "`", "\"", "\""),
ELASTICSEARCH("sql4es", "elasticsearch", "nl.anchormen.sql4es.jdbc.ESDriver", "", "", "'", "'"),
PRESTO("presto", "presto", "com.facebook.presto.jdbc.PrestoDriver", "", "", "\"", "\""),
MOONBOX("moonbox", "moonbox", "moonbox.jdbc.MbDriver", "`", "`", "`", "`"),
CASSANDRA("cassandra", "cassandra", "com.github.adejanovski.cassandra.jdbc.CassandraDriver", "", "", "'", "'"),
CLICKHOUSE("clickhouse", "clickhouse", "ru.yandex.clickhouse.ClickHouseDriver", "", "", "\"", "\""),
KYLIN("kylin", "kylin", "org.apache.kylin.jdbc.Driver", "\"", "\"", "\"", "\""),
VERTICA("vertica", "vertica", "com.vertica.jdbc.Driver", "", "", "'", "'"),
HANA("sap", "sap hana", "com.sap.db.jdbc.Driver", "", "", "'", "'"),
IMPALA("impala", "impala", "com.cloudera.impala.jdbc41.Driver", "", "", "'", "'");
private String feature;
private String desc;
private String driver;
private String keywordPrefix;
private String keywordSuffix;
private String aliasPrefix;
private String aliasSuffix;
private static final String jdbcUrlPrefix = "jdbc:";
DataTypeEnum(String feature, String desc, String driver, String keywordPrefix, String keywordSuffix, String aliasPrefix, String aliasSuffix) {
this.feature = feature;
this.desc = desc;
this.driver = driver;
this.keywordPrefix = keywordPrefix;
this.keywordSuffix = keywordSuffix;
this.aliasPrefix = aliasPrefix;
this.aliasSuffix = aliasSuffix;
}
public static DataTypeEnum urlOf(String jdbcUrl) {
String url = jdbcUrl.toLowerCase().trim();
for (DataTypeEnum dataTypeEnum : values()) {
if (url.startsWith(jdbcUrlPrefix + dataTypeEnum.feature)) {
try {
Class<?> aClass = Class.forName(dataTypeEnum.getDriver());
if (null == aClass) {
throw new RuntimeException("Unable to get driver instance for jdbcUrl: " + jdbcUrl);
}
} catch (ClassNotFoundException e) {
throw new RuntimeException("Unable to get driver instance: " + jdbcUrl);
}
return dataTypeEnum;
}
}
return null;
}
public String getFeature() {
return feature;
}
public String getDesc() {
return desc;
}
public String getDriver() {
return driver;
}
public String getKeywordPrefix() {
return keywordPrefix;
}
public String getKeywordSuffix() {
return keywordSuffix;
}
public String getAliasPrefix() {
return aliasPrefix;
}
public String getAliasSuffix() {
return aliasSuffix;
}
}
package me.zhengjie.modules.mnt.util;
import cn.hutool.crypto.SecureUtil;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.util.StringUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import javax.sql.DataSource;
import java.io.*;
import java.sql.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Slf4j
public class SqlUtils {
public static final String COLON = ":";
private static volatile Map<String, DruidDataSource> map = new HashMap<>();
private static String getKey(String jdbcUrl, String username, String password) {
StringBuilder sb = new StringBuilder();
if (!StringUtils.isEmpty(username)) {
sb.append(username);
}
if (!StringUtils.isEmpty(password)) {
sb.append(COLON).append(password);
}
sb.append(COLON).append(jdbcUrl.trim());
return SecureUtil.md5(sb.toString());
}
/**
* 获取数据源
*
* @param jdbcUrl
* @param userName
* @param password
* @return
*/
private static DataSource getDataSource(String jdbcUrl, String userName, String password) {
String key = getKey(jdbcUrl, userName, password);
if (!map.containsKey(key) || null == map.get(key)) {
DruidDataSource druidDataSource = new DruidDataSource();
String className = null;
try {
className = DriverManager.getDriver(jdbcUrl.trim()).getClass().getName();
} catch (SQLException e) {
throw new RuntimeException("Get class name error: =" + jdbcUrl);
}
if (StringUtils.isEmpty(className)) {
DataTypeEnum dataTypeEnum = DataTypeEnum.urlOf(jdbcUrl);
if (null == dataTypeEnum) {
throw new RuntimeException("Not supported data type: jdbcUrl=" + jdbcUrl);
}
druidDataSource.setDriverClassName(dataTypeEnum.getDriver());
} else {
druidDataSource.setDriverClassName(className);
}
druidDataSource.setUrl(jdbcUrl);
druidDataSource.setUsername(userName);
druidDataSource.setPassword(password);
// 配置获取连接等待超时的时间
druidDataSource.setMaxWait(3000);
// 配置初始化大小、最小、最大
druidDataSource.setInitialSize(1);
druidDataSource.setMinIdle(1);
druidDataSource.setMaxActive(1);
// 配置间隔多久才进行一次检测需要关闭的空闲连接,单位是毫秒
druidDataSource.setTimeBetweenEvictionRunsMillis(50000);
// 配置一旦重试多次失败后等待多久再继续重试连接,单位是毫秒
druidDataSource.setTimeBetweenConnectErrorMillis(18000);
// 配置一个连接在池中最小生存的时间,单位是毫秒
druidDataSource.setMinEvictableIdleTimeMillis(300000);
// 这个特性能解决 MySQL 服务器8小时关闭连接的问题
druidDataSource.setMaxEvictableIdleTimeMillis(25200000);
try {
druidDataSource.init();
} catch (SQLException e) {
log.error("Exception during pool initialization", e);
throw new RuntimeException(e.getMessage());
}
map.put(key, druidDataSource);
}
return map.get(key);
}
private static Connection getConnection(String jdbcUrl, String userName, String password) {
DataSource dataSource = getDataSource(jdbcUrl, userName, password);
Connection connection = null;
try {
connection = dataSource.getConnection();
} catch (Exception e) {
connection = null;
}
try {
if (null == connection || connection.isClosed() || !connection.isValid(5)) {
log.info("connection is closed or invalid, retry get connection!");
connection = dataSource.getConnection();
}
} catch (Exception e) {
log.error("create connection error, jdbcUrl: {}", jdbcUrl);
throw new RuntimeException("create connection error, jdbcUrl: " + jdbcUrl);
}
return connection;
}
private static void releaseConnection(Connection connection) {
if (null != connection) {
try {
connection.close();
connection = null;
} catch (Exception e) {
e.printStackTrace();
log.error("connection close error", e.getMessage());
}
}
}
public static void closeResult(ResultSet rs) {
if (rs != null) {
try {
rs.close();
rs = null;
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static boolean testConnection(String jdbcUrl, String userName, String password) {
Connection connection = null;
try {
connection = getConnection(jdbcUrl, userName, password);
if (null != connection) {
return true;
}
} catch (Exception e) {
log.info("Get connection failed:", e.getMessage());
} finally {
releaseConnection(connection);
}
return false;
}
public static String executeFile(String jdbcUrl, String userName, String password, File sqlFile) {
Connection connection = getConnection(jdbcUrl, userName, password);
try {
batchExecute(connection, readSqlList( sqlFile));
} catch (Exception e) {
log.error("sql脚本执行发生异常:{}",e.getMessage());
return e.getMessage();
}finally {
releaseConnection(connection);
}
return "success";
}
/**
* 批量执行sql
* @param connection
* @param sqlList
* @return
*/
public static void batchExecute(Connection connection, List<String> sqlList) throws SQLException {
Statement st = connection.createStatement();
for (String sql : sqlList) {
if (sql.endsWith(";")) {
sql = sql.substring(0, sql.length() - 1);
}
st.addBatch(sql);
}
st.executeBatch();
}
/**
* 将文件中的sql语句以;为单位读取到列表中
* @param sqlFile
* @return
* @throws Exception
*/
private static List<String> readSqlList(File sqlFile) throws Exception {
List<String> sqlList = Lists.newArrayList();
StringBuilder sb = new StringBuilder();
BufferedReader reader = null;
try {
reader = new BufferedReader(new InputStreamReader(
new FileInputStream(sqlFile), "UTF-8"));
String tmp = null;
while ((tmp = reader.readLine()) != null) {
log.info("line:{}", tmp);
if (tmp.endsWith(";")) {
sb.append(tmp);
sqlList.add(sb.toString());
sb.delete(0, sb.length());
} else {
sb.append(tmp);
}
}
if (!"".endsWith(sb.toString().trim())) {
sqlList.add(sb.toString());
}
} finally {
try {
reader.close();
} catch (IOException e1) {
}
}
return sqlList;
}
}
......@@ -367,6 +367,8 @@ CREATE TABLE `mnt_database` (
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
INSERT INTO `mnt_database` VALUES ('604dd98ae8b44b128544c2135628f87d', '本机', 'jdbc:log4jdbc:mysql://localhost:3306/eladmin?serverTimezone=UTC', 'root', '123456');
-- ----------------------------
-- Table structure for mnt_deploy
-- ----------------------------
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册