mirror of
https://e.coding.net/circlecloud/YumCore.git
synced 2024-12-25 07:08:52 +00:00
feat: 添加数据库基本操作
Signed-off-by: 502647092 <admin@yumc.pw>
This commit is contained in:
parent
c977885b82
commit
71b8f56e1e
503
src/main/java/pw/yumc/YumCore/sql/DataBase.java
Normal file
503
src/main/java/pw/yumc/YumCore/sql/DataBase.java
Normal file
@ -0,0 +1,503 @@
|
||||
package pw.yumc.YumCore.sql;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import pw.yumc.YumCore.bukkit.Log;
|
||||
import pw.yumc.YumCore.sql.core.DataBaseCore;
|
||||
import pw.yumc.YumCore.sql.core.KeyValue;
|
||||
import pw.yumc.YumCore.sql.core.MySQLCore;
|
||||
import pw.yumc.YumCore.sql.core.SQLiteCore;
|
||||
|
||||
/**
|
||||
* 数据库管理类
|
||||
*
|
||||
* @since 2015年12月14日 下午1:26:06
|
||||
* @author 喵♂呜
|
||||
*
|
||||
*/
|
||||
public class DataBase {
|
||||
private final DataBaseCore dataBaseCore;
|
||||
|
||||
/**
|
||||
* 初始化数据库管理
|
||||
*
|
||||
* @param core
|
||||
* 数据库核心
|
||||
*/
|
||||
public DataBase(final DataBaseCore core) {
|
||||
this.dataBaseCore = core;
|
||||
}
|
||||
|
||||
public static DataBase create(final Plugin plugin, final ConfigurationSection dbConfig) {
|
||||
final ConfigurationSection cfg = dbConfig.getConfigurationSection("MySQL");
|
||||
if (dbConfig.getString("FileSystem").equalsIgnoreCase("MySQL")) {
|
||||
plugin.getLogger().info("已启用MySQL保存数据,开始连接数据库...");
|
||||
return new DataBase(new MySQLCore(cfg));
|
||||
}
|
||||
return new DataBase(new SQLiteCore(plugin, cfg));
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭数据库连接
|
||||
*
|
||||
* @return 是否关闭成功
|
||||
*/
|
||||
public boolean close() {
|
||||
try {
|
||||
this.dataBaseCore.getConnection().close();
|
||||
return true;
|
||||
} catch (final SQLException e) {
|
||||
Log.debug("数据库链接关闭失败!", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 复制当前数据核心的数据库到指定的数据库
|
||||
* 此方法将不会删除当前数据库原有数据
|
||||
* 此方法可能花费较长的时间
|
||||
*
|
||||
* 注意: 当前方法将不会创建表在新的数据库内 需要自行创建数据表
|
||||
*
|
||||
* @param db
|
||||
* 接受数据的数据库核心
|
||||
* @return 是否转换成功
|
||||
*/
|
||||
public boolean copyTo(final DataBaseCore db) {
|
||||
try {
|
||||
final String src = this.dataBaseCore.getConnection().getMetaData().getURL();
|
||||
final String des = db.getConnection().getMetaData().getURL();
|
||||
Log.info("开始从源 " + src + " 复制数据到 " + des + " ...");
|
||||
ResultSet rs = this.dataBaseCore.getConnection().getMetaData().getTables(null, null, "%", null);
|
||||
final List<String> tables = new LinkedList<>();
|
||||
while (rs.next()) {
|
||||
tables.add(rs.getString("TABLE_NAME"));
|
||||
}
|
||||
info("源数据库中有 " + tables.size() + " 张数据表 ...");
|
||||
rs.close();
|
||||
int s = 0;
|
||||
final long start = System.currentTimeMillis();
|
||||
for (final String table : tables) {
|
||||
Log.info("开始复制源数据库中的表 " + table + " ...");
|
||||
if (table.toLowerCase().startsWith("sqlite_autoindex_")) {
|
||||
continue;
|
||||
}
|
||||
Log.info("清空目标数据库中的表 " + table + " ...");
|
||||
db.execute("DELETE FROM " + table);
|
||||
rs = this.dataBaseCore.query("SELECT * FROM " + table);
|
||||
int n = 0;
|
||||
String query = "INSERT INTO " + table + " VALUES (";
|
||||
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
|
||||
query += "?, ";
|
||||
}
|
||||
query = query.substring(0, query.length() - 2) + ")";
|
||||
|
||||
final Connection con = db.getConnection();
|
||||
try {
|
||||
con.setAutoCommit(false);
|
||||
final PreparedStatement ps = con.prepareStatement(query);
|
||||
long time = System.currentTimeMillis();
|
||||
while (rs.next()) {
|
||||
n++;
|
||||
for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
|
||||
ps.setObject(i, rs.getObject(i));
|
||||
}
|
||||
ps.addBatch();
|
||||
if (n % 100 == 0) {
|
||||
try {
|
||||
ps.executeBatch();
|
||||
con.commit();
|
||||
} catch (final SQLException e) {
|
||||
info("#====================================================");
|
||||
info("#数据复制区段(不是ID!) " + (n - 100) + "-" + n + " 出现错误...");
|
||||
info("#错误信息如下: ");
|
||||
e.printStackTrace();
|
||||
info("#====================================================");
|
||||
}
|
||||
}
|
||||
if (System.currentTimeMillis() - time > 500) {
|
||||
info("已复制 " + n + " 条记录...");
|
||||
time = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
s += n;
|
||||
ps.executeBatch();
|
||||
con.commit();
|
||||
info("数据表 " + table + " 复制完成 共 " + n + " 条记录...");
|
||||
} catch (final Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
con.setAutoCommit(true);
|
||||
}
|
||||
rs.close();
|
||||
}
|
||||
info("成功从 " + src + " 复制 " + s + " 条数据到 " + des + " 耗时 " + (System.currentTimeMillis() - start) / 1000 + " 秒...");
|
||||
db.getConnection().close();
|
||||
this.dataBaseCore.getConnection().close();
|
||||
return true;
|
||||
} catch (final SQLException e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据表
|
||||
*
|
||||
* @param tableName
|
||||
* 表名
|
||||
* @param fields
|
||||
* 字段参数
|
||||
* @param Conditions
|
||||
* -附加值
|
||||
* @return 运行结果
|
||||
*/
|
||||
public boolean createTables(final String tableName, final KeyValue fields, final String Conditions) {
|
||||
try {
|
||||
this.dataBaseCore.createTables(tableName, fields, Conditions);
|
||||
return isTableExists(tableName);
|
||||
} catch (final Exception e) {
|
||||
sqlerr("创建数据表 " + tableName + " 异常(内部方法)...", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对数据库表中的记录进行删除操作
|
||||
*
|
||||
* @param tableName
|
||||
* 表名
|
||||
* @param fields
|
||||
* 删除条件
|
||||
* @return 受到影响的数据条目
|
||||
*/
|
||||
public int dbDelete(final String tableName, final KeyValue fields) {
|
||||
final String sql = "DELETE FROM `" + tableName + "` WHERE " + fields.toWhereString();
|
||||
try {
|
||||
return this.dataBaseCore.update(sql);
|
||||
} catch (final Exception e) {
|
||||
sqlerr(sql, e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断数据库某个值是否存在!
|
||||
*
|
||||
* @param tableName
|
||||
* 数据库表名
|
||||
* @param fields
|
||||
* 选择条件
|
||||
* @return 首个符合条件的结果
|
||||
*/
|
||||
public boolean dbExist(final String tableName, final KeyValue fields) {
|
||||
final String sql = "SELECT * FROM " + tableName + " WHERE " + fields.toWhereString();
|
||||
try {
|
||||
return this.dataBaseCore.query(sql).next();
|
||||
} catch (final Exception e) {
|
||||
sqlerr(sql, e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 对数据库表进行插入操作
|
||||
*
|
||||
* @param tabName
|
||||
* 表名
|
||||
* @param fields
|
||||
* 带键值的
|
||||
* @return 受到影响的数据条目
|
||||
*/
|
||||
public int dbInsert(final String tabName, final KeyValue fields) {
|
||||
final String sql = "INSERT INTO `" + tabName + "` " + fields.toInsertString();
|
||||
try {
|
||||
return this.dataBaseCore.update(sql);
|
||||
} catch (final Exception e) {
|
||||
sqlerr(sql, e);
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public <M> List<M> dbSelect(final Class<? extends Model<?>> model, final KeyValue selCondition) {
|
||||
// final List<M> modellist = new ArrayList<>();
|
||||
// final String sql = "SELECT " + toKeys(model) + " FROM `" + model.getAnnotation(Entity.class).name() + "`" + (selCondition == null ? "" : " WHERE " + selCondition.toWhereString());
|
||||
// try {
|
||||
// final ResultSet dbresult = this.dataBaseCore.execute(sql);
|
||||
// while (dbresult.next()) {
|
||||
// final M m = (M) model.newInstance();
|
||||
// final Field[] fields = model.getDeclaredFields();
|
||||
// for (final Field col : fields) {
|
||||
// col.set(m, dbresult.getObject(col.getName()));
|
||||
// }
|
||||
// modellist.add(m);
|
||||
// }
|
||||
// } catch (final InstantiationException e) {
|
||||
// info("模型类实例化失败!");
|
||||
// e.printStackTrace();
|
||||
// } catch (final Exception e) {
|
||||
// sqlerr(sql, e);
|
||||
// }
|
||||
// return modellist;
|
||||
// }
|
||||
|
||||
/**
|
||||
* 对数据库表进行选择操作!
|
||||
*
|
||||
* @param tableName
|
||||
* 数据库表名
|
||||
* @param fields
|
||||
* 读取的字段
|
||||
* @param selCondition
|
||||
* 选择条件
|
||||
* @return 一个含有KeyValue的List(列表)
|
||||
*/
|
||||
public List<KeyValue> dbSelect(final String tableName, final KeyValue fields, final KeyValue selCondition) {
|
||||
final String sql = "SELECT " + fields.toKeys() + " FROM `" + tableName + "`" + (selCondition == null ? "" : " WHERE " + selCondition.toWhereString());
|
||||
final List<KeyValue> kvlist = new ArrayList<>();
|
||||
try {
|
||||
final ResultSet dbresult = this.dataBaseCore.query(sql);
|
||||
while (dbresult.next()) {
|
||||
final KeyValue kv = new KeyValue();
|
||||
for (final String col : fields.getKeys()) {
|
||||
kv.add(col, dbresult.getString(col.toString()));
|
||||
}
|
||||
kvlist.add(kv);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
sqlerr(sql, e);
|
||||
}
|
||||
return kvlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对数据库表进行选择操作!
|
||||
*
|
||||
* @param tableName
|
||||
* 数据库表名
|
||||
* @param selCondition
|
||||
* 选择条件
|
||||
* @param fields
|
||||
* 读取的字段
|
||||
* @return 一个含有KeyValue的List(列表)
|
||||
*/
|
||||
public List<KeyValue> dbSelect(final String tableName, final KeyValue selCondition, final String... fields) {
|
||||
final String sql = "SELECT " + getKeys(fields) + " FROM `" + tableName + "`" + (selCondition == null ? "" : " WHERE " + selCondition.toWhereString());
|
||||
final List<KeyValue> kvlist = new ArrayList<>();
|
||||
try {
|
||||
final ResultSet dbresult = this.dataBaseCore.query(sql);
|
||||
while (dbresult.next()) {
|
||||
final KeyValue kv = new KeyValue();
|
||||
for (final String col : fields) {
|
||||
kv.add(col, dbresult.getString(col.toString()));
|
||||
}
|
||||
kvlist.add(kv);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
sqlerr(sql, e);
|
||||
}
|
||||
return kvlist;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对数据库表进行选择操作!
|
||||
*
|
||||
* @param tableName
|
||||
* 数据库表名
|
||||
* @param fields
|
||||
* 字段名
|
||||
* @param selConditions
|
||||
* 选择条件
|
||||
* @return 首个符合条件的结果
|
||||
*/
|
||||
public String dbSelectFirst(final String tableName, final String fields, final KeyValue selConditions) {
|
||||
final String sql = "SELECT " + fields + " FROM " + tableName + " WHERE " + selConditions.toWhereString() + " limit 1";
|
||||
try {
|
||||
final ResultSet dbresult = this.dataBaseCore.query(sql);
|
||||
if (dbresult.next()) {
|
||||
return dbresult.getString(fields);
|
||||
}
|
||||
} catch (final Exception e) {
|
||||
sqlerr(sql, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 对数据库表中记录进行更新操作
|
||||
*
|
||||
* @param tabName
|
||||
* 表名
|
||||
* @param fields
|
||||
* 字段参数
|
||||
* @param upCondition
|
||||
* 更新条件
|
||||
* @return 受到影响的数据条目
|
||||
*/
|
||||
public int dbUpdate(final String tabName, final KeyValue fields, final KeyValue upCondition) {
|
||||
final String sql = "UPDATE `" + tabName + "` SET " + fields.toUpdateString() + " WHERE " + upCondition.toWhereString();
|
||||
try {
|
||||
return this.dataBaseCore.update(sql);
|
||||
} catch (final Exception e) {
|
||||
sqlerr(sql, e);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得当前使用的数据库核心
|
||||
*
|
||||
* @return 数据库核心
|
||||
*/
|
||||
public DataBaseCore getDataBaseCore() {
|
||||
return this.dataBaseCore;
|
||||
}
|
||||
|
||||
/**
|
||||
* 字段数组转字符串
|
||||
*
|
||||
* @param fields
|
||||
* 字段数组
|
||||
* @return 字段字符串
|
||||
*/
|
||||
public String getKeys(final String... fields) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
for (final String string : fields) {
|
||||
sb.append("`");
|
||||
sb.append(string);
|
||||
sb.append("`, ");
|
||||
}
|
||||
return sb.toString().substring(0, sb.length() - 2);
|
||||
}
|
||||
|
||||
public boolean isFieldExists(final String tableName, final KeyValue fields) {
|
||||
final DatabaseMetaData dbm;
|
||||
final ResultSet tables;
|
||||
try {
|
||||
dbm = this.dataBaseCore.getConnection().getMetaData();
|
||||
tables = dbm.getTables(null, null, tableName, null);
|
||||
if (tables.next()) {
|
||||
final ResultSet f = dbm.getColumns(null, null, tableName, fields.getKeys()[0]);
|
||||
return f.next();
|
||||
}
|
||||
} catch (final SQLException e) {
|
||||
sqlerr("判断 表名:" + tableName + " 字段名:" + fields.getKeys()[0] + " 是否存在时出错!", e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断数据表是否存在
|
||||
*
|
||||
* @param tableName
|
||||
* 表名
|
||||
* @return 是否存在
|
||||
*/
|
||||
public boolean isTableExists(final String tableName) {
|
||||
try {
|
||||
final DatabaseMetaData dbm = this.dataBaseCore.getConnection().getMetaData();
|
||||
final ResultSet tables = dbm.getTables(null, null, tableName, null);
|
||||
return tables.next();
|
||||
} catch (final SQLException e) {
|
||||
sqlerr("判断 表名:" + tableName + " 是否存在时出错!", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量执行SQL语句
|
||||
*
|
||||
* @param sqls
|
||||
* SQL语句列表
|
||||
*/
|
||||
public void runSqlList(final Collection<String> sqls) {
|
||||
final Connection con = getDataBaseCore().getConnection();
|
||||
final long start = System.currentTimeMillis();
|
||||
try {
|
||||
long time = System.currentTimeMillis();
|
||||
con.setAutoCommit(false);
|
||||
final Statement st = con.createStatement();
|
||||
int i = 0;
|
||||
for (final String sql : sqls) {
|
||||
st.addBatch(sql);
|
||||
i++;
|
||||
if (i % 100 == 0) {
|
||||
st.executeBatch();
|
||||
con.commit();
|
||||
if (System.currentTimeMillis() - time > 500) {
|
||||
info("已执行 " + i + " 条语句...");
|
||||
time = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
}
|
||||
st.executeBatch();
|
||||
con.commit();
|
||||
info("执行SQL完毕 总计: " + sqls.size() + " 条 耗时: " + start + "ms!");
|
||||
} catch (final SQLException e) {
|
||||
try {
|
||||
con.rollback();
|
||||
sqlerr("执行SQL数组发生错误 数据已回滚...", e);
|
||||
} catch (final SQLException e1) {
|
||||
sqlerr("执行SQL数组发生错误 警告! 数据回滚失败...", e1);
|
||||
}
|
||||
} finally {
|
||||
try {
|
||||
con.setAutoCommit(true);
|
||||
} catch (final SQLException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 输出SQL错误
|
||||
*
|
||||
* @param sql
|
||||
* SQL语句
|
||||
* @param e
|
||||
* 错误异常
|
||||
*/
|
||||
public void sqlerr(final String sql, final Exception e) {
|
||||
info("数据库操作出错: " + e.getMessage());
|
||||
info("SQL查询语句: " + sql);
|
||||
Log.debug(this.getClass().getName());
|
||||
Log.debug(e);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试数据库连接
|
||||
*
|
||||
* @return 是否连接成功
|
||||
*/
|
||||
public boolean testConnect() {
|
||||
return this.dataBaseCore.getConnection() != null;
|
||||
}
|
||||
|
||||
private void info(final String info) {
|
||||
Log.info(info);
|
||||
}
|
||||
|
||||
// private String toKeys(final Class<? extends Model<?>> model) {
|
||||
// final Field[] fields = model.getDeclaredFields();
|
||||
// final StringBuilder sb = new StringBuilder();
|
||||
// for (final Field next : fields) {
|
||||
// sb.append("`");
|
||||
// sb.append(next.getName());
|
||||
// sb.append("`, ");
|
||||
// }
|
||||
// return sb.toString().substring(0, sb.length() - 2);
|
||||
// }
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user