sql refactoring
This commit is contained in:
parent
41119a683d
commit
ed61bf6e61
13 changed files with 201 additions and 147 deletions
|
|
@ -1,9 +0,0 @@
|
||||||
package org.zhdev.sql;
|
|
||||||
|
|
||||||
import org.zhdev.util.SqlUtils;
|
|
||||||
|
|
||||||
public final class H2SqlConnection extends AbstractSqlConnection {
|
|
||||||
public H2SqlConnection(String path, String username, String password) {
|
|
||||||
super(SqlUtils.createH2Connection(path, username, password));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
package org.zhdev.sql;
|
|
||||||
|
|
||||||
import org.zhdev.util.SqlUtils;
|
|
||||||
|
|
||||||
public final class MySqlConnection extends AbstractSqlConnection {
|
|
||||||
public MySqlConnection(String address, String dbname, String username, String password, boolean ssl) {
|
|
||||||
super(SqlUtils.createMySqlConnection(address, dbname, username, password, ssl));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
package org.zhdev.sql;
|
|
||||||
|
|
||||||
import org.zhdev.util.CheckedFunction;
|
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.ResultSet;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public final class SqlAdapter implements AutoCloseable {
|
|
||||||
private SqlConnection connection = SqlConnection.NOT_ESTABLISHED;
|
|
||||||
|
|
||||||
public SqlConnection getConnection() {
|
|
||||||
return connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setConnection(SqlConnection connection) {
|
|
||||||
Objects.requireNonNull(connection, "connection");
|
|
||||||
this.connection = connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T prepareStatement(CheckedFunction<PreparedStatement, T, SQLException> function, String query, Object... args) throws SqlException {
|
|
||||||
try (PreparedStatement statement = connection.prepareStatement(query)) {
|
|
||||||
for (int i = 0, j = 1; i < args.length; i++, j++) {
|
|
||||||
statement.setObject(j, args[i]);
|
|
||||||
}
|
|
||||||
return function.apply(statement);
|
|
||||||
} catch (SQLException e) {
|
|
||||||
throw new SqlException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public <T> T executeQuery(CheckedFunction<ResultSet, T, SQLException> function, String query, Object... args) throws SqlException {
|
|
||||||
return prepareStatement(statement -> {
|
|
||||||
try (ResultSet set = statement.executeQuery()) {
|
|
||||||
return function.apply(set);
|
|
||||||
}
|
|
||||||
}, query, args);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isClosed() {
|
|
||||||
return connection.isClosed();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void close() {
|
|
||||||
if (connection.isClosed()) {
|
|
||||||
connection.close();
|
|
||||||
}
|
|
||||||
connection = SqlConnection.CLOSED;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
package org.zhdev.sql;
|
|
||||||
|
|
||||||
import java.sql.PreparedStatement;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
|
|
||||||
public interface SqlConnection extends AutoCloseable {
|
|
||||||
SqlConnection NOT_ESTABLISHED = new SqlConnection() {
|
|
||||||
@Override
|
|
||||||
public PreparedStatement prepareStatement(String query) {
|
|
||||||
throw new SqlException("Connection not established");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isClosed() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
throw new SqlException("Connection not established");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
SqlConnection CLOSED = new SqlConnection() {
|
|
||||||
@Override
|
|
||||||
public PreparedStatement prepareStatement(String query) {
|
|
||||||
throw new SqlException("Connection closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isClosed() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
throw new SqlException("Connection closed");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
PreparedStatement prepareStatement(String query) throws SQLException;
|
|
||||||
|
|
||||||
boolean isClosed();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void close();
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
package org.zhdev.sql;
|
|
||||||
|
|
||||||
import org.zhdev.util.SqlUtils;
|
|
||||||
|
|
||||||
public class SqliteConnection extends AbstractSqlConnection {
|
|
||||||
public SqliteConnection(String path) {
|
|
||||||
super(SqlUtils.createSqliteConnection(path));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
package org.zhdev.varioutil.sql;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
abstract class AbstractProvider implements ConnectionProvider {
|
||||||
|
private final Connection connection;
|
||||||
|
|
||||||
|
AbstractProvider(Connection connection) {
|
||||||
|
this.connection = connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection() {
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isClosed() {
|
||||||
|
try {
|
||||||
|
return connection.isClosed();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new SqlException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
9
db/src/main/java/org/zhdev/varioutil/sql/H2Provider.java
Normal file
9
db/src/main/java/org/zhdev/varioutil/sql/H2Provider.java
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.zhdev.varioutil.sql;
|
||||||
|
|
||||||
|
import org.zhdev.varioutil.util.SqlUtils;
|
||||||
|
|
||||||
|
public class H2Provider extends AbstractProvider {
|
||||||
|
public H2Provider(String path, String username, String password) {
|
||||||
|
super(SqlUtils.createH2Connection(path, username, password));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.zhdev.varioutil.sql;
|
||||||
|
|
||||||
|
import org.zhdev.varioutil.util.SqlUtils;
|
||||||
|
|
||||||
|
public class MysqlProvider extends AbstractProvider {
|
||||||
|
public MysqlProvider(String address, String dbname, String username, String password, boolean ssl) {
|
||||||
|
super(SqlUtils.createMysqlConnection(address, dbname, username, password, ssl));
|
||||||
|
}
|
||||||
|
}
|
||||||
17
db/src/main/java/org/zhdev/varioutil/sql/NullProvider.java
Normal file
17
db/src/main/java/org/zhdev/varioutil/sql/NullProvider.java
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
package org.zhdev.varioutil.sql;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
|
||||||
|
class NullProvider implements ConnectionProvider {
|
||||||
|
private final String message;
|
||||||
|
|
||||||
|
NullProvider(String message) {
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Connection getConnection() {
|
||||||
|
throw new SqlException(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
64
db/src/main/java/org/zhdev/varioutil/sql/SqlAdapter.java
Normal file
64
db/src/main/java/org/zhdev/varioutil/sql/SqlAdapter.java
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
package org.zhdev.varioutil.sql;
|
||||||
|
|
||||||
|
import org.zhdev.varioutil.util.CheckedFunction;
|
||||||
|
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
public final class SqlAdapter implements AutoCloseable {
|
||||||
|
private ConnectionProvider provider = ConnectionProvider.NOT_ESTABLISHED;
|
||||||
|
|
||||||
|
public void setProvider(ConnectionProvider provider) {
|
||||||
|
Objects.requireNonNull(provider, "provider");
|
||||||
|
this.provider = provider;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void applyArgs(PreparedStatement statement, Object[] args) throws SQLException {
|
||||||
|
for (int i = 0, j = 1; i < args.length; i++, j++) {
|
||||||
|
statement.setObject(j, args[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T prepareStatement(CheckedFunction<PreparedStatement, T, SQLException> function, String query, Object... args) throws SqlException {
|
||||||
|
try (PreparedStatement statement = provider.getConnection().prepareStatement(query)) {
|
||||||
|
applyArgs(statement, args);
|
||||||
|
return function.apply(statement);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new SqlException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T prepareStatement(int autoGeneratedKeys, CheckedFunction<PreparedStatement, T, SQLException> function, String query, Object... args) throws SqlException {
|
||||||
|
try (PreparedStatement statement = provider.getConnection().prepareStatement(query, autoGeneratedKeys)) {
|
||||||
|
applyArgs(statement, args);
|
||||||
|
return function.apply(statement);
|
||||||
|
} catch (SQLException e) {
|
||||||
|
throw new SqlException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public <T> T executeQuery(CheckedFunction<ResultSet, T, SQLException> function, String query, Object... args) throws SqlException {
|
||||||
|
return prepareStatement(statement -> {
|
||||||
|
try (ResultSet set = statement.executeQuery()) {
|
||||||
|
return function.apply(set);
|
||||||
|
}
|
||||||
|
}, query, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isClosed() {
|
||||||
|
return provider.isClosed();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
if (!provider.isClosed()) {
|
||||||
|
provider.close();
|
||||||
|
}
|
||||||
|
provider = ConnectionProvider.CLOSED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
package org.zhdev.sql;
|
package org.zhdev.varioutil.sql;
|
||||||
|
|
||||||
public class SqlException extends RuntimeException {
|
public class SqlException extends RuntimeException {
|
||||||
public SqlException() {
|
public SqlException() {
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
package org.zhdev.varioutil.sql;
|
||||||
|
|
||||||
|
import org.zhdev.varioutil.util.SqlUtils;
|
||||||
|
|
||||||
|
public class SqliteProvider extends AbstractProvider {
|
||||||
|
public SqliteProvider(String path) {
|
||||||
|
super(SqlUtils.createSqliteConnection(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,35 +1,34 @@
|
||||||
package org.zhdev.util;
|
package org.zhdev.varioutil.util;
|
||||||
|
|
||||||
import org.zhdev.sql.SqlException;
|
import org.zhdev.varioutil.sql.SqlException;
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.sql.*;
|
import java.sql.*;
|
||||||
|
|
||||||
public class SqlUtils {
|
public class SqlUtils {
|
||||||
public static final char[] ESCAPE_CHARS = {'%', '_', '[', ']', '^'};
|
public static final char[] ESCAPE_CHARS = {'%', '_', '[', ']', '^'};
|
||||||
|
|
||||||
public static Connection createMySqlConnection(String address, String dbname, String username, String password, boolean ssl) throws SqlException {
|
private static boolean sqlite;
|
||||||
|
private static boolean h2;
|
||||||
|
private static boolean mysql;
|
||||||
|
|
||||||
|
public static Connection createMysqlConnection(String address, String dbname, String username, String password, boolean ssl) throws SqlException {
|
||||||
try {
|
try {
|
||||||
try {
|
|
||||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
Class.forName("com.mysql.jdbc.Driver");
|
|
||||||
}
|
|
||||||
if (!address.contains(":")) {
|
if (!address.contains(":")) {
|
||||||
address = address + ":3306";
|
address = address + ":3306";
|
||||||
}
|
}
|
||||||
return DriverManager.getConnection("jdbc:mysql://" + address + '/' + dbname + "?useSSL=" + ssl, username, password);
|
return DriverManager.getConnection("jdbc:mysql://" + address + '/' + dbname + "?useSSL=" + ssl, username, password);
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new SqlException(e);
|
throw new SqlException(e);
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new SqlException("No suitable driver");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Connection createH2Connection(String path, String username, String password) throws SqlException {
|
public static Connection createH2Connection(String path, String username, String password) throws SqlException {
|
||||||
try {
|
try {
|
||||||
Class.forName("org.h2.Driver");
|
DriverManager.registerDriver(new org.h2.Driver());
|
||||||
Connection connection;
|
Connection connection;
|
||||||
if (username != null) {
|
if (username != null) {
|
||||||
connection = DriverManager.getConnection("jdbc:h2:./" + path + ";mode=MySQL;AUTO_SERVER=TRUE", username, password);
|
connection = DriverManager.getConnection("jdbc:h2:./" + path + ";mode=MySQL;AUTO_SERVER=TRUE", username, password);
|
||||||
|
|
@ -37,29 +36,29 @@ public class SqlUtils {
|
||||||
connection = DriverManager.getConnection("jdbc:h2:./" + path + ";mode=MySQL;AUTO_SERVER=TRUE", "sa", "");
|
connection = DriverManager.getConnection("jdbc:h2:./" + path + ";mode=MySQL;AUTO_SERVER=TRUE", "sa", "");
|
||||||
}
|
}
|
||||||
return connection;
|
return connection;
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (NoClassDefFoundError e) {
|
||||||
throw new SqlException("No suitable driver");
|
throw new SqlException("No suitable driver");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
throw new SqlException(e);
|
throw new SqlException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Connection createSqliteConnection(String path) throws SqlException {
|
public static Connection createSqliteConnection(String pathname) throws SqlException {
|
||||||
File file = new File(path);
|
Path path = Paths.get(pathname);
|
||||||
if (!file.exists()) {
|
if (!Files.exists(path)) {
|
||||||
File parent = file.getParentFile();
|
Path parent = path.getParent();
|
||||||
if (parent != null) {
|
|
||||||
parent.mkdirs();
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
file.createNewFile();
|
if (parent != null) {
|
||||||
|
Files.createDirectories(parent);
|
||||||
|
}
|
||||||
|
Files.createFile(path);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new SqlException(e);
|
throw new SqlException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Class.forName("org.sqlite.JDBC");
|
Class.forName("org.sqlite.JDBC");
|
||||||
return DriverManager.getConnection("jdbc:sqlite:" + file);
|
return DriverManager.getConnection("jdbc:sqlite:" + path);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
throw new SqlException("No suitable driver");
|
throw new SqlException("No suitable driver");
|
||||||
} catch (SQLException e) {
|
} catch (SQLException e) {
|
||||||
|
|
@ -101,4 +100,49 @@ public class SqlUtils {
|
||||||
public static String unescape(String str, String escape) {
|
public static String unescape(String str, String escape) {
|
||||||
return StringUtils.unescape(str, escape, ESCAPE_CHARS);
|
return StringUtils.unescape(str, escape, ESCAPE_CHARS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void initializeH2() {
|
||||||
|
if (h2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
DriverManager.registerDriver(new org.h2.Driver());
|
||||||
|
} catch (NoClassDefFoundError | SQLException ignored) {}
|
||||||
|
|
||||||
|
h2 = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initializeMySql() {
|
||||||
|
if (mysql) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
try {
|
||||||
|
DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
|
||||||
|
} catch (NoClassDefFoundError e) {
|
||||||
|
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
|
||||||
|
}
|
||||||
|
} catch (NoClassDefFoundError | SQLException ignored) {}
|
||||||
|
|
||||||
|
mysql = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initializeSqlite() {
|
||||||
|
if (sqlite) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
DriverManager.registerDriver(new org.sqlite.JDBC());
|
||||||
|
} catch (NoClassDefFoundError | SQLException ignored) {}
|
||||||
|
|
||||||
|
sqlite = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
initializeH2();
|
||||||
|
initializeMySql();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue