Benutzer-Werkzeuge

Webseiten-Werkzeuge


api:documentation:database:start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
api:documentation:database:start [2022/06/08 09:33] – [2. Datenbankverbindung herstellen] Martin Pabstapi:documentation:database:start [2023/05/15 13:16] (aktuell) – [3. Daten in die Datenbank schreiben] Martin Pabst
Zeile 1: Zeile 1:
 ====== Datenbankverbindung ====== ====== Datenbankverbindung ======
 <WRAP center round warning 80%> <WRAP center round warning 80%>
-Legt man in der SQL-IDE eine Datenbank an, so kann man von Java-Programmen in der Online-IDE aus lesend und schreibend darauf zugreifen. Dies ist leider nicht von den Programmierkästen der Embedded-IDE aus möglich, daher lassen sich die Beispiele unten nicht direkt auf dieser Seite ausführen, sondern nur, wenn man sie in die Online-IDE kopiert und den Code "XYZ" durch einen korrekten Datenbankzugriffscode aus der SQL-IDE ersetzt.+Legt man in der SQL-IDE eine Datenbank an, so kann man von Java-Programmen in der Online-IDE aus lesend und schreibend darauf zugreifen. Dies ist leider nicht von den Programmierkästen der Embedded-IDE aus möglich, daher lassen sich die Beispiele unten nicht direkt auf dieser Seite ausführen, sondern nur, wenn man sie in die Online-IDE kopiert und den Code "1Ts8qXH77X" durch einen korrekten Datenbankzugriffscode aus der SQL-IDE ersetzt.
 </WRAP> </WRAP>
  
Zeile 14: Zeile 14:
 <HTML> <HTML>
  
-<div class="java-online" style="height: 150px; width: 70%" data-java-online="{'withBottomPanel': false, 'id': 'db1'}">+<div class="java-online" style="height: 350px; width: 80%" data-java-online="{'withBottomPanel': false, 'id': 'db1'}">
  
 <script type="text/plain" title="DBRead.java"> <script type="text/plain" title="DBRead.java">
 +// Dieses Beispiel lässt sich nur von der Online-IDE aus ausführen, nicht von www.learnj.de aus.
 +// Zuvor müssen Sie den Verbindungs-Code 1Ts8qXH77X durch den Ihrer eigenen Datenbank ersetzen.
 Connection c = DatabaseManager.getConnection("1Ts8qXH77X"); Connection c = DatabaseManager.getConnection("1Ts8qXH77X");
  
Zeile 38: Zeile 40:
  
  
 +<WRAP center round info 80%>
 +**Zum Vorgehen:** \\ 
 +  * Zunächst holt man sich mit ''Connection c = DatabaseManager.getConnection("1Ts8qXH77X");'' ein ''Connection''-Objekt. Dieses repräsentiert die Verbindung zur Datenbank.
 +  * ''Statement st = c.createStatement();'' baut mit Hilfe dieser Datenbankverbindung ein ''Statement''-Objekt, das es ermöglicht, Anweisungen an die Datenbank zu senden.
 +  * ''ResultSet rs = st.executeQuery("select name from fluss where name = 'S%'");'' schickt nun die als Zeichenkette übergebene SQL-Anweisungen an die Datenbank. Diese führt die Anweisung aus, baut ein ''ResultSet''-Objekt und verschafft diesem Zugriff auf die Ergebnistabelle. Das ''ResultSet''-Objekt wird von der ''executeQuery''-Anweisung zurückgegeben.
 +  * Das ''ResultSet''-Objekt kann nun die einzelnen Zeilen der Ergebnistabelle ( = "Datensätze") holen. Dazu besitzt es einen "Zeiger", der auf den aktuellen Datensatz zeigt. Anfangs zeigt er auf keinen Datensatz.
 +  * Die Methode "next()" des ''ResultSet''-Objekts bewegt den "Zeiger" jeweils eins weiter und gibt genau dann ''true'' zurück, wenn das Ende der Tabelle noch nicht erreicht ist.
 +  * Mit den Methoden ''getString(spaltenbezeichner)'', ''getInt(spaltenbezeichner)'' usw. können nun die Zellinhalte des aktuellen Datensatzes geholt werden.
 +</WRAP>
 +
 +===== 3. Daten in die Datenbank schreiben =====
 +
 +<WRAP center round info 80%>
 +Beim Schreiben geht man vor wie beim Lesen, nur dass jetzt die Methode ''executeUpdate'' des Statement-Objekts verwendet wird. \\ \\ 
 +**Spezialfall: auto_increment** \\ 
 +Fügt man einer Tabelle mittels ''insert into...'' einen Datensatz hinzu und besitzt diese einen Integer-Primärschlüssel, der automatisch vergeben wird (SQL-Schlüsselwort ''autoincrement''), so gibt die Anweisung ''executeUpdate'' den automatisch vergebenen Primärschlüssel zurück. Ansonsten gibt sie den Wert ''0'' zurück.
 +</WRAP>
 +
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 350px; width: 80%" data-java-online="{'withBottomPanel': false, 'id': 'db2'}">
 +
 +<script type="text/plain" title="DBRead.java">
 +// Dieses Beispiel lässt sich nur von der Online-IDE aus ausführen, nicht von www.learnj.de aus.
 +// Zuvor müssen Sie den Verbindungs-Code 1Ts8qXH77X durch den Ihrer eigenen Datenbank ersetzen.
 +Connection c = DatabaseManager.getConnection("1Ts8qXH77X");
 +
 +Statement st = c.createStatement();
 +
 +String statement = """
 +   insert into fluss(fnr, name, zielfnr, meer, laenge)
 +   values
 +   ('SAR', 'Sandrach', 'DOU', null, 40)
 +   """;
 +   
 +st.executeUpdate(statement);
 +</script>
 +
 +</div>
 +
 +</HTML>
 +
 +==== Schreibender Zugriff mit prepared statement: ====
 +<HTML>
 +
 +<div class="java-online" style="height: 350px; width: 80%" data-java-online="{'withBottomPanel': false, 'id': 'db2a'}">
 +
 +<script type="text/plain" title="DBWriteWithPreparedStatements.java">
 +Connection c = DatabaseManager.getConnection("asdfj82hkhlTi");
 +
 +String statement = """
 +update fluss set name = ? where FNR = ?
 +""";
 +
 +PreparedStatement st = c.prepareStatement(statement);
 +String neuerName = "Sanga_neu";
 +String fnr = "SAG";
 +
 +st.setString(1, neuerName);
 +st.setString(2, fnr);
 +st.executeUpdate();
 +
 +</script>
 +
 +</div>
 +
 +</HTML>
 +===== 4. Prepared Statements =====
 +
 +<WRAP center round info 80%>
 +Kommen Teile einer SQL-Anweisung von einer Benutzereingabe, z.B. 
 +<code java>
 +String name = Input.readString("Bitte geben Sie Ihren Namen ein");
 +String password = Input.readString("Bitte geben Sie Ihr Passwort ein");
 +String statement = "select * from user where name ='" + name + ' and password = '" + password + "'" ;
 +</code>
 +so kann ein Benutzer mittels [[https://de.wikipedia.org/wiki/SQL-Injection|SQL-Injection]] unberechtigt Daten abgreifen, in diesem Beispiel, indem er als Name eingibt: ''Barack Obama' and (' '= ' '' und als Passwort: ''test' or true) and ' ' = ' ''. \\ 
 +Dann wird aus dem Statement nämlich
 +<code sql>
 +select * from user where name = 'Barack Obama' and (' ' = ' ' and password = 'test' or true) and ' ' = ' '
 +</code>
 +Da ''and'' stärker bindet als ''or'', ergibt der Wert des Terms in Klammern immer ''true''. Dadurch bekommt der Nutzer Zugriff auf den Datensatz von Barack Obama. \\ \\ 
 +Ein gutes Mittel, um dies zu verhindern, sind **Prepared Statements**. Die Idee besteht darin, vom Benutzer eingegebene Bestandteile nicht durch Aneinanderhängen von Zeichenketten in eine SQL-Anweisung einzubauen, sondern als Parameterwert mit an die Datenbank zu übergeben. Die Datenbank behandelt diese Parameter dann wie Zeichenketten Werte. Diese dürfen beliebige Zeichen enthalten und werden nie als SQL-Schlüsselwörter interpretiert, sondern immer als Konstante. \\ \\ 
 +Die Stellen, an denen in der SQL-Anweisung Parameterwerte eingefügt werden sollen, werden mit ''?'' gekennzeichnet, z.B.
 +<code java>
 +String statement = """
 +select name from fluss 
 +where name like ?
 +""";
 +
 +PreparedStatement st = c.prepareStatement(statement);
 +</code>
 +
 +Mittels ''st.setString(index, value)'', ''st.setInt(index, value)'' usw. können dann die Werte definiert werden, die statt der ''?'' eingefügt werden sollen. Der ''index'' startet dabei ungewöhnlicherweise nicht bei ''0'', sondern bei ''1''. Mittels
 +<code java>
 +st.setString(1, "Donau");   // Ersetzt den Wert des ersten Fragezeichens im statement
 +</code>
 +wird das erste ''?'' durch '' 'Donau' '' ersetzt. Anschließend wird das Statement durch
 +<code java>
 +ResultSet rs = st.executeQuery();
 +</code>
 +an die Datenbank geschickt. Natürlich gibt es auch ''st.executeUpdate()'' für datenverändernde Anweisungen (''insert'', ''update'', ...).
 +</WRAP>
 +
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 400px; width: 80%" data-java-online="{'withBottomPanel': false, 'id': 'db3'}">
 +
 +<script type="text/plain" title="DBRead.java">
 +// Dieses Beispiel lässt sich nur von der Online-IDE aus ausführen, nicht von www.learnj.de aus.
 +// Zuvor müssen Sie den Verbindungs-Code 1Ts8qXH77X durch den Ihrer eigenen Datenbank ersetzen.
 +Connection c = DatabaseManager.getConnection("1Ts8qXH77X");
 +
 +String statement = """
 +select name from fluss 
 +where name like ?
 +""";
 +
 +PreparedStatement st = c.prepareStatement(statement);
 +
 +String flussName = Input.readString("Bitte geben Sie den Namen eines Flusses ein:");
 +st.setString(1, flussName);   // Ersetzt den Wert des ersten Fragezeichens im statement
 +
 +ResultSet rs = st.executeQuery();
 +
 +while(rs.next()) {
 +   println(rs.getString("name"));
 +}
 +</script>
 +
 +</div>
 +
 +</HTML>
 +
 +
 +<WRAP center round tip 80%>
 +Möchte man von Java aus viele gleichartige Statements hintereinander an die Datenbank schicken, z.B. zum Verändern von Daten, so bringen Prepared Statements nicht nur einen Sicherheitsgewinn, sondern auch einen Geschwindigkeitsvorteil: Man ruft ''PreparedStatement st = c.prepareStatement(statement);'' nur ein Mal auf, gefolgt von vielen abwechselnden ''st.setString'' und ''st.executeUpdate()''-Aufrufen. Das SQL-Statement wird von der Datenbank in diesem Fall nur ein einziges Mal kompiliert (beim Aufruf von ''prepareStatement'').
 +</WRAP>
  
api/documentation/database/start.1654673637.txt.gz · Zuletzt geändert: 2022/06/08 09:33 von Martin Pabst

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki