Ich implementiere ein einfaches Jail-System für Minecraft-Server.
Jails sind Objekte, sie haben ihre eigene ID, Anzahl der Spieler innerhalb und Ort.Methode zum Erstellen eines Objekts, das Callback verwendet
Ich möchte eine einfache Methode zum Erstellen neuer Jail erstellen.
public static Jail createJail(final Location location);
Diese Methode sollte automatisch neu erstellt Jail in DB einfügen meine DBhelper mit (was alles async läuft), und wenn etwas fehlschlägt, null zurück statt Jail Objekt. Das Problem ist natürlich bei CallBack und anonymer Klasse, die meine einfache CallBack-Schnittstelle implementieren, weil ich nichts innerhalb der inneren anonymen Klasse zurückgeben kann.
Hier ist, was ich bisher:
/**
* Create new Jail object, fill with values and register in List
* @param id Unique id of Jail, usually got from DB
* @param location Location of Jail
*/
private Jail(final int id, final Location location) {
this.id = id;
this.location = location;
this.amountOfJailed = 0;
jails.add(id, this);
}
/**
* Tries to create new Jail<br />
* New Jail will be auto-inserted into DB.
* @param location Valid Bukkit Location
* @return Jail if successfully created, null otherwise
*/
public static Jail createJail(final Location location) {
if (location == null) {
Bukkit.getLogger().warning(Lang.PREFIX + " Tried to create new Jail with invalid location");
return null;
}
final Jail newJail;
DatabaseQuery db = new DatabaseQuery();
db.insertJail(location, new SimpleCallBack() {
@Override
public void onQueryDone(ResultSet result) {
if (result == null) {
newJail = null;
} else {
result.next();
int usedId = result.getInt("id");
newJail = new Jail(usedId, location);
}
}
});
return newJail;
}
und Databasequery # insertJail
/**
* Inserts Jail into DB<br />
* When any error happens, callBack will receive null ResultSet<br />
* When everything goes well, ResultSet will hold generated id
* @param location Location of inserted Jail
* @param callBack Class with 'onQueryDone' method to be executed
*/
public void insertJail(final Location location, final SimpleCallBack callBack) {
new BukkitRunnable() {
@Override
public void run() {
ResultSet result = null;
try
{
Connection connection = hikari.getConnection();
PreparedStatement statement = connection.prepareStatement("INSERT INTO p_jails (`location`) VALUES (?);");
statement.setString(1, Serializer.location_serialize(location));
statement.executeUpdate();
result = statement.getGeneratedKeys();
} catch (SQLException e) {
e.printStackTrace();
}
final ResultSet fResult = result;
new BukkitRunnable() {
@Override
public void run() {
callBack.onQueryDone(fResult);
}
}.runTask(Main.coreapi);
}
}.runTaskAsynchronously(Main.coreapi);
}
Wie soll ich createJail
Methode implementieren? Ich muss wissen, ob es erfolgreich in DB eingefügt wurde, und ich muss id von ResultSet verwendet werden, damit ich dieses Jail-Objekt schließlich zurückgeben und ihm etwas wie "Erfolgreiches neues Gefängnis mit ID ##" sagen kann.
Es ist nur sehr einfache Schnittstelle mit 'void onQueryDone (ResultSet result);' method –
Weil das erste 'BukkitRunnable' es async macht. Dann rufe ich den Sync-Thread an, der manchmal von Bukkit als Tick-Thread bezeichnet wird.Wenn ich es auf zwei Methoden aufteile, wird es nicht helfen, weil ich 'Jail'-Objekt innerhalb der' createJail'-Methode zurückgeben muss ... aber nur, wenn es richtig in DB gespeichert ist. Diese Aufteilung würde nur aus einer Abfrage zwei Abfragen machen. Erst um freie ID zu bekommen und dann 'Jail' in DB zu speichern. –