更换至 Gradle
This commit is contained in:
11
src/main/scala/me/skymc/taboolib/mysql/IColumn.java
Normal file
11
src/main/scala/me/skymc/taboolib/mysql/IColumn.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package me.skymc.taboolib.mysql;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-12-08 13:46
|
||||
*/
|
||||
public abstract class IColumn {
|
||||
|
||||
abstract public String convertToCommand();
|
||||
|
||||
}
|
||||
42
src/main/scala/me/skymc/taboolib/mysql/IHost.java
Normal file
42
src/main/scala/me/skymc/taboolib/mysql/IHost.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package me.skymc.taboolib.mysql;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-14 19:07
|
||||
*/
|
||||
public abstract class IHost {
|
||||
|
||||
private Plugin plugin;
|
||||
private boolean autoClose;
|
||||
|
||||
public IHost(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public IHost(Plugin plugin, boolean autoClose) {
|
||||
this.plugin = plugin;
|
||||
this.autoClose = autoClose;
|
||||
}
|
||||
|
||||
public Plugin getPlugin() {
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public void setPlugin(Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
|
||||
public boolean isAutoClose() {
|
||||
return autoClose;
|
||||
}
|
||||
|
||||
public void setAutoClose(boolean autoClose) {
|
||||
this.autoClose = autoClose;
|
||||
}
|
||||
|
||||
abstract public String getConnectionUrl();
|
||||
|
||||
abstract public String getConnectionUrlSimple();
|
||||
}
|
||||
133
src/main/scala/me/skymc/taboolib/mysql/builder/SQLColumn.java
Normal file
133
src/main/scala/me/skymc/taboolib/mysql/builder/SQLColumn.java
Normal file
@@ -0,0 +1,133 @@
|
||||
package me.skymc.taboolib.mysql.builder;
|
||||
|
||||
import com.ilummc.tlib.util.Strings;
|
||||
import me.skymc.taboolib.mysql.IColumn;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-14 19:09
|
||||
*/
|
||||
public class SQLColumn extends IColumn {
|
||||
|
||||
public static final SQLColumn PRIMARY_KEY_ID = new SQLColumn(SQLColumnType.INT, "id", SQLColumnOption.NOTNULL, SQLColumnOption.PRIMARY_KEY, SQLColumnOption.AUTO_INCREMENT);
|
||||
|
||||
private SQLColumnType columnType;
|
||||
private int m;
|
||||
private int d;
|
||||
|
||||
private String columnName;
|
||||
private Object defaultValue;
|
||||
|
||||
private SQLColumnOption[] columnOptions;
|
||||
|
||||
/**
|
||||
* 文本 类型常用构造器
|
||||
* new SQLColumn(SQLColumnType.TEXT, "username");
|
||||
*/
|
||||
public SQLColumn(SQLColumnType columnType, String columnName) {
|
||||
this(columnType, 0, 0, columnName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* CHAR 类型常用构造器
|
||||
*
|
||||
* @param columnType
|
||||
* @param columnName
|
||||
*/
|
||||
public SQLColumn(SQLColumnType columnType, int m, String columnName) {
|
||||
this(columnType, m, 0, columnName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主键 类型常用构造器
|
||||
* new SQLColumn(SQLColumnType.TEXT, "username", SQLColumnOption.PRIMARY_KEY, SQLColumnOption.AUTO_INCREMENT);
|
||||
*/
|
||||
public SQLColumn(SQLColumnType columnType, String columnName, SQLColumnOption... columnOptions) {
|
||||
this(columnType, 0, 0, columnName, null, columnOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据 类型常用构造器
|
||||
* new SQLColumn(SQLColumnType.TEXT, "player_group", "PLAYER");
|
||||
*/
|
||||
public SQLColumn(SQLColumnType columnType, String columnName, Object defaultValue) {
|
||||
this(columnType, 0, 0, columnName, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 完整构造器
|
||||
*
|
||||
* @param columnType 类型
|
||||
* @param m m值
|
||||
* @param d d值
|
||||
* @param columnName 名称
|
||||
* @param defaultValue 默认值
|
||||
* @param columnOptions 属性值
|
||||
*/
|
||||
public SQLColumn(SQLColumnType columnType, int m, int d, String columnName, Object defaultValue, SQLColumnOption... columnOptions) {
|
||||
this.columnType = columnType;
|
||||
this.m = m;
|
||||
this.d = d;
|
||||
this.columnName = columnName;
|
||||
this.defaultValue = defaultValue;
|
||||
this.columnOptions = columnOptions;
|
||||
}
|
||||
|
||||
public SQLColumn m(int m) {
|
||||
this.m = m;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SQLColumn d(int d) {
|
||||
this.d = d;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SQLColumn defaultValue(Object defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SQLColumn columnOptions(SQLColumnOption... columnOptions) {
|
||||
this.columnOptions = columnOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToCommand() {
|
||||
if (this.m == 0 && this.d == 0) {
|
||||
return Strings.replaceWithOrder("`{0}` {1}{2}", columnName, columnType.name().toLowerCase(), convertToOptions());
|
||||
} else if (this.d == 0) {
|
||||
return Strings.replaceWithOrder("`{0}` {1}({2}){3}", columnName, columnType.name().toLowerCase(), m, convertToOptions());
|
||||
} else {
|
||||
return Strings.replaceWithOrder("`{0}` {1}({2},{3}){4}", columnName, columnType.name().toLowerCase(), m, d, convertToOptions());
|
||||
}
|
||||
}
|
||||
|
||||
private String convertToOptions() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Arrays.stream(columnOptions).forEach(option -> builder.append(" ").append(option.getText()));
|
||||
if (defaultValue != null) {
|
||||
if (defaultValue instanceof String) {
|
||||
builder.append(" DEFAULT '").append(defaultValue).append("'");
|
||||
} else {
|
||||
builder.append(" DEFAULT ").append(defaultValue);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SQLColumn{" +
|
||||
"columnType=" + columnType +
|
||||
", m=" + m +
|
||||
", d=" + d +
|
||||
", columnName='" + columnName + '\'' +
|
||||
", defaultValue=" + defaultValue +
|
||||
", columnOptions=" + Arrays.toString(columnOptions) +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package me.skymc.taboolib.mysql.builder;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-14 21:43
|
||||
*/
|
||||
public enum SQLColumnOption {
|
||||
|
||||
/**
|
||||
* 不能为空
|
||||
*/
|
||||
NOTNULL("NOT NULL"),
|
||||
|
||||
/**
|
||||
* 唯一
|
||||
*/
|
||||
UNIQUE_KEY("UNIQUE KEY"),
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
PRIMARY_KEY("PRIMARY KEY"),
|
||||
|
||||
/**
|
||||
* 递增
|
||||
*/
|
||||
AUTO_INCREMENT("AUTO_INCREMENT");
|
||||
|
||||
String text;
|
||||
|
||||
SQLColumnOption(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
package me.skymc.taboolib.mysql.builder;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-14 19:13
|
||||
*/
|
||||
public enum SQLColumnType {
|
||||
|
||||
/**
|
||||
* 有符号值:-128 到127(- 27 到27 - 1)
|
||||
* 无符号值:0到255(0 到28 - 1) 1个字节
|
||||
*/
|
||||
TINYINT,
|
||||
|
||||
/**
|
||||
* 有符号值:-32768 到32767(- 215 到215 - 1)
|
||||
* 无符号值:0到65535(0 到21 6 - 1) 2个字节
|
||||
*/
|
||||
SMALLINT,
|
||||
|
||||
/**
|
||||
* 有符号值:-8388608 到8388607(- 22 3 到22 3 - 1 )
|
||||
* 无符号值:0到16777215(0 到22 4 - 1) 3个字节
|
||||
*/
|
||||
MEDIUMINT,
|
||||
|
||||
/**
|
||||
* 有符号值:-2147683648 到2147683647(- 231 到231- 1)
|
||||
* 无符号值:0到4294967295(0 到232 - 1) 4个字节
|
||||
*/
|
||||
INT,
|
||||
|
||||
/**
|
||||
* 有符号值:-9223372036854775808 到9223373036854775807(- 263到263-1)
|
||||
* 无符号值:0到18446744073709551615(0到264 – 1) 8个字节
|
||||
*/
|
||||
BIGINT,
|
||||
|
||||
/**
|
||||
* 最小非零值:±1.175494351e - 38
|
||||
*/
|
||||
FLOAT,
|
||||
|
||||
/**
|
||||
* 最小非零值:±2.2250738585072014e - 308
|
||||
*/
|
||||
DOUBLE,
|
||||
|
||||
/**
|
||||
* 可变:其值的范围依赖于m 和d
|
||||
*/
|
||||
DECIMAL,
|
||||
|
||||
/**
|
||||
* 定长:磁盘空间比较浪费,但是效率高,确定数据长度都一样,就使用定长
|
||||
* 比如:电话号码,身份证号
|
||||
* 最长可取255
|
||||
*/
|
||||
CHAR,
|
||||
|
||||
/**
|
||||
* 边长:比较节省空间,但是效率低,数据不能确定长度(不同数据长度有变化)
|
||||
* 比如:地址
|
||||
* 最长可取65535
|
||||
*/
|
||||
VARCHAR,
|
||||
|
||||
/**
|
||||
* 0~255字节值的长度+2字节
|
||||
*/
|
||||
TINYTEXT,
|
||||
|
||||
/**
|
||||
* 0~65535字节值的长度+2字节
|
||||
*/
|
||||
TEXT,
|
||||
|
||||
/**
|
||||
* 0~167772150字节值的长度+3字节
|
||||
*/
|
||||
MEDIUMTEXT,
|
||||
|
||||
/**
|
||||
* 0~4294967295字节值的长度+4字节
|
||||
*/
|
||||
LONGTEXT,
|
||||
|
||||
/**
|
||||
* 字节数为M,允许长度为0~M的定长二进制字符串
|
||||
*/
|
||||
BINARY,
|
||||
|
||||
/**
|
||||
* 允许长度为0~M的变长二进制字符串,字节数为值的长度加1
|
||||
*/
|
||||
VARBINARY,
|
||||
|
||||
/**
|
||||
* M位二进制数据,M最大值为64
|
||||
*/
|
||||
BIT,
|
||||
|
||||
/**
|
||||
* 可变长二进制数据,最多255个字节
|
||||
*/
|
||||
TINYBLOB,
|
||||
|
||||
/**
|
||||
* 可变长二进制数据,最多2的16次方-1个字节
|
||||
*/
|
||||
BLOB,
|
||||
|
||||
/**
|
||||
* 可变长二进制数据,最多2的24次方-1个字节
|
||||
*/
|
||||
MEDIUMBLOB,
|
||||
|
||||
/**
|
||||
* 可变长二进制数据,最多2的32次方-1个字节
|
||||
*/
|
||||
LONGBLOB
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package me.skymc.taboolib.mysql.builder;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-06-22 16:38
|
||||
*/
|
||||
public class SQLExecutor {
|
||||
|
||||
public static void freeConnection(Connection connection) {
|
||||
try {
|
||||
if (connection != null) {
|
||||
connection.close();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
public static void freeStatement(PreparedStatement preparedStatement, ResultSet resultSet) {
|
||||
try {
|
||||
if (preparedStatement != null) {
|
||||
preparedStatement.close();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
try {
|
||||
if (resultSet != null) {
|
||||
resultSet.close();
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
}
|
||||
}
|
||||
127
src/main/scala/me/skymc/taboolib/mysql/builder/SQLHost.java
Normal file
127
src/main/scala/me/skymc/taboolib/mysql/builder/SQLHost.java
Normal file
@@ -0,0 +1,127 @@
|
||||
package me.skymc.taboolib.mysql.builder;
|
||||
|
||||
import com.ilummc.tlib.util.Strings;
|
||||
import me.skymc.taboolib.mysql.IHost;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-14 19:01
|
||||
*/
|
||||
public class SQLHost extends IHost {
|
||||
|
||||
private String host;
|
||||
private String user;
|
||||
private String port;
|
||||
private String password;
|
||||
private String database;
|
||||
private List<String> flags = ArrayUtils.asList("characterEncoding=utf-8", "useSSL=false");
|
||||
|
||||
public SQLHost(ConfigurationSection section, Plugin plugin) {
|
||||
this(section, plugin, false);
|
||||
}
|
||||
|
||||
public SQLHost(ConfigurationSection section, Plugin plugin, boolean autoClose) {
|
||||
this(section.getString("host", "localhost"), section.getString("user", "root"), section.getString("port", "3306"), section.getString("password", ""), section.getString("database", "test"), plugin);
|
||||
}
|
||||
|
||||
public SQLHost(String host, int port, String user, String password, String database, Plugin plugin) {
|
||||
this(host, user, String.valueOf(port), password, database, plugin, false);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public SQLHost(String host, String user, String port, String password, String database, Plugin plugin) {
|
||||
this(host, user, port, password, database, plugin, false);
|
||||
}
|
||||
|
||||
public SQLHost(String host, String user, String port, String password, String database, Plugin plugin, boolean autoClose) {
|
||||
super(plugin, autoClose);
|
||||
this.host = host;
|
||||
this.user = user;
|
||||
this.port = port;
|
||||
this.password = password;
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionUrl() {
|
||||
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}" + getFlagsInUrl(), this.host, this.port, this.database);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionUrlSimple() {
|
||||
return Strings.replaceWithOrder("jdbc:mysql://{0}:{1}/{2}", this.host, this.port, this.database);
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public String getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public String getDatabase() {
|
||||
return database;
|
||||
}
|
||||
|
||||
public List<String> getFlags() {
|
||||
return flags;
|
||||
}
|
||||
|
||||
public String getFlagsInUrl() {
|
||||
if (flags.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
String collect = flags.stream().map(f -> f + "&").collect(Collectors.joining());
|
||||
return "?" + collect.substring(0, collect.length() - 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof SQLHost)) {
|
||||
return false;
|
||||
}
|
||||
SQLHost sqlHost = (SQLHost) o;
|
||||
return Objects.equals(getHost(), sqlHost.getHost()) &&
|
||||
Objects.equals(getUser(), sqlHost.getUser()) &&
|
||||
Objects.equals(getPort(), sqlHost.getPort()) &&
|
||||
Objects.equals(getPassword(), sqlHost.getPassword()) &&
|
||||
Objects.equals(getDatabase(), sqlHost.getDatabase()) &&
|
||||
Objects.equals(getFlags(), sqlHost.getFlags());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getHost(), getUser(), getPort(), getPassword(), getDatabase(), getFlags());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SQLHost{" +
|
||||
"host='" + host + '\'' +
|
||||
", user='" + user + '\'' +
|
||||
", port='" + port + '\'' +
|
||||
", password='" + password + '\'' +
|
||||
", database='" + database + '\'' +
|
||||
", flags=" + flags +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
100
src/main/scala/me/skymc/taboolib/mysql/builder/SQLTable.java
Normal file
100
src/main/scala/me/skymc/taboolib/mysql/builder/SQLTable.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package me.skymc.taboolib.mysql.builder;
|
||||
|
||||
import com.ilummc.tlib.util.Strings;
|
||||
import me.skymc.taboolib.mysql.IColumn;
|
||||
import me.skymc.taboolib.mysql.builder.query.RunnableQuery;
|
||||
import me.skymc.taboolib.mysql.builder.query.RunnableUpdate;
|
||||
import me.skymc.taboolib.string.ArrayUtils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-14 19:07
|
||||
*/
|
||||
public class SQLTable {
|
||||
|
||||
private String tableName;
|
||||
private IColumn[] columns;
|
||||
|
||||
public SQLTable(String tableName) {
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public SQLTable(String tableName, IColumn... column) {
|
||||
this.tableName = tableName;
|
||||
this.columns = column;
|
||||
}
|
||||
|
||||
public SQLTable(String tableName, SQLColumn... column) {
|
||||
this.tableName = tableName;
|
||||
this.columns = column;
|
||||
}
|
||||
|
||||
public SQLTable column(IColumn column) {
|
||||
columns = columns == null ? new IColumn[] {column} : ArrayUtils.arrayAppend(columns, column);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public SQLTable addColumn(SQLColumn sqlColumn) {
|
||||
columns = columns == null ? new SQLColumn[] {sqlColumn} : ArrayUtils.arrayAppend(columns, sqlColumn);
|
||||
return this;
|
||||
}
|
||||
|
||||
public String createQuery() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Arrays.stream(columns).forEach(sqlColumn -> builder.append(sqlColumn.convertToCommand()).append(", "));
|
||||
return Strings.replaceWithOrder("create table if not exists `{0}` ({1})", tableName, builder.substring(0, builder.length() - 2));
|
||||
}
|
||||
|
||||
public String deleteQuery() {
|
||||
return Strings.replaceWithOrder("drop table if exists `{0}`" + tableName);
|
||||
}
|
||||
|
||||
public String cleanQuery() {
|
||||
return Strings.replaceWithOrder("delete from `{0}`" + tableName);
|
||||
}
|
||||
|
||||
public String truncateQuery() {
|
||||
return Strings.replaceWithOrder("truncate table `{0}`", tableName);
|
||||
}
|
||||
|
||||
public RunnableQuery executeQuery(String query) {
|
||||
return new RunnableQuery(query);
|
||||
}
|
||||
|
||||
public RunnableQuery executeSelect() {
|
||||
return executeQuery("select * from " + tableName);
|
||||
}
|
||||
|
||||
public RunnableQuery executeSelect(String queryWhere) {
|
||||
return executeQuery("select * from " + tableName + " where " + queryWhere);
|
||||
}
|
||||
|
||||
public RunnableUpdate executeInsert(String queryValues) {
|
||||
return executeUpdate("insert into " + tableName + " values(" + queryValues + ")");
|
||||
}
|
||||
|
||||
public RunnableUpdate executeUpdate(String query) {
|
||||
return new RunnableUpdate(query);
|
||||
}
|
||||
|
||||
public RunnableUpdate executeUpdate(String update, String where) {
|
||||
return executeUpdate("update " + tableName + " set " + update + " where " + where);
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public String getTableName() {
|
||||
return tableName;
|
||||
}
|
||||
|
||||
public IColumn[] getColumns() {
|
||||
return columns;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
package me.skymc.taboolib.mysql.builder.query;
|
||||
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import me.skymc.taboolib.mysql.builder.SQLExecutor;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-07-03 21:29
|
||||
*/
|
||||
public class RunnableQuery {
|
||||
|
||||
private DataSource dataSource;
|
||||
private TaskStatement statement;
|
||||
private TaskResult result;
|
||||
private TaskResult resultNext;
|
||||
private Connection connection;
|
||||
private boolean autoClose;
|
||||
private String query;
|
||||
|
||||
public RunnableQuery(String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public RunnableQuery dataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RunnableQuery statement(TaskStatement statement) {
|
||||
this.statement = statement;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RunnableQuery result(TaskResult result) {
|
||||
this.result = result;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RunnableQuery resultNext(TaskResult result) {
|
||||
this.resultNext = result;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RunnableQuery connection(Connection connection) {
|
||||
return connection(connection, false);
|
||||
}
|
||||
|
||||
public RunnableQuery connection(Connection connection, boolean autoClose) {
|
||||
this.connection = connection;
|
||||
this.autoClose = autoClose;
|
||||
return this;
|
||||
}
|
||||
|
||||
public <T> T run(Object def, T translate) {
|
||||
Object object = run(def);
|
||||
return object == null ? def == null ? null : (T) def : (T) object;
|
||||
}
|
||||
|
||||
public Object run() {
|
||||
return run(null);
|
||||
}
|
||||
|
||||
public Object run(Object def) {
|
||||
PreparedStatement preparedStatement = null;
|
||||
ResultSet resultSet = null;
|
||||
if (dataSource != null) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
preparedStatement = connection.prepareStatement(query);
|
||||
if (statement != null) {
|
||||
statement.execute(preparedStatement);
|
||||
}
|
||||
resultSet = preparedStatement.executeQuery();
|
||||
return getResult(resultSet);
|
||||
} catch (Exception e) {
|
||||
printException(e);
|
||||
} finally {
|
||||
SQLExecutor.freeStatement(preparedStatement, resultSet);
|
||||
}
|
||||
} else if (connection != null) {
|
||||
try {
|
||||
preparedStatement = connection.prepareStatement(query);
|
||||
if (statement != null) {
|
||||
statement.execute(preparedStatement);
|
||||
}
|
||||
resultSet = preparedStatement.executeQuery();
|
||||
return getResult(resultSet);
|
||||
} catch (Exception e) {
|
||||
printException(e);
|
||||
} finally {
|
||||
SQLExecutor.freeStatement(preparedStatement, resultSet);
|
||||
if (autoClose) {
|
||||
SQLExecutor.freeConnection(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
return def;
|
||||
}
|
||||
|
||||
private void printException(Exception e) {
|
||||
TLogger.getGlobalLogger().error("An exception occurred in the database. (" + query + ")");
|
||||
TLogger.getGlobalLogger().error("Reason: " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
private Object getResult(ResultSet resultSet) throws SQLException {
|
||||
if (resultNext != null && resultSet.next()) {
|
||||
return resultNext.execute(resultSet);
|
||||
} else if (result != null) {
|
||||
return result.execute(resultSet);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
package me.skymc.taboolib.mysql.builder.query;
|
||||
|
||||
import com.ilummc.tlib.logger.TLogger;
|
||||
import me.skymc.taboolib.mysql.builder.SQLExecutor;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
/**
|
||||
* F
|
||||
*
|
||||
* @Author sky
|
||||
* @Since 2018-07-03 21:29
|
||||
*/
|
||||
public class RunnableUpdate {
|
||||
|
||||
private DataSource dataSource;
|
||||
private TaskStatement statement;
|
||||
private Connection connection;
|
||||
private boolean autoClose;
|
||||
private String query;
|
||||
|
||||
public RunnableUpdate(String query) {
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
public RunnableUpdate dataSource(DataSource dataSource) {
|
||||
this.dataSource = dataSource;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RunnableUpdate statement(TaskStatement task) {
|
||||
this.statement = task;
|
||||
return this;
|
||||
}
|
||||
|
||||
public RunnableUpdate connection(Connection connection) {
|
||||
return connection(connection, false);
|
||||
}
|
||||
|
||||
public RunnableUpdate connection(Connection connection, boolean autoClose) {
|
||||
this.connection = connection;
|
||||
this.autoClose = autoClose;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
PreparedStatement preparedStatement = null;
|
||||
if (dataSource != null) {
|
||||
try (Connection connection = dataSource.getConnection()) {
|
||||
preparedStatement = connection.prepareStatement(query);
|
||||
if (statement != null) {
|
||||
statement.execute(preparedStatement);
|
||||
}
|
||||
preparedStatement.executeUpdate();
|
||||
} catch (Exception e) {
|
||||
printException(e);
|
||||
} finally {
|
||||
SQLExecutor.freeStatement(preparedStatement, null);
|
||||
}
|
||||
} else if (connection != null) {
|
||||
try {
|
||||
preparedStatement = connection.prepareStatement(query);
|
||||
if (statement != null) {
|
||||
statement.execute(preparedStatement);
|
||||
}
|
||||
preparedStatement.executeUpdate();
|
||||
} catch (Exception e) {
|
||||
printException(e);
|
||||
} finally {
|
||||
SQLExecutor.freeStatement(preparedStatement, null);
|
||||
if (autoClose) {
|
||||
SQLExecutor.freeConnection(connection);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void printException(Exception e) {
|
||||
TLogger.getGlobalLogger().error("An exception occurred in the database. (" + query + ")");
|
||||
TLogger.getGlobalLogger().error("Reason: " + e.toString());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package me.skymc.taboolib.mysql.builder.query;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-07-03 22:02
|
||||
*/
|
||||
public interface TaskResult {
|
||||
|
||||
Object execute(ResultSet resultSet) throws SQLException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package me.skymc.taboolib.mysql.builder.query;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-07-03 22:02
|
||||
*/
|
||||
public interface TaskStatement {
|
||||
|
||||
void execute(PreparedStatement preparedStatement) throws SQLException;
|
||||
|
||||
}
|
||||
120
src/main/scala/me/skymc/taboolib/mysql/hikari/HikariHandler.java
Normal file
120
src/main/scala/me/skymc/taboolib/mysql/hikari/HikariHandler.java
Normal file
@@ -0,0 +1,120 @@
|
||||
package me.skymc.taboolib.mysql.hikari;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.ilummc.tlib.resources.TLocale;
|
||||
import com.zaxxer.hikari.HikariConfig;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import me.skymc.taboolib.Main;
|
||||
import me.skymc.taboolib.fileutils.ConfigUtils;
|
||||
import me.skymc.taboolib.mysql.IHost;
|
||||
import me.skymc.taboolib.mysql.builder.SQLHost;
|
||||
import me.skymc.taboolib.mysql.sqlite.SQLiteHost;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-16 21:59
|
||||
*/
|
||||
public class HikariHandler {
|
||||
|
||||
private static ConcurrentHashMap<IHost, MapDataSource> dataSource = new ConcurrentHashMap<>();
|
||||
private static FileConfiguration settings = ConfigUtils.saveDefaultConfig(Main.getInst(), "hikarisettings.yml");
|
||||
|
||||
public static DataSource createDataSource(IHost host) {
|
||||
return createDataSource(host, null);
|
||||
}
|
||||
|
||||
public static HikariDataSource createDataSource(IHost host, HikariConfig hikariConfig) {
|
||||
MapDataSource mapDataSource = dataSource.computeIfAbsent(host, x -> new MapDataSource(x, new HikariDataSource(hikariConfig == null ? createConfig(host) : hikariConfig)));
|
||||
mapDataSource.getActivePlugin().getAndIncrement();
|
||||
if (mapDataSource.getActivePlugin().get() == 1) {
|
||||
TLocale.Logger.info("MYSQL-HIKARI.CREATE-SUCCESS", host.getPlugin().getName(), host.getConnectionUrlSimple());
|
||||
} else {
|
||||
TLocale.Logger.info("MYSQL-HIKARI.CREATE-EXISTS", host.getPlugin().getName(), mapDataSource.getHost().getPlugin().getName());
|
||||
}
|
||||
return mapDataSource.getHikariDataSource();
|
||||
}
|
||||
|
||||
public static void closeDataSourceForce() {
|
||||
Preconditions.checkArgument(Main.isDisable(), "Cannot be invoked when the server is running.");
|
||||
dataSource.values().forEach(x -> x.getHikariDataSource().close());
|
||||
}
|
||||
|
||||
public static void closeDataSource(IHost host) {
|
||||
if (host != null && dataSource.containsKey(host)) {
|
||||
MapDataSource mapDataSource = dataSource.get(host);
|
||||
if (mapDataSource.getActivePlugin().getAndDecrement() <= 1) {
|
||||
mapDataSource.getHikariDataSource().close();
|
||||
dataSource.remove(host);
|
||||
TLocale.Logger.info("MYSQL-HIKARI.CLOSE-SUCCESS", host.getPlugin().getName(), host.getConnectionUrlSimple());
|
||||
} else {
|
||||
TLocale.Logger.info("MYSQL-HIKARI.CLOSE-FAIL", host.getPlugin().getName(), String.valueOf(mapDataSource.getActivePlugin().get()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static HikariConfig createConfig(IHost host) {
|
||||
HikariConfig config = new HikariConfig();
|
||||
config.setJdbcUrl(host.getConnectionUrl());
|
||||
if (host instanceof SQLHost) {
|
||||
config.setDriverClassName(settings.getString("DefaultSettings.DriverClassName", "com.mysql.jdbc.Driver"));
|
||||
config.setUsername(((SQLHost) host).getUser());
|
||||
config.setPassword(((SQLHost) host).getPassword());
|
||||
} else if (host instanceof SQLiteHost) {
|
||||
config.setDriverClassName("org.sqlite.JDBC");
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid host: " + host.getClass().getName());
|
||||
}
|
||||
config.setAutoCommit(settings.getBoolean("DefaultSettings.AutoCommit", true));
|
||||
config.setMinimumIdle(settings.getInt("DefaultSettings.MinimumIdle", 1));
|
||||
config.setMaximumPoolSize(settings.getInt("DefaultSettings.MaximumPoolSize", 10));
|
||||
config.setValidationTimeout(settings.getInt("DefaultSettings.ValidationTimeout", 5000));
|
||||
config.setConnectionTimeout(settings.getInt("DefaultSettings.ConnectionTimeout", 30000));
|
||||
config.setIdleTimeout(settings.getInt("DefaultSettings.IdleTimeout", 600000));
|
||||
config.setMaxLifetime(settings.getInt("DefaultSettings.MaxLifetime", 1800000));
|
||||
if (settings.contains("DefaultSettings.ConnectionTestQuery")) {
|
||||
config.setConnectionTestQuery(settings.getString("DefaultSettings.ConnectionTestQuery"));
|
||||
}
|
||||
if (settings.contains("DefaultSettings.DataSourceProperty")) {
|
||||
settings.getConfigurationSection("DefaultSettings.DataSourceProperty").getKeys(false).forEach(key -> config.addDataSourceProperty(key, settings.getString("DefaultSettings.DataSourceProperty." + key)));
|
||||
}
|
||||
return config;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static DataSource createDataSource(SQLHost host) {
|
||||
return createDataSource((IHost) host, null);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static HikariConfig createConfig(SQLHost host) {
|
||||
return createConfig((IHost) host);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static HikariDataSource createDataSource(SQLHost host, HikariConfig hikariConfig) {
|
||||
return createDataSource((IHost) host, hikariConfig);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static void closeDataSource(SQLHost host) {
|
||||
closeDataSource((IHost) host);
|
||||
}
|
||||
|
||||
// *********************************
|
||||
//
|
||||
// Getter and Setter
|
||||
//
|
||||
// *********************************
|
||||
|
||||
public static ConcurrentHashMap<IHost, MapDataSource> getDataSource() {
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
public static FileConfiguration getSettings() {
|
||||
return settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package me.skymc.taboolib.mysql.hikari;
|
||||
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import me.skymc.taboolib.mysql.IHost;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-17 23:47
|
||||
*/
|
||||
public class MapDataSource {
|
||||
|
||||
private IHost host;
|
||||
private AtomicInteger activePlugin;
|
||||
private HikariDataSource hikariDataSource;
|
||||
|
||||
MapDataSource(IHost host, HikariDataSource hikariDataSource) {
|
||||
this.host = host;
|
||||
this.activePlugin = new AtomicInteger();
|
||||
this.hikariDataSource = hikariDataSource;
|
||||
}
|
||||
|
||||
public IHost getHost() {
|
||||
return host;
|
||||
}
|
||||
|
||||
public AtomicInteger getActivePlugin() {
|
||||
return activePlugin;
|
||||
}
|
||||
|
||||
public HikariDataSource getHikariDataSource() {
|
||||
return hikariDataSource;
|
||||
}
|
||||
}
|
||||
132
src/main/scala/me/skymc/taboolib/mysql/sqlite/SQLiteColumn.java
Normal file
132
src/main/scala/me/skymc/taboolib/mysql/sqlite/SQLiteColumn.java
Normal file
@@ -0,0 +1,132 @@
|
||||
package me.skymc.taboolib.mysql.sqlite;
|
||||
|
||||
import com.ilummc.tlib.util.Strings;
|
||||
import me.skymc.taboolib.mysql.IColumn;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-14 19:09
|
||||
*/
|
||||
public class SQLiteColumn extends IColumn {
|
||||
|
||||
public static final SQLiteColumn PRIMARY_KEY_ID = new SQLiteColumn(SQLiteColumnType.INTEGER, "id", SQLiteColumnOption.NOTNULL, SQLiteColumnOption.PRIMARY_KEY, SQLiteColumnOption.AUTOINCREMENT);
|
||||
|
||||
private SQLiteColumnType columnType;
|
||||
private int m;
|
||||
private int d;
|
||||
|
||||
private String columnName;
|
||||
private Object defaultValue;
|
||||
|
||||
private SQLiteColumnOption[] columnOptions;
|
||||
|
||||
/**
|
||||
* 文本 类型常用构造器
|
||||
* new SQLColumn(SQLiteColumnType.TEXT, "username");
|
||||
*/
|
||||
public SQLiteColumn(SQLiteColumnType columnType, String columnName) {
|
||||
this(columnType, 0, 0, columnName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* CHAR 类型常用构造器
|
||||
*
|
||||
* @param columnType
|
||||
* @param columnName
|
||||
*/
|
||||
public SQLiteColumn(SQLiteColumnType columnType, int m, String columnName) {
|
||||
this(columnType, m, 0, columnName, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 主键 类型常用构造器
|
||||
* new SQLColumn(SQLiteColumnType.TEXT, "username", SQLiteColumnOption.PRIMARY_KEY, SQLiteColumnOption.AUTO_INCREMENT);
|
||||
*/
|
||||
public SQLiteColumn(SQLiteColumnType columnType, String columnName, SQLiteColumnOption... columnOptions) {
|
||||
this(columnType, 0, 0, columnName, null, columnOptions);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数据 类型常用构造器
|
||||
* new SQLColumn(SQLiteColumnType.TEXT, "player_group", "PLAYER");
|
||||
*/
|
||||
public SQLiteColumn(SQLiteColumnType columnType, String columnName, Object defaultValue) {
|
||||
this(columnType, 0, 0, columnName, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 完整构造器
|
||||
*
|
||||
* @param columnType 类型
|
||||
* @param m m值
|
||||
* @param d d值
|
||||
* @param columnName 名称
|
||||
* @param defaultValue 默认值
|
||||
* @param columnOptions 属性值
|
||||
*/
|
||||
public SQLiteColumn(SQLiteColumnType columnType, int m, int d, String columnName, Object defaultValue, SQLiteColumnOption... columnOptions) {
|
||||
this.columnType = columnType;
|
||||
this.m = m;
|
||||
this.d = d;
|
||||
this.columnName = columnName;
|
||||
this.defaultValue = defaultValue;
|
||||
this.columnOptions = columnOptions;
|
||||
}
|
||||
|
||||
public SQLiteColumn m(int m) {
|
||||
this.m = m;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SQLiteColumn d(int d) {
|
||||
this.d = d;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SQLiteColumn defaultValue(Object defaultValue) {
|
||||
this.defaultValue = defaultValue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public SQLiteColumn columnOptions(SQLiteColumnOption... columnOptions) {
|
||||
this.columnOptions = columnOptions;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String convertToCommand() {
|
||||
if (this.m == 0 && this.d == 0) {
|
||||
return Strings.replaceWithOrder("`{0}` {1}{2}", columnName, columnType.name().toLowerCase(), convertToOptions());
|
||||
} else if (this.d == 0) {
|
||||
return Strings.replaceWithOrder("`{0}` {1}({2}){3}", columnName, columnType.name().toLowerCase(), m, convertToOptions());
|
||||
} else {
|
||||
return Strings.replaceWithOrder("`{0}` {1}({2},{3}){4}", columnName, columnType.name().toLowerCase(), m, d, convertToOptions());
|
||||
}
|
||||
}
|
||||
|
||||
private String convertToOptions() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
Arrays.stream(columnOptions).forEach(option -> builder.append(" ").append(option.getText()));
|
||||
if (defaultValue != null) {
|
||||
if (defaultValue instanceof String) {
|
||||
builder.append(" DEFAULT '").append(defaultValue).append("'");
|
||||
} else {
|
||||
builder.append(" DEFAULT ").append(defaultValue);
|
||||
}
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SQLiteColumn{" +
|
||||
"columnType=" + columnType +
|
||||
", m=" + m +
|
||||
", d=" + d +
|
||||
", columnName='" + columnName + '\'' +
|
||||
", defaultValue=" + defaultValue +
|
||||
", columnOptions=" + Arrays.toString(columnOptions) +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package me.skymc.taboolib.mysql.sqlite;
|
||||
|
||||
/**
|
||||
* @Author sky
|
||||
* @Since 2018-05-14 21:43
|
||||
*/
|
||||
public enum SQLiteColumnOption {
|
||||
|
||||
/**
|
||||
* 不能为空
|
||||
*/
|
||||
NOTNULL("NOT NULL"),
|
||||
|
||||
/**
|
||||
* 唯一
|
||||
*/
|
||||
UNIQUE("UNIQUE"),
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
PRIMARY_KEY("PRIMARY KEY"),
|
||||
|
||||
/**
|
||||
* 递增
|
||||
*/
|
||||
AUTOINCREMENT("AUTOINCREMENT");
|
||||
|
||||
String text;
|
||||
|
||||
SQLiteColumnOption(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public String getText() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package me.skymc.taboolib.mysql.sqlite;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-12-08 13:28
|
||||
*/
|
||||
public enum SQLiteColumnType {
|
||||
|
||||
NULL,
|
||||
|
||||
/**
|
||||
* 带符号的整数,根据值的大小存储在 1、2、3、4、6 或 8 字节中。
|
||||
*/
|
||||
INTEGER,
|
||||
|
||||
/**
|
||||
* 浮点值,存储为 8 字节的 IEEE 浮点数字。
|
||||
*/
|
||||
REAL,
|
||||
|
||||
/**
|
||||
* 文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。
|
||||
*/
|
||||
TEXT,
|
||||
|
||||
/**
|
||||
* blob 数据,完全根据它的输入存储。
|
||||
*/
|
||||
BLOB,
|
||||
|
||||
/**
|
||||
* 数字自动转换
|
||||
*/
|
||||
NUMERIC
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package me.skymc.taboolib.mysql.sqlite;
|
||||
|
||||
import me.skymc.taboolib.mysql.IHost;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* @Author 坏黑
|
||||
* @Since 2018-12-08 12:58
|
||||
*/
|
||||
public class SQLiteHost extends IHost {
|
||||
|
||||
private final File file;
|
||||
|
||||
public SQLiteHost(File file, Plugin plugin) {
|
||||
super(plugin);
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public SQLiteHost(File file, Plugin plugin, boolean autoClose) {
|
||||
super(plugin, autoClose);
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionUrl() {
|
||||
return "jdbc:sqlite:" + file.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getConnectionUrlSimple() {
|
||||
return "jdbc:sqlite:" + file.getPath();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (!(o instanceof SQLiteHost)) {
|
||||
return false;
|
||||
}
|
||||
SQLiteHost that = (SQLiteHost) o;
|
||||
return Objects.equals(getFile(), that.getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(getFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "SQLiteHost{" +
|
||||
"file=" + file +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user