MySQL Neuen Datensatz mit "new" anlegen

Dimadon

Aktives Mitglied
Hallo Leute,

ich bin ganz frisch hier und würde mich wirklich sehr freuen wenn der ein oder andere mir bei meinem Problem behilflich sein könnte.
Ich schreibe derzeit an einem kleinen Pinnwand_Programm. Hierzu habe ich eine locale Datenbankanbindung geschrieben und eine Mapperklasse die nach der Fertigstellung des Programms mit der Datenbank sprechen soll. Mit der Insert Methode hat alles wunderbar funktioniert nur möchte ich nun wissen ob meine MappeKlasse funktioniert. Hierzu habe eine kleine Testklasse(TestCon) angelegt die nun mit new einen neuen User anlegen soll. Sprich über diese Klasse zum Mapper der sich die Datenbankanbindung holt und schließlich den Datensatz in den Datenbank einbindet.

Hier der Code:
Java:
public class TestCon {
	
	public static void main(String[] args){
	
		User a = new User();
		a.setVorname("Jens");
		a.setNachname("Merkel");
		a.setNickname("merkelj");
		UserMapper.userMapper().insert(a);
	}
          }

Java:
public class UserMapper {

	private static UserMapper userMapper = null;

  
  protected UserMapper() {
  }


  public static UserMapper userMapper() {
    if (userMapper == null) {
      userMapper = new UserMapper();
    }

  return userMapper;
  }

 
  public User
  	findByKey(int Uid) {
    // DB-Verbindung holen
    Connection con = LocalDBConnection.connection();

    try {
//      Leeres SQL-Statement (JDBC) anlegen
      Statement stmt = con.createStatement();

      // Statement ausfüllen und als Query an die DB schicken
      ResultSet rs = stmt
          .executeQuery("SELECT Uid, vorname, nachname, nichkname FROM users "
              + "WHERE Uid=" + Uid + " ORDER BY lastName");

      /*
       * Da id Primärschlüssel ist, kann max. nur ein Tupel zurückgegeben
       * werden. Prüfe, ob ein Ergebnis vorliegt.
       */
      if (rs.next()) {
        // Ergebnis-Tupel in Objekt umwandeln
        User c = new User();
        c.setUid(rs.getInt("Uid"));
        c.setVorname(rs.getString("vorname"));
        c.setNachname(rs.getString("nachname"));
        c.setNickname(rs.getString("nickname"));

        return c;
      }
    }
    catch (SQLException e) {
      e.printStackTrace();
      return null;
    }

    return null;
  }

  /**
   * Auslesen aller Kunden.
   * 
   * @return Ein Vektor mit Customer-Objekten, die sämtliche Kunden
   *         repräsentieren. Bei evtl. Exceptions wird ein partiell gef�llter
   *         oder ggf. auch leerer Vetor zurückgeliefert.
   */
  public Vector<User> findAll() {
    Connection con = LocalDBConnection.connection();
    // Ergebnisvektor vorbereiten
    Vector<User> result = new Vector<User>();

    try {
      Statement stmt = con.createStatement();

      ResultSet rs = stmt.executeQuery("SELECT Uid, vorname, nachname, nickname "
          + "FROM users " + "ORDER BY lastName");

      // Für jeden Eintrag im Suchergebnis wird nun ein Customer-Objekt
      // erstellt.
      while (rs.next()) {
        User c = new User();
        c.setUid(rs.getInt("Uid"));
        c.setVorname(rs.getString("vorname"));
        c.setNachname(rs.getString("nachname"));
        c.setNickname(rs.getString("nickanme"));

        // Hinzufügen des neuen Objekts zum Ergebnisvektor
        result.addElement(c);
      }
    }
    catch (SQLException e) {
      e.printStackTrace();
    }

    // Ergebnisvektor zurückgeben
    return result;
  }

  /**
   * Auslesen aller Kunden-Objekte mit gegebenem Nachnamen
   * 
   * @param name Nachname der Kunden, die ausgegeben werden sollen
   * @return Ein Vektor mit Customer-Objekten, die sämtliche Kunden mit dem
   *         gesuchten Nachnamen repräsentieren. Bei evtl. Exceptions wird ein
   *         partiell gefüllter oder ggf. auch leerer Vetor zurückgeliefert.
   */
  public Vector<User> findByNachname(String name) {
    Connection con = LocalDBConnection.connection();
    Vector<User> result = new Vector<User>();

    try {
      Statement stmt = con.createStatement();

      ResultSet rs = stmt.executeQuery("SELECT Uid, vorname, nachname, nickname "
              + "FROM users " + "ORDER BY lastName");


      // Für jeden Eintrag im Suchergebnis wird nun ein Customer-Objekt
      // erstellt.
      while (rs.next()) {
        User c = new User();
        c.setUid(rs.getInt("Uid"));
        c.setVorname(rs.getString("firstName"));
        c.setNachname(rs.getString("lastName"));

        // Hinzufügen des neuen Objekts zum Ergebnisvektor
        result.addElement(c);
      }
    }
    catch (SQLException e) {
      e.printStackTrace();
    }

    // Ergebnisvektor zurückgeben
    return result;
  }

  /**
   * Einfügen eines <code>Customer</code>-Objekts in die Datenbank. Dabei wird
   * auch der Primärschlüssel des übergebenen Objekts geprüft und ggf.
   * berichtigt.
   * 
   * @param c das zu speichernde Objekt
   * @return das bereits übergebene Objekt, jedoch mit ggf. korrigierter
   *         <code>id</code>.
   */
  public User insert(User c) {
    Connection con = LocalDBConnection.connection();
    

    try {
      Statement stmt = con.createStatement();

      /*
       * Zunächst schauen wir nach, welches der momentan höchste
       * Primärschlüsselwert ist.
       */
      ResultSet rs = stmt.executeQuery("SELECT MAX(Uid) AS maxid "
          + "FROM users ");

      // Wenn wir etwas zurückerhalten, kann dies nur einzeilig sein
      if (rs.next()) {
        /*
         * c erhält den bisher maximalen, nun um 1 inkrementierten
         * Primärschlüssel.
         */
        c.setUid(rs.getInt("maxid") + 1);

        stmt = con.createStatement();

        // Jetzt erst erfolgt die tatsächliche Einfügeoperation
        stmt.executeUpdate("INSERT INTO users (Uid, vorname, nachname, nickname) "
            + "VALUES (" + c.getUid() + ",'" + c.getVorname() + "','"
            + c.getNachname() +  ",'" + c.getNickname() +"')");
      }
    }
    catch (SQLException e) {
      e.printStackTrace();
    }

    /*
     * Rückgabe, des evtl. korrigierten Customers.
     * 
     * HINWEIS: Da in Java nur Referenzen auf Objekte und keine physischen
     * Objekte übergeben werden, wäre die Anpassung des Customer-Objekts auch
     * ohne diese explizite Rückgabe au�erhalb dieser Methode sichtbar. Die
     * explizite Rückgabe von c ist eher ein Stilmittel, um zu signalisieren,
     * dass sich das Objekt evtl. im Laufe der Methode verändert hat.
     */
    return c;
  }

  /**
   * Wiederholtes Schreiben eines Objekts in die Datenbank.
   * 
   * @param c das Objekt, das in die DB geschrieben werden soll
   * @return das als Parameter übergebene Objekt
   */
  public User update(User c) {
    Connection con = LocalDBConnection.connection();

    try {
      Statement stmt = con.createStatement();

      stmt.executeUpdate("UPDATE users " + "SET vorname=\""
          + c.getVorname() + "\", " + "nachname=\"" + c.getNachname() + "\" , " + "nickname=\"" + c.getNickname() + "\" "
          + "WHERE Uid=" + c.getUid());

    }
    catch (SQLException e) {
      e.printStackTrace();
    }

    // Um Analogie zu insert(Customer c) zu wahren, geben wir c zurück
    return c;
  }

  /**
   * Löschen der Daten eines <code>Customer</code>-Objekts aus der Datenbank.
   * 
   * @param c das aus der DB zu löschende "Objekt"
   */
  public void delete(User c) {
    Connection con = LocalDBConnection.connection();

    try {
      Statement stmt = con.createStatement();

      stmt.executeUpdate("DELETE FROM users " + "WHERE Uid=" + c.getUid());
    }
    catch (SQLException e) {
      e.printStackTrace();
    }
  }

Java:
public class LocalDBConnection {
	 
	private static Connection con = null;

	public static Connection connection() {
		
		
		// Wenn es bisher keine Conncetion zur DB gab, ... 
		
			try {
				
				Class.forName("com.mysql.jdbc.Driver").newInstance();
				
				Connection con = DriverManager.getConnection(
						"jdbc:mysql://localhost/socialmediapinnwand","","");
				con.setReadOnly(false);
				con.close();
			}
		

			catch(Exception e){
			
				System.out.println("*****FEHLER*****->" +e);
			}

		
		// Zurückgegeben der Verbindung
		return con;
		
	}

Es wäre echt super wenn mir hier jemand weiterhelfen kann.
 

Dimadon

Aktives Mitglied
Danke für das rasche Feedback. Das Problem ist das ich bei der Ausführung immer eine NullPointerException bekomme und die Daten nicht eingetragen werden. Ich weiß leider nicht woran es liegt. Mir ist bekannt was der NullPointerException ist aber was ich hierbei falsch gemacht habe ist mir leider nicht klar....

Edit: Den NullPointerException erhalten ich für:

Java:
UserMapper.userMapper().insert(a);

und

Java:
      Statement stmt = con.createStatement();
 
Zuletzt bearbeitet:

Dimadon

Aktives Mitglied
Per Consolenausgabe erhalte ich folgenden Bericht:

Exception in thread "main" java.lang.NullPointerException
at de.hdm.socialmediapinnwand.server.UserMapper.insert(UserMapper.java:148)
at de.hdm.socialmediapinnwand.server.TestCon.main(TestCon.java:9)
 
Zuletzt bearbeitet:

BRoll

Bekanntes Mitglied
Also deine Connection ist null, das ist dein Problem.
Das Verbinden funktioniert, sonst würde es den "FEHLER" schmeissen.

Dein Problem ist, dass du die connection gleich wieder schließt bevor du sie zurückgibst.

con.close(); erst aufrufen wenn du die Verbindung schließen möchtest,
also keine Daten mehr lesen oder anlegen.

Deshalb sagts dir auch null-pointer, weil con.close() die connection wohl
auf null setzt danach.
 

Dimadon

Aktives Mitglied
Ok...Dank dir schonmal...Und wie kann ich das beheben? Habe mal versucht die close nach der Rückgabe zu setzen, jedoch ohne Erfolg. Die Fehlermeldung bleibt leider :(
 

BRoll

Bekanntes Mitglied
Close garnicht aufrufen xDD

Erst wenn du dein Programm schließt, oder wenn du nur diesen einen Testaufruf
machst, dann nach dem Adden eines neuen Accounts.
 

Dimadon

Aktives Mitglied
Leider ohne Erfolg...Auch wenn ich die con.close() komplett weglasse erhalte ich die Exception in thread "main" java.lang.NullPointerException....
 

turtle

Top Contributor
Neben den richtigen Antworten, ist mir noch ein weiterer grober Schnitzer aufgefallen.

Dieses nennen wir Check-then-act Problem und bedeutet, das du etwas prüfst, hier die maximale ID in der DB, und darauf eine Entscheidung aufbaust (hier Einfügen eines Datensatzes).

Aber natürlich kann in der Zeit zwischen Lesen der maximalen ID und der weiteren Ausführung jemand anderes bereits einen Datensatz eingefügt haben und wenn du das versuchst, knallt die DB mit einem Fehler, weil die ID doch nicht so eindeutig war.

Daher ist es angebrachter diese Arbeit die DB machen zu lassen. In praktisch allen DB gibt es eine Möglichkeit eine ID automatisch inkrementieren zu lassen. In mySQL nennt sich das dann AUTO_INCREMENT, in anderen Sequenz,...

Desweiteren gebe ich den Ratschlag, besser Prepared-Statements zu nutzen und NICHT per String-Bastelei einen SQL-Befehl zusammen zubauen.
Dein Ansatz ist anfällig gegen sogenannte SQL-Injection Angriffe und dieses ist ein schwerwiegendes Problem, welches einfach durch Prepared-Statements verhindert werden kann.

Dein NPE-Problem rührt anscheinend daher, das du die Connection nicht richtig verwaltest. Dieses ist oft der Fall, zumal man eigentlich "gepoolte" Connections verwendet. Das sollte ein Framework, was du statt "plain" JDBC nehmen solltest, bereits anbieten.
 

BRoll

Bekanntes Mitglied
Ok hab dein Fehler jetzt gefunden.

Schau dir nochmal genau an welche Connection du zurückgibst.

Als Tip:

beachte den Unterschied zwischen lokaler und Klassenvariable.

return this.con != return con in deinem Fall.

Du hast zwei verschieden con Objekte, da du einmal als
Instanz und einmal als Methodenvariable die Connection con
initialisierst.

Wahrscheinlich ein übersehener Leichtsinnsfehler xD
(Deshalb hab ichs auch jetzt erst bemerkt)
 

Dimadon

Aktives Mitglied
@ turtle: Danke für den Hinweiß bezüglicher des Fehlers. Auto_Inkrement habe ich mir bereits überlegt einzubauen. Aber ich habe hier nicht so weit gedacht wie du :) Macht aber sicher Sinn.

Dein Hinweiß zu meinem Fehler kann ich leider nicht ganz nachvollziehen. Worin liegt genau mein Fehler jetzt? Im Aufbau der Anbindung oder etwa wo anders?
 

BRoll

Bekanntes Mitglied
Hier
Java:
    public class LocalDBConnection {
         
        private static Connection con = null;
     
        public static Connection connection() {
           
           
            // Wenn es bisher keine Conncetion zur DB gab, ...
           
                try {
                   
                    Class.forName("com.mysql.jdbc.Driver").newInstance();
                   
                    Connection con = DriverManager.getConnection(
                            "jdbc:mysql://localhost/socialmediapinnwand","","");
                    con.setReadOnly(false);
                    con.close();
                }
           
     
                catch(Exception e){
               
                    System.out.println("*****FEHLER*****->" +e);
                }
     
           
            // Zurückgegeben der Verbindung
            return con;
           
        }

Diese Zeile:
Java:
        Connection con = DriverManager.getConnection(
                            "jdbc:mysql://localhost/socialmediapinnwand","","");

Da darf Connection natürlich nicht nochmal stehen, sondern nur
Java:
con = DriverManager.getConnection(
                            "jdbc:mysql://localhost/socialmediapinnwand","","");

Sonst bleibt dein eigentliches con objekt null wie oben zu Anfangs zugewiesen.
 

Dimadon

Aktives Mitglied
Super dank dir.....Ist ja auch logisch wenn man es sieht :) OH man.... Jetzt läuft der Fehler nicht mehr...

Jedoch erhalte ich keinen Eintrag in der Datenbank... und diese Fehlermeldung :(

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'merkelj)' at line 1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:525)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
at com.mysql.jdbc.Util.getInstance(Util.java:384)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1052)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4232)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:4164)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2615)
at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2776)
at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2832)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1755)
at com.mysql.jdbc.StatementImpl.executeUpdate(StatementImpl.java:1679)
at de.hdm.socialmediapinnwand.server.UserMapper.insert(UserMapper.java:182)
at de.hdm.socialmediapinnwand.server.TestCon.main(TestCon.java:21)
 
Zuletzt bearbeitet:

BRoll

Bekanntes Mitglied
Die Meldung ist doch jetzt logisch :D

Du hast wohl noch ein Fehler in deiner SQL Syntax.

Das hängt jetzt davon ab was das für eine Datenbank ist und wie deine
Daten aussehen.

Probier am besten vorher deine SQL Statements direkt in der Datenbank
mit Selektionsskripten aus, und bau sie dann erst in dein programm aus wenn
du weißt dass sie stimmen.
 

Dimadon

Aktives Mitglied
Ok Fehler gefunden....Nun noch eine Fragen: Es wird zwar ein Datensatz eingepflegt jedoch ohne Inhalt..Muss ich den Vor- bzw. Nachnamen anders deklarieren?

Update: Fehler gefunden: Hatte '...' vergessen....

Ich danke euch sehr bei der Hilfe...Tolles Forum, tolle Leute:applaus:
 
Zuletzt bearbeitet:
Ähnliche Java Themen
  Titel Forum Antworten Datum
Eldorado MySQL Hibernate - neuen Datensatz einfügen Datenbankprogrammierung 2
D SQLite INSERT OR REPLACE INTO macht neuen Eintrag?! Datenbankprogrammierung 2
J Java DB Neuen Eintrag am Anfang der Table Datenbankprogrammierung 6
P Mittels Java einen neuen MySQL User erstellen Datenbankprogrammierung 4
S Daten einer Tabelle vergleichen und ggs neuen Wert einfügen Datenbankprogrammierung 8
D Erstellen einer neuen Datenbank Datenbankprogrammierung 3
G Verwendung neuen Treiber für JDBC-Zugriff auf OracleDB Datenbankprogrammierung 5
P Fehlermeldung beim Erstellen einer neuen Tabelle Datenbankprogrammierung 2
F SQLite Datensatz löschen Datenbankprogrammierung 13
B Mit Button einen Datensatz löschen Datenbankprogrammierung 2
S sql query, um bestimten datensatz zu finden Datenbankprogrammierung 33
E Nur der letzte Datensatz wird in Tabelle geschrieben Datenbankprogrammierung 4
M Serienbrief aus Datensatz Datenbankprogrammierung 2
E Aufzählung liest nur ersten Datensatz Datenbankprogrammierung 14
S SQLite Selectanfrage lieft datensatz aber cursor ist leer Datenbankprogrammierung 2
M Designfrage zu Rows die sich auf einen Datensatz derselben Tabelle beziehen Datenbankprogrammierung 7
A MySQL Datensatz wird nicht richtig gelöscht Datenbankprogrammierung 6
L SQLite fügt nur den ersten Datensatz ein Datenbankprogrammierung 2
C Hibernate Datensatz löschen Datenbankprogrammierung 2
M Access Datensatz beinhaltet ESC-Zeichen Datenbankprogrammierung 3
U Nur den ersten Datensatz löschen wenn mehrere gleiche da sind Datenbankprogrammierung 2
C Gleichzeitiger Zugriff auf Datensatz Datenbankprogrammierung 5
Java.getSkill() Datensatz / Tupel automatisch nach xy Tagen / Stunden löschen Datenbankprogrammierung 7
M Datensatz exklusiv öffnen Datenbankprogrammierung 5
M design issue: datensatz lange locken? Datenbankprogrammierung 10
M Datensatz aus Datenbank löschen Datenbankprogrammierung 6
T Theoriefrage : mehrere User vs gleichen Datensatz Datenbankprogrammierung 4
K Schnelle Methode um zu testen ob Datensatz existiert Datenbankprogrammierung 9
R datenbank - datensatz sucjen Datenbankprogrammierung 4
-MacNuke- Hibernate löscht jeden Datensatz einzeln? Datenbankprogrammierung 12
V Doppelten Datensatz vermeiden? Datenbankprogrammierung 7
S Überprüfen ob Datensatz existiert Datenbankprogrammierung 2
P SQL, nur jeder 5. Datensatz Datenbankprogrammierung 9
B Eingefügter Datensatz erneut abfragen. Datenbankprogrammierung 10
J Anzeige Button gibt immer nur 1. Datensatz aus DB aus Datenbankprogrammierung 8
M Letzter Datensatz mit auslesen(brauch kleinen Tipp) Datenbankprogrammierung 15
N SELECT: Datensatz sperren Datenbankprogrammierung 6
C vorheriegen oder letzten Datensatz Datenbankprogrammierung 2
K ResultSet: Erste Zeile ausgeben, Datensatz in String speiche Datenbankprogrammierung 13
W Nur ein Datensatz wird angezeigt, obwohl mehrere existieren Datenbankprogrammierung 7
C Datensatz einfügen und quittierung Datenbankprogrammierung 31
H letzter Datensatz wird nicht gefunden? Datenbankprogrammierung 6
F suche MySQl-Befehl um Datensatz an Tabellenende zu schreiben Datenbankprogrammierung 2
C Datenbank anlegen und über eine Website mit Daten füllen? Datenbankprogrammierung 25
B MySQL installieren - silent / User anlegen Datenbankprogrammierung 3
L Neue Zeile in DB anlegen Datenbankprogrammierung 3
R MySQL Frage zum Anlegen von Artikeln inkl. Verbindungen Datenbankprogrammierung 0
P MySQL Historie für ein Objekt anlegen Datenbankprogrammierung 5
S Derby/JavaDB Probleme beim anlegen einer embedded DB Datenbankprogrammierung 13
S Problem beim Anlegen einer Tabelle Datenbankprogrammierung 5
A Kundendaten anlegen oder gleich in DB schreiben? Datenbankprogrammierung 8
G Mit Java-Programm Datenbank löschen/neu anlegen Datenbankprogrammierung 5
G Wie seine Datenbankklassen anlegen? Datenbankprogrammierung 7
G HSQLDB als Dateien anlegen Datenbankprogrammierung 5
G embedded H2; wie tables anlegen? Datenbankprogrammierung 3
L Datenbank anlegen, . Datenbankprogrammierung 9

Ähnliche Java Themen

Neue Themen


Oben