Java程序实现 测试数据库连接和批量SQL执行
工具类
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.util.StringUtils;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import marchsoft.exception.BadRequestException;
import javax.sql.DataSource;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.sql.*;
import java.util.List;
/**
* @author /
*/
@Slf4j
public class SqlUtils {
public static final String COLON = ":";
/**
* 获取数据源
*
* @param jdbcUrl /
* @param userName /
* @param password /
* @return DataSource
*/
private static DataSource getDataSource(String jdbcUrl, String userName, String password) {
DruidDataSource druidDataSource = new DruidDataSource();
String className;
try {
// 为 url 选择一个适当的驱动
className = DriverManager.getDriver(jdbcUrl.trim()).getClass().getName();
} catch (SQLException e) {
throw new BadRequestException("【测试连接数据库失败】Get class name error: =" + jdbcUrl);
}
if (StringUtils.isEmpty(className)) {
// 如果找不到,从自定义的驱动中查找
DataTypeEnum dataTypeEnum = DataTypeEnum.urlOf(jdbcUrl);
if (null == dataTypeEnum) {
throw new BadRequestException("【测试连接数据库失败】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.setBreakAfterAcquireFailure(true);
try {
druidDataSource.init();
} catch (SQLException e) {
log.error("【测试连接数据库失败】Exception during pool initialization", e);
throw new RuntimeException(e.getMessage());
}
return druidDataSource;
}
/**
* 连接数据库
* @param jdbcUrl /
* @param userName /
* @param password /
* @return connection
*/
private static Connection getConnect(String jdbcUrl, String userName, String password) {
DataSource dataSource = getDataSource(jdbcUrl, userName, password);
Connection connection;
try {
connection = dataSource.getConnection();
int timeOut = 5;
if (null == connection || connection.isClosed() || !connection.isValid(timeOut)) {
log.info("【测试连接数据库失败】connection is closed or invalid, retry get connection!");
connection = dataSource.getConnection();
}
} catch (Exception ignored) {
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();
} catch (Exception e) {
log.error(e.getMessage(),e);
log.error("【测试连接数据库失败】connection close error:" + e.getMessage());
}
}
}
public static void closeResult(ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
log.error(e.getMessage(),e);
}
}
}
public static boolean testConnection(String jdbcUrl, String userName, String password) {
Connection connection = null;
try {
connection = getConnect(jdbcUrl, userName, password);
if (null != connection) {
return true;
}
} catch (Exception e) {
log.error("【测试连接数据库失败】Get connection failed:" + e.getMessage());
} finally {
releaseConnection(connection);
}
return false;
}
public static String executeFile(String jdbcUrl, String userName, String password, File sqlFile) {
Connection connection = getConnect(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 /
*/
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 e
*/
private static List<String> readSqlList(File sqlFile) throws Exception {
List<String> sqlList = Lists.newArrayList();
StringBuilder sb = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(
new FileInputStream(sqlFile), StandardCharsets.UTF_8))) {
String tmp;
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());
}
}
return sqlList;
}
}
自定义数据库枚举类
import lombok.extern.slf4j.Slf4j;
/**
* @author /
*/
@Slf4j
@SuppressWarnings({"unchecked","all"})
public enum DataTypeEnum {
/** mysql */
MYSQL("mysql", "mysql", "com.mysql.jdbc.Driver", "`", "`", "'", "'"),
/** oracle */
ORACLE("oracle", "oracle", "oracle.jdbc.driver.OracleDriver", "\"", "\"", "\"", "\""),
/** sql server */
SQLSERVER("sqlserver", "sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "\"", "\"", "\"", "\""),
/** h2 */
H2("h2", "h2", "org.h2.Driver", "`", "`", "\"", "\""),
/** phoenix */
PHOENIX("phoenix", "hbase phoenix", "org.apache.phoenix.jdbc.PhoenixDriver", "", "", "\"", "\""),
/** mongo */
MONGODB("mongo", "mongodb", "mongodb.jdbc.MongoDriver", "`", "`", "\"", "\""),
/** sql4es */
ELASTICSEARCH("sql4es", "elasticsearch", "nl.anchormen.sql4es.jdbc.ESDriver", "", "", "'", "'"),
/** presto */
PRESTO("presto", "presto", "com.facebook.presto.jdbc.PrestoDriver", "", "", "\"", "\""),
/** moonbox */
MOONBOX("moonbox", "moonbox", "moonbox.jdbc.MbDriver", "`", "`", "`", "`"),
/** cassandra */
CASSANDRA("cassandra", "cassandra", "com.github.adejanovski.cassandra.jdbc.CassandraDriver", "", "", "'", "'"),
/** click house */
CLICKHOUSE("clickhouse", "clickhouse", "ru.yandex.clickhouse.ClickHouseDriver", "", "", "\"", "\""),
/** kylin */
KYLIN("kylin", "kylin", "org.apache.kylin.jdbc.Driver", "\"", "\"", "\"", "\""),
/** vertica */
VERTICA("vertica", "vertica", "com.vertica.jdbc.Driver", "", "", "'", "'"),
/** sap */
HANA("sap", "sap hana", "com.sap.db.jdbc.Driver", "", "", "'", "'"),
/** impala */
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 JDBC_URL_PREFIX = "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) {
// 将url的 字符串转换为小写,并删除头尾的空白符
String url = jdbcUrl.toLowerCase().trim();
for (DataTypeEnum dataTypeEnum : values()) {
// 通过判断 url 的开头,找到对应的数据库驱动
if (url.startsWith(JDBC_URL_PREFIX + 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;
}
}
测试:
public Result<Object> testConnect(@RequestBody Database resources){
boolean connect = databaseService.testConnect(resources);
if (!connect){
log.error(StrUtil.format("【测试连接数据库失败 /api/database/test-connect】操作人id:{},测试连接目标,Database:{}"), SecurityUtils.getCurrentUserId(),
resources);
throw new BadRequestException("测试连接数据库失败");
}
log.info(StrUtil.format("【测试数据库连接成功 /api/database/test-connect】操作人id:{},测试连接目标:{}"), SecurityUtils.getCurrentUserId(),
resources);
return Result.success();
}
@Override
public boolean testConnect(Database resources) {
try{
return SqlUtils.testConnection(resources.getJdbcUrl(), resources.getUserName(), resources.getPwd());
}catch (Exception e){
log.error(e.getMessage());
return false;
}
}