Verschiede Aktionen der Datenbank getrennt durchführen

DaCrazyJavaExpert

Bekanntes Mitglied
Hey,
ich habe hier diesen Code einer Datenbank:
Java:
package de.m_ver.cookieclicker.database;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import de.m_ver.cookieclicker.gui.CookieClickerGUI;

public class Database {

    private final static String CREATE_DATA_TABLE = "CREATE TABLE COOKIE_VALUES ("
            + "ID INT NOT NULL GENERATED BY DEFAULT AS IDENTITY, " + "COOKIES_PRO_KLICK INT, " + "ANZAL_COOKIES INT, "
            + "PRIMARY KEY (ID) " + ")";
    private final static String ADD_INSTRUCTIONS = "INSERT INTO COOKIE_VALUES VALUES (DEFAULT, ?, ?)";

    private static String id;
    private static int cookies_Pro_Klick;
    private static int anzahl_Cookies;

    public static int getCookies_Pro_Klick() {
        return cookies_Pro_Klick;
    }

    public static void setCookies_Pro_Klick(int cookies_Pro_Klick) {
        Database.cookies_Pro_Klick = cookies_Pro_Klick;
    }

    public static int getAnzahl_Cookies() {
        return anzahl_Cookies;
    }

    public static void setAnzahl_Cookies(int anzahl_Cookies) {
        Database.anzahl_Cookies = anzahl_Cookies;
    }

    private static Connection createConnection() throws ClassNotFoundException, SQLException {
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        Connection connection = DriverManager.getConnection("jdbc:derby:database/cookie;create=true");
        return connection;
    }

    public static void registerConnectionInListener() {
        try (Connection connection = createConnection()) { //#
            DatabaseMetaData metaData = connection.getMetaData();//#
            ResultSet tables = metaData.getTables(null, "APP", "COOKIE_VALUES", null);//#
            if (!tables.next()) {//#
                Statement instructions = connection.createStatement();//#
                instructions.executeUpdate(CREATE_DATA_TABLE);//#
                instructions.close();//#
            }
            PreparedStatement insertStatement = connection.prepareStatement(ADD_INSTRUCTIONS);//*
            insertStatement.setInt(1, CookieClickerGUI.getCookiesProClick());//*
            insertStatement.setLong(2, CookieClickerGUI.getAnzahlCookies());//*
            insertStatement.executeUpdate();//*
            PreparedStatement queryInstructions = connection.prepareStatement("SELECT * FROM COOKIE_VALUES");//*
            ResultSet resultSet = queryInstructions.executeQuery();//*
            while (resultSet.next()) {//*
                id = resultSet.getString("ID");//*
                cookies_Pro_Klick = resultSet.getInt("COOKIES_PRO_KLICK");//*
                anzahl_Cookies = resultSet.getInt("ANZAL_COOKIES");//*
            }
        } catch (ClassNotFoundException e) { //Und der Teil ab hier muss halt irgendwie trotzem passen.
            System.err.println("Database driver not found!");
        } catch (SQLException e) {
            System.err.println("SQL error");
            e.printStackTrace();
        }
    }

    public static String getId() {
        return id;
    }

    public static void setId(String id) {
        Database.id = id;
    }
}
Ich möchte den Teil den ich jetzt oben im Code mit '#' makiert habe in meiner GUI-Klasse im Listener haben.
Jedesmal wenn der Listener in Aktion kommt, soll der '#' Teil ausgeführt werden.
Hier nochmal der Listener:
Java:
private void registerCookieListener() {
        this.lblCookie.addMouseListener(new MouseListener() {

            @Override
            public void mouseReleased(MouseEvent e) {
                lblCookieClicked.setVisible(false);
                lblCookie.setVisible(true);
                Database.registerConnectionInListener(); // Dies hier funktioniert nicht so recht, also einfach nicht beachten
            }

            @Override
            public void mousePressed(MouseEvent e) {
                anzahlCookies += cookiesProClick;
                lblAnzahlCookies.setText("Cookies: " + anzahlCookies);
                lblCookie.setVisible(false);
                lblCookieClicked.setVisible(true);
            }
Den Teil den ich mit '*' makiert habe, möchte ich in der Main Methode haben.
Jedes mal wenn das Programm gestartet wird, soll also der '*' Teil ausgeführt werden, also die Daten aus der Datenbank abgerufen werden.
Hier die Main:
Java:
public class Main {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    CookieClickerGUI frame = new CookieClickerGUI();
                    frame.start();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

Ich hab veruscht die beiden Teile in eine einzelne Methode zu packen, allerding klappt dass mit dem initialisieren von "connection" nicht so gut und generell der ganze catch block wäre "kaputt". Hat jemand ein Vorschlag wie ich die beiden Teile getrennt ausführen kann, ohne den kompletten Code neuschreiben zu müssen oder andere große Veränderungen vornehemen zu müssen.

Ich hoffe ich hab mein Problem einigermaßen gut erklärt. Ansonsten fragt bitte nach 🙂. Danke!
 
Zuletzt bearbeitet von einem Moderator:
den catch-Block doppelt haben
Den try () - Teil dann auch? Oder hab ich da was falsch verstanden. Jedenfalls klappts nicht so wie ich will. Die Daten werden entweder nicht geladen/in die Datenbank eingetragen, oder, was ich glaube, ich habe das Auslesen + Einlesen der Daten einfach irgendwie falsch implementiert. Soll ich mal meine kompletten Code posten, weil ich komm nicht drauf, was ich da falsch mache. Allerdings geht mein kompletter Code über ca. 500 - 600 Zeilen. Das will ich euch eigentlich nicht antun. Hat eventuell jemand ein Tipp was ich eventuell Falsch gemacht habe? Oder ist im obigen Code irgendein Fheler aufzufinden, welchen ich übersehen habe. Meines Erachtens, liegt der Fehler nämlich in der Implementierung der Methoden/Zeilen, und nicht am Fehlerhaften Code.
Danke
 
Ja, den try-Block logischerweise auch.

Generell seh ich da keinen schlimmen Fehler, du solltest die Methode problemlos trennen können.
Man könnte das besser aufbauen - die Methode muss man aber trotzdem spalten, und das geht auch so
 
Ok Danke. Ich hab es jetzt so in die zwei Methoden geteilt:
Java:
    private static Connection createConnection() throws ClassNotFoundException, SQLException {
        Class.forName("org.apache.derby.jdbc.EmbeddedDriver");
        Connection connection = DriverManager.getConnection("jdbc:derby:database/cookie;create=true");
        return connection;
    }

    public static void registerConnectionInMain() {
        try (Connection connection = createConnection()) {
            DatabaseMetaData metaData = connection.getMetaData();
            ResultSet tables = metaData.getTables(null, "APP", "COOKIE_VALUES", null);
            if (!tables.next()) {
                Statement instructions = connection.createStatement();
                instructions.executeUpdate(CREATE_DATA_TABLE);
                instructions.close();
            }
        } catch (ClassNotFoundException e) {
            System.err.println("Database driver not found!");
        } catch (SQLException e) {
            System.err.println("SQL error");
            e.printStackTrace();
        }
    }

    public static void registerConnectionInListener() {
        try (Connection connection = createConnection()) {
            PreparedStatement insertStatement = connection.prepareStatement(ADD_INSTRUCTIONS);
            insertStatement.setInt(1, CookieClickerGUI.getCookiesProClick());
            insertStatement.setLong(2, CookieClickerGUI.getAnzahlCookies());
            insertStatement.executeUpdate();
            PreparedStatement queryInstructions = connection.prepareStatement("SELECT * FROM COOKIE_VALUES");
            ResultSet resultSet = queryInstructions.executeQuery();
            while (resultSet.next()) {
                id = resultSet.getString("ID");
                cookies_Pro_Klick = resultSet.getInt("COOKIES_PRO_KLICK");
                anzahl_Cookies = resultSet.getInt("ANZAL_COOKIES");
            }
        } catch (ClassNotFoundException e) {
            System.err.println("Database driver not found!");
        } catch (SQLException e) {
            System.err.println("SQL error");
            e.printStackTrace();
        }
    }
Bei der ersten Methode [wird ja(?)], sollen die Daten bei Programmstart aufgerufen werden. :
Java:
public class Main {

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    CookieClickerGUI frame = new CookieClickerGUI();
                    frame.start();
                    Database.registerConnectionInMain();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
Und bei einem Klick auf den Keks(in meinem Fall), wird die Datenbank immer aktualisiert:
Java:
            @Override
            public void mouseReleased(MouseEvent e) {
                lblCookieClicked.setVisible(false);
                lblCookie.setVisible(true);
                Database.registerConnectionInListener();
            }
 

Zurück
Oben