Zum Inhalt springen
  • 0

Java ExecuteUpdate zur Erweiterung einer Tabelle


Frage

Geschrieben

Hallo,

ich habe hier unten mal meinen Code gepostet, mit dem ich versuche, meine Tabelle "kunde" durch die Informationen, die der User zuvor eingegeben zu erweitern, im Falle dass sie noch nicht in der Tabelle existieren. Allerdings erscheint ständig ein Fehler, den ich nicht ganz nachvollziehen kann. Wenn jemand vielleicht in dem Code einen Fehler findet, dann könnte das mein Problem lösen.

package testaufgabe;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;


public class Aufgaben {

    private BufferedReader reader;
    private Scanner scanner;
    private ConnectionToMySQL conMySQL;
    private ResultSet result = null;
    private Connection connection;
    private Statement statement;

    public Aufgaben() {
        reader = new BufferedReader(new InputStreamReader(System.in));
        scanner = new Scanner(System.in);
        conMySQL = new ConnectionToMySQL();
    }

    
    public void EnterInformation() throws IOException {

        // NAMEN abfragen, USER-Eingabe
        System.out.println("Gib hier deinen Vor- und Nachnamen ein: \nVorname: ");
        String firstName = scanner.nextLine();
        System.out.println("\nNachname: ");
        String lastName = reader.readLine();
        System.out.println("\n" + firstName + " " + lastName);

        ExistingName(firstName, lastName);
    }

    private void ExistingName(String firstName, String lastName) {
        
        List<String> usernames = new ArrayList<String>();
        result = conMySQL.executeQuery("SELECT k.vn, k.nn FROM kunde k");
        
        try {
            while (result.next()) {
                usernames.add(result.getString(1) + " " + result.getString(2));
            }
        } catch (SQLException ex) {
            Logger.getLogger(Aufgaben.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        // Überprüft, ob User in der DB existiert
        // Fügt neuen Namen in die Tabelle
        for (String name : usernames) {
            
            String username = firstName + " " + lastName;
            
            if (!username.equals(name)) {   
                conMySQL.executeUpdate(firstName, lastName);
            }
        }
    }

}

---------------------------------------------------------------------------------------

Die Klasse hier drüber greift auf die folgende zu:

---------------------------------------------------------------------------------------

package testaufgabe;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.sql.Connection;


public class ConnectionToMySQL {

    private static final String MYSQL_JDBC_STRING = "jdbc:mysql://127.0.0.1:3306/pizza_service";
    private boolean connected = false;
    private Statement stmt;
    private Connection connection;
    private ResultSet resultSet = null;
    private Random random = new Random();

    public boolean connect() {

        String url = MYSQL_JDBC_STRING + "?zeroDateTimeBehavior=convertToNull";

        try {
            connection = DriverManager.getConnection(url, "root", "");

            stmt = connection.createStatement();
        } catch (SQLException ex) {
            Logger.getLogger(main.class.getName()).log(Level.WARNING, null, ex);
        }

        connected = true;
        return connected;
    }

    public void close() {
        try {
            connection.close();
            connected = false;
        } catch (SQLException ex) {
            Logger.getGlobal().log(Level.SEVERE, null, ex);
        }
    }

    public boolean isConnected() {
        return connected;
    }

    public ResultSet executeQuery(final String query) {

        try {
            String url = MYSQL_JDBC_STRING + "?zeroDateTimeBehavior=convertToNull";
            connection = DriverManager.getConnection(url, "root", "");

            stmt = connection.createStatement();
            return stmt.executeQuery(query);
        } catch (SQLException ex) {
            Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
        }

        return null;
    }
    
    public Statement executeUpdate(String firstName, String lastName) {
    
        try {
            String url = MYSQL_JDBC_STRING + "?zeroDateTimeBehavior=convertToNull";
            connection = DriverManager.getConnection(url, "root", "");
            
            stmt = connection.createStatement();
            stmt.executeUpdate("INSERT INTO kunde VALUES ('" + firstName + "','" + lastName + "')");
        } catch (SQLException ex) {
            Logger.getLogger(ConnectionToMySQL.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        return null;
    }
}

18 Antworten auf diese Frage

Empfohlene Beiträge

  • 0
Geschrieben (bearbeitet)
vor 53 Minuten schrieb Monsieur Bate:

Allerdings erscheint ständig ein Fehler, den ich nicht ganz nachvollziehen kann

Und was ist "ein Fehler" ? Warum schreibst du den nicht einfach dazu? Java ist typischerweise sehr kulant und sagt, was für eine Exception es ist - inkl. Zeilenangabe.

 

vor 53 Minuten schrieb Monsieur Bate:

Wenn jemand vielleicht in dem Code einen Fehler findet, dann könnte das mein Problem lösen.

.. Und wenn nicht?

 

Was haste denn bisher gemacht? Wo kommt der Code her? Hast du ihn mal ausgeführt?

Warum postest du nicht die Fehlermeldung + Stacktrace?

 

Viele von uns benötigen die Glaskugel beruflich, sodass sie zwischendrin mal aufgeladen werden muss.

//Edit:

Da sind so viele Ungereimtheiten und Fehler drin, dass ich gar nicht weiss, wo ich anfangen soll....
Mein Tipp: Lerne, mit einem Debugger zu arbeiten und schritt für schritt durch deinen Code zu gehen.

Bearbeitet von Memento
  • 0
Geschrieben (bearbeitet)
vor 14 Minuten schrieb Memento:

Und was ist "ein Fehler" ? Warum schreibst du den nicht einfach dazu? Java ist typischerweise sehr kulant und sagt, was für eine Exception es ist - inkl. Zeilenangabe.

Sorry, hatte ich voll vergessen hinzuzufügen.

Hier der Fehler:

Exception in thread "main" java.lang.NullPointerException
    at testaufgabe.ConnectionToMySQL.executeQuery(ConnectionToMySQL.java:64)
    at testaufgabe.Aufgaben.ExistingName(Aufgaben.java:57)
    at testaufgabe.Aufgaben.EnterInformation(Aufgaben.java:51)
    at testaufgabe.main.main(main.java:34)
C:\Users\TESTPROJEKT\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 2 seconds)

Bearbeitet von Monsieur Bate
  • 0
Geschrieben

Jo, steht doch alles da... NullpointerException in testaufgabe.ConnectionToMySQL.executeQuery -> Zeile 64

Bitte mach dich mit dem Konzept des Debuggers vertraut und nutze diesen, um den Fehler zu lokalisieren.

 

Übrigens: Vollzitate sind echt ätzend, wenn man sicht nicht auf den gesamten, zittierten Text bezieht.

  • 0
Geschrieben (bearbeitet)
vor 4 Minuten schrieb Memento:

Bitte mach dich mit dem Konzept des Debuggers vertraut und nutze diesen, um den Fehler zu lokalisieren.

Das hat mir nicht wirklich weitergeholfen. Bin bereits mit dem Debugger durch den Code gegangen. Da war kein Fehler ersichtlich.

Der Fehler entstand, als ich versuchte die Informationen, die eingegeben wurden, in die Tabelle hinzuzufügen.

Bearbeitet von Monsieur Bate
  • 0
Geschrieben (bearbeitet)

Dann empfehle ich dir, entweder deine Entwicklungsumgebung samt Debugger zu ändern, oder nochmal zu schauen, ob du tatsächlich zur Laufzeit einen Debugger genutzt hast. Denn wenn du eine Exception bekommst, dann hält der Debugger entsprechend an von dir gesetzten Breakpoints an und dann siehst du ja, was genau da null ist.

Ich möchte dir bewusst nicht die Lösung verraten, sonst bist du morgen mit gleichem Fehlverhalten der Anwendung wieder hier.

Getreu dem Motto: give a man a fish and you feed him for a day; teach a man to fish and you feed him for a lifetime.

 

Bearbeitet von Memento
  • 0
Geschrieben (bearbeitet)
vor 13 Minuten schrieb Memento:

Denn wenn du eine Exception bekommst, dann hält der Debugger entsprechend an von dir gesetzten Breakpoints an und dann siehst du ja, was genau da null ist.

Ist mir schon klar. Aber es macht keinen Sinn, dass es in der Zeile 64 einen Fehler gibt. Denn die Sache ist, dass es bevor ich die neue Methode "executeUpdate" geschrieben und verwendet hatte, problemlos funktionierte. Ich benutze die Methode "executeQuery" genau einemal, und das passiert bevor ich die Methode "executeUpdate" aufrufe. Daher ist es für mich trotz Debuggen nicht ersichtlich. Denn der Fehler ist nicht bei "executeQuery".

Bearbeitet von Monsieur Bate
  • 0
Geschrieben (bearbeitet)

Welche Zeile ist denn nun genau Zeile 64 in der ConnectionToMySQL.java?

Du kannst auch mit dem Debugger Schritt-für-Schritt dein Code durchlaufen und den Status der jeweiligen Objekte anschauen. Irgendeins muss davon ja NULL sein.

Bearbeitet von Whiz-zarD
  • 0
Geschrieben
vor 1 Minute schrieb Whiz-zarD:

Welche Zeile ist denn nun genau Zeile 64 in der ConnectionToMySQL.java?

Findest du aus meinem Eröffnungspost in der 2. Klasse, in der "executeQuery"-Methode:

return stmt.executeQuery(query);

  • 0
Geschrieben

Hallo @Monsieur Bate!

Ist die Datenbankverbindung noch geöffnet? Oder wird die in der Query-Methode irgendwo unter der Haube geschlossen? Wird vor dem Absenden der Query der String noch validiert und ist in deinem Fall ggfs. falsch oder "null"?

Auch: Wieso führst du in der Methode executeUpdate ein INSERT aus? Ich finde das bzgl. der Benennung extrem verwirrend. Und: Meines Wissens nach gibt es auch in MySQL Stored Procedures. Kennst du das Konzept?

Gruß, Goulasz :goulasz: 

  • 0
Geschrieben (bearbeitet)
vor 11 Minuten schrieb Goulasz:

Ist die Datenbankverbindung noch geöffnet? Oder wird die in der Query-Methode irgendwo unter der Haube geschlossen? Wird vor dem Absenden der Query der String noch validiert und ist in deinem Fall ggfs. falsch oder "null"?

Schau mal hier:

public class main {
 
    public static void main(String[] args) throws IOException {
        
        ConnectionToMySQL conMySQL = new ConnectionToMySQL();
        Aufgaben tasks = new Aufgaben();
        
        conMySQL.connect();
        System.out.print("Verbindung: " + conMySQL.isConnected() + "\n");
        tasks.EnterInformation(); 
    }
}

Ich habe hier in der main-Klasse die Connection gestartet und entsprechend meines Vorhabens die "EnterInformation"-Methode meiner Klasse "Aufgaben" verwendet. Die Connection wird nicht geschlossen. Ja, das ganze wird auch geprüft, bevor sie ausgeführt wird. Also was genau passiert ist, dass das Programm erkennt, dass meine Tabelle "kunde" beispielsweise die Eingabe, die ich gemacht habe erkennt und auswertet. Ist die Eingabe in der Tabelle nicht enthalten so soll die eingegebene Information in die Tabelle eingetragen werden.

vor 11 Minuten schrieb Goulasz:

Auch: Wieso führst du in der Methode executeUpdate ein INSERT aus? Ich finde das bzgl. der Benennung extrem verwirrend. Und: Meines Wissens nach gibt es auch in MySQL Stored Procedures. Kennst du das Konzept?

Ich habe das gemacht, weil der Sinn hinter der Methode ist, dass die Informationen dort an die Tabelle übergeben werden. Leider ist mir das nicht bekannt.

Bearbeitet von Monsieur Bate
  • 0
Geschrieben

Ist zwar schon und gut, dass du in der Main-Methode ein Objekt der ConnectionToMySQL-Klasse erzeugst, aber das tust du in der Aufgaben-Klasse auch und in der Aufgaben-Klasse baust du keine Verbindung zum Server auf. DU willst also somit zwei Verbindunegen aufbauen, wobei du in der Main-Methode connect() aufrufst aber nicht in der Aufgaben-Klasse. Deswegen auch die NullReferenceException.

  • 0
Geschrieben (bearbeitet)

Schau auch mal deine Rückgaben durch.. zB willst du ein Statement zurückgeben (wofür eigentlich? Mach ne void draus..) , gibst aber immer null zurück. Auch wird in der connect-Methode der Fall, dass eine Exception geworfen wird, nicht auf die flag-Variable übertragen; connected wird da immer true sein. Das log-Level da plump als Warning anzugeben ist auch eher ungeschickt. Müsstest eigentlich von der Exception selbst den Log-Level beziehen können (da bin ich grad aber unsicher). Die ExistingName-Methode musst du dir auch nochmal anschauen, die macht überhaupt keinen Sinn. Erst packst du den Namen in die Liste, dann gehst du diese Liste in der Schleife durch und für jeden Namen, der nicht der eingegebene ist, fügst du einen neuen Datensatz in die Tabelle. Heißt, bei 10 Personen, 9 neue Einträge mit der neuen Person in der Datenbank. Beim nächsten Eintrag wärens schon 19 zusätzliche usw. 

Ich würd mir die ganze Connection statisch in die Main-Klasse packen, so dass du dann von egal woher über Main.getConnection() drankommen kannst. So musst du nicht verschiedene Connections erstellen und wirst zumindest in diesem Zusammenhang keine NullPointer mehr sehen.

..und ich muss Goulasz rechtgeben: Ein Insert und ein Update sind zwei grundlegend verschiedene Dinge, auch wenn das Statement als solches diese nicht unterscheidet. Deine Update-Methode sollte also Insert heißen, bei Updates gehts um Veränderungen von bestehenden Datensätzen, nicht um neue Einträge.

Bearbeitet von MartinGrupinski
  • 0
Geschrieben
vor 16 Minuten schrieb MartinGrupinski:

Ich würd mir die ganze Connection statisch in die Main-Klasse packen, so dass du dann von egal woher über Main.getConnection() drankommen kannst. So musst du nicht verschiedene Connections erstellen und wirst zumindest in diesem Zusammenhang keine NullPointer mehr sehen.

Statische Klassen sind die Hölle, wenn man mal einen Unittest schreiben will. Sowas immer als Dependency Injection in die Klasse reinreichen und nicht überall im Code verstreut Main.getConnection() aufrufen. So etwas macht die Klassen erst recht untestbar.

  • 0
Geschrieben

Ich versteh deinen Punkt nicht so ganz, muss ich gestehen. Natürlich ist es "richtiger", solche Dinge per Konstruktoren durchzureichen, doch auch bei statischen Methoden werden Fehler ganz normal im Stacktrace zurückgegeben. Wieso sollte das dadurch schwerer zu testen sein? Oder interpretier ich die Begriffe "Unittest" und "Dependency Injection" einfach falsch?

  • 0
Geschrieben (bearbeitet)

Du erzeugst beim Testen so immer eine Verbindung. Es sei denn du mockst das ganze Konstrukt. 

Hier: Statische Methoden vs. Statische "Daten". Statische Methoden, die einfach nur simple Funktionen ausführen, sind idR einfach und gut testbar. 

Gruß, Goulasz :goulasz: 

Bearbeitet von Goulasz
  • 0
Geschrieben
vor 4 Minuten schrieb Goulasz:

Du erzeugst beim Testen so immer eine Verbindung.

Wieso? Ich dachte jetzt eher an sowas:

	private static Connection con;
	public static void main(String[] args) {
	  Main.con =  ..bla
	}
	public static Connection getConnection() {
	  return Main.con;
	}
	

Dass du beim Testen nicht auf die echte Datenbank zugreifen solltest, sollte klar sein - aber ich wüsst nicht, was die "Dependency Injection" da dran ändern würde?

  • 0
Geschrieben

Die Main-Klasse wird ja nicht die einzige Klasse sein, die eine Datenbankverbindung benötigt. Wenn du nun in jeder anderen Klasse Main.getConnection() aufrufst, lassen sich die Klassen nicht mehr isoliert testen, weil sie Abhängig von Main sind. Du musst in jedem Test erst mal die main()-Methode aufrufen, weil die Methode die Verbindung aufbaut.

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Diese Frage beantworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...