SteamWar/SpigotCore
Archiviert
13
0

New SQL API + SchemByUserAndType speedup

Dieser Commit ist enthalten in:
Lixfel 2021-09-16 21:50:52 +02:00
Ursprung 6a3d82bc1d
Commit 6d20b7bb2a
3 geänderte Dateien mit 112 neuen und 35 gelöschten Zeilen

Datei anzeigen

@ -71,7 +71,7 @@ public class Core extends JavaPlugin{
@Override
public void onDisable(){
SQL.closeConnection();
SQL.close();
}
public static Core getInstance() {

Datei anzeigen

@ -24,18 +24,18 @@ import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
public class SQL {
private SQL(){}
private static final String host;
private static final String port;
private static final String database;
private static final String user;
private static final String password;
private static Connection con;
private static String url;
private static String user;
private static String password;
static{
File file = new File(Core.getInstance().getDataFolder(), "MySQL.yml");
@ -44,20 +44,47 @@ public class SQL {
if(!file.exists())
throw new SecurityException("SQL-ConfigFile not found!");
host = config.getString("HOST");
port = config.getString("PORT");
database = config.getString("DATABASE");
url = "jdbc:mysql://" + config.getString("HOST") + ":" + config.getString("PORT") + "/" + config.getString("DATABASE");
user = config.getString("USER");
password = config.getString("PASSWORD");
connect();
}
public static void closeConnection() {
private static void connect() {
try {
con = DriverManager.getConnection(url + "?autoreconnect=true", user, password);
} catch (SQLException e) {
throw new SecurityException("Could not start SQL connection", e);
}
}
public static void close() {
for (Statement statement : Statement.statements) {
try {
statement.st.close();
} catch (SQLException e) {
Core.getInstance().getLogger().log(Level.INFO, "Could not close statement", e);
}
}
try {
con.close();
}catch (SQLException e) {
throw new SecurityException("Could not close connection", e);
} catch (SQLException e) {
Core.getInstance().getLogger().log(Level.WARNING, "Could not close SQL-Connection", e);
}
}
private static void reset(SQLException e) {
Core.getInstance().getLogger().log(Level.WARNING, "SQL Exception thrown", e);
close();
connect();
try {
for (Statement statement : Statement.statements) {
statement.init();
}
} catch (SQLException ex) {
throw new SecurityException("Could not reprepare SQL Statements", ex);
}
}
@ -65,7 +92,7 @@ public class SQL {
try {
prepare(qry, objects).executeUpdate();
} catch (SQLException e) {
reconnect();
reset(e);
try {
prepare(qry, objects).executeUpdate();
} catch (SQLException ex) {
@ -78,7 +105,7 @@ public class SQL {
try {
return prepare(qry, objects).executeQuery();
} catch (SQLException e) {
reconnect();
reset(e);
try {
return prepare(qry, objects).executeQuery();
} catch (SQLException ex) {
@ -91,7 +118,7 @@ public class SQL {
try {
return con.createBlob();
} catch (SQLException e) {
reconnect();
reset(e);
try {
return con.createBlob();
} catch (SQLException ex) {
@ -108,18 +135,66 @@ public class SQL {
return st;
}
private static void connect() {
public static class Statement {
private static final List<Statement> statements = new ArrayList<>();
private final String sql;
private PreparedStatement st;
Statement(String sql) {
this.sql = sql;
statements.add(this);
try {
con = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database + "?autoreconnect=true", user, password);
if(con.isClosed())
throw new SQLException("Could not connect to database!");
}catch (SQLException e) {
throw new SecurityException("No connection to database.", e);
init();
} catch (SQLException e) {
reset(e);
}
}
private static void reconnect(){
closeConnection();
connect();
private synchronized void init() throws SQLException {
st = con.prepareStatement(sql);
}
<T> T select(ResultSetUser<T> user, Object... objects) {
return prepare(() -> {
ResultSet rs = st.executeQuery();
T result = user.use(rs);
rs.close();
return result;
}, objects);
}
void update(Object... objects) {
prepare(st::executeUpdate, objects);
}
private synchronized <T> T prepare(SQLRunnable<T> runnable, Object... objects) {
try {
setObjects(objects);
return runnable.run();
} catch (SQLException e) {
reset(e);
try {
setObjects(objects);
return runnable.run();
} catch (SQLException ex) {
throw new SecurityException("Could not execute SQL statement", ex);
}
}
}
private void setObjects(Object... objects) throws SQLException {
for (int i = 0; i < objects.length; i++) {
st.setObject(i + 1, objects[i]);
}
}
interface ResultSetUser<T> {
T use(ResultSet rs) throws SQLException;
}
private interface SQLRunnable<T> {
T run() throws SQLException;
}
}
}

Datei anzeigen

@ -35,6 +35,8 @@ import java.util.zip.GZIPInputStream;
public class Schematic {
private static final SQL.Statement getSchemsOfType = new SQL.Statement("SELECT DISTINCT s.SchemID, s.SchemName, s.SchemOwner, s.Item, s.SchemType, s.Rank, s.SchemFormat FROM Schematic s LEFT JOIN SchemMember sm ON sm.SchemName = s.SchemName AND sm.SchemOwner = s.SchemOwner WHERE s.SchemType = ? AND (s.SchemOwner = ? OR sm.Member = ?) ORDER BY s.SchemName");
private final int schemID;
private final String schemName;
private final int schemOwner;
@ -118,12 +120,12 @@ public class Schematic {
}
public static List<Schematic> getSchemsOfType(int schemOwner, SchematicType schemType){
//Unsauber, dafür auch geaddede Schematics dabei
List<Schematic> schems = getSchemsAccessibleByUser(schemOwner);
for(int i = schems.size()-1; i >= 0; i--)
if(!schems.get(i).getSchemType().equals(schemType))
schems.remove(i);
return schems;
return getSchemsOfType.select(rs -> {
List<Schematic> schematics = new ArrayList<>();
while(rs.next())
schematics.add(new Schematic(rs));
return schematics;
}, schemType.toDB(), schemOwner, schemOwner);
}
public static List<Schematic> getAllSchemsOfType(SchematicType schemType){