Programmierkurs

Werbung
Programmierkurs – Kapitel 2
Dipl.-Wirt.-Inf. Stefan Fleischer
Dipl.-Wirt.-Inf. Ulrich Wolffgang
Programmierkurs
Komponente: Persistierung
Interface für Persistenzschicht entwickeln
import java.net.URL;
import java.util.ArrayList;
public interface IDatabase {
public void saveEmailAddresses(ArrayList<String> emailaddresses)
throws Exception;
public void saveUrls(ArrayList<URL> urls) throws Exception;
public void setUrlVisited(URL url) throws Exception;
public URL getRandomUrl() throws Exception;
}
Programmierkurs
1
Entwicklungsfolie für die Tafel
Datenbanksystem
Problem: Java-Programm verliert Speicherwerte nach
Beendigung des Programms
Lösung: Zur Persistierung wird ein dauerhafter
Speicher benutzt  eine Datenbank
Verbreitete Datenbanksysteme: PostgreSQL, MySQL,
MSQL, Oracle Database, SQLite
Auswahlkriterien
Lizenz  Nutzbarkeit, Preis
Dokumentation  Best-Practices
Verbreitung  Dokumentation, Unterstützung in Foren
Technisch  Performance, Datensicherheit, Standardabdeckung
Toolsupport  Interaktion mit DBS ermöglichen
Programmierkurs
2
MySQL
Für den Kurs wird MySQL genutzt
GPL als Lizenz
Dokumentation unter www.mysql.com
Verbreitung sehr hoch, vor allem bei dynamischen Websites
Technisch: zuverlässig, Performance OK für unsere Zwecke,
unterstützt SQL1999/SQL3
Toolsupport sehr gut: MySQL Admin, MySQL Query Browser,
mysqldump, phpMyAdmin, …
Download des Community Server: www.mysql.com
Installationsprozess zeigen (UTF8)
Tools zeigen
Programmierkurs
3
Installation eines MySQL Community Servers
Programmierkurs
4
Installation eines MySQL Community Servers
Programmierkurs
5
Installation eines MySQL Community Servers
Programmierkurs
6
Installation eines MySQL Community Servers
Programmierkurs
7
Konfiguration des MySQL Community Servers
Programmierkurs
8
Konfiguration des MySQL Community Servers
Programmierkurs
9
Konfiguration des MySQL Community Servers
Programmierkurs
10
Konfiguration des MySQL Community Servers
Programmierkurs
11
Konfiguration des MySQL Community Servers
Programmierkurs
12
Konfiguration des MySQL Community Servers
Programmierkurs
13
Konfiguration des MySQL Community Servers
Programmierkurs
14
Konfiguration des MySQL Community Servers
Programmierkurs
15
Konfiguration des MySQL Community Servers
Programmierkurs
16
Konfiguration des MySQL Community Servers
Programmierkurs
17
MySQL Tools
MySQL Administrator
MySQL Query Browser
Programmierkurs
18
MySQL
User Account Management
User haben Zugriffsrechte auf Datenbanken/Tabellen/Spalten und
damit auf Datensätze
Account: Name, Passwort
Resource-Limits
SSL-Connections
Beispiel: Neuen Nutzer anlegen
GRANT SELECT, INSERT, UPDATE ON db.* TO
‚username‘@‚localhost‘ IDENTIFIED BY ‚password‘;
flush privileges;
Auf „ernstzunehmenden“ Produktivsystemen sollte die reguläre
Interaktion nicht mit root-Rechten erfolgen!
Programmierkurs
19
MySQL-Treiber für Java bekannt machen
Problem: Java Virtual Machine muss wissen, wo
MySQL-Treiber zu finden ist
Lösung: Java-Classpath
Pfadangabe für Java Virtual Machine, wo beim Ausführen von JavaProgrammen nach Klassen und Paketen gesucht werden soll.
Classpath soll auf MySQL-Treiber zeigen.
Alternative 1: Systemweit
Auf der Konsole (Eingabeaufforderung
) eingeben:
set CLASSPATH=% CLASSPATH%; C:\mysql-connector-java-5.1.5bin.jar;
Alternative 2 für den Kurs: Eclipse-Projekt-weit
MySQL-Treiber in Eclipse-Project auf folgende Weise dem Classpath
hinzufügen:
Programmierkurs
20
MySQL-Treiber für Java bekannt machen
Programmierkurs
21
MySQL-Treiber für Java bekannt machen
Programmierkurs
22
Datenmanagement
SQL
Funktionalität auf Metadaten
Create: CREATE DATABASE dbname;
Create: CREATE TABLE tblname (id INT, …);
Read: SHOW TABLES;
Update: ALTER TABLE tblname CHANGE …;
Delete: DROP TABLE tblname;
Funktionalität auf Datensätzen
Create: INSERT INTO tblname (colname, …) VALUES („wert“, …);
Read: SELECT expr FROM tblnames WHERE wherecond;
Update: UPDATE tblname SET (colname=„wert“, …);
Delete: DELETE FROM tblname WHERE wherecond;
PRIMARY KEY, INDEX, UNIQUE (für URLs)
Programmierkurs
23
MySQL-Typen
In den Tabellen der Datenbank ist jede Spalte typisiert
Einige MySQL-Typen:
INT: Zahl zwischen -2147483648 und 2147483647
TINYINT: Zahl zwischen -128 und 127
VARCHAR(M): String der maximalen Länge von M Zeichen, z. B.
VARCHAR(255)
CHAR(M): String der Länge von M Zeichen, z. B. CHAR(255)
TEXT: Text mit maximaler Länge 65535
DATETIME: Datum im Format ‚YYYY-MM-DD HH:MM:SS‘, z. B.
2012-12-31 23:59:59
Programmierkurs
24
Datenmanagement
SQL
CREATE TABLE person (id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
INTEGER id
VARCHAR(255) name
ALTER TABLE person CHANGE name vorname VARCHAR(255) CHARACTER
SET utf8 COLLATE utf8_general_ci NOT NULL;
INTEGER id
VARCHAR(255) vorname
INSERT INTO person (vorname) VALUES ("Charlie");
INTEGER id
VARCHAR(255) vorname
1
Charlie
Programmierkurs
25
Datenmanagement
SQL
INSERT INTO person (vorname) VALUES ("John");
INTEGER id
VARCHAR(255) vorname
1
Charlie
2
John
Feld id wird automatisch inkrementiert.
UPDATE person SET vorname = "Stephen" WHERE person.id = 1;
INTEGER id
VARCHAR(255) vorname
1
Stephen
2
John
Programmierkurs
26
Datenmanagement
SQL
SELECT * FROM person WHERE vorname = "Stephen" LIMIT 0,30;
SELECT * FROM person WHERE vorname LIKE "Ste%" LIMIT 0,30;
INTEGER id
vorname
1
Stephen
DELETE FROM person WHERE person.id = 2;
INTEGER id
VARCHAR(255) vorname
1
Stephen
2
John
DROP TABLE person;
INTEGER id
VARCHAR(255) vorname
1
Stephen
Programmierkurs
27
Datenstrukturen und Algorithmen
Index
Warum Indexe?
Schnelleres Finden von Datensätzen bestimmter Spaltenwerte
Entsprechende Spalte muss indiziert sein
Bei 1000 Datensätzen ist die Suche über einen Index ca. 100 mal
schneller als die sequentielle Suche
Verschiedene Index-Arten:
Index allgemein (INDEX): Beschleunigt Suche auf Feldern
CREATE TABLE person (id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (id),
INDEX namensindex (name)
) ENGINE = MYISAM CHARACTER SET utf8 COLLATE utf8_general_ci;
Indexe mit erweiterter Semantik: Primärschlüssel (PRIMARY KEY),
Eindeutiger Index (UNIQUE), Index zur Volltextsuche (FULLTEXT)
Programmierkurs
28
Datenmanagement
Datenbank fachkonzeptionell: ERM
Datenmodell der Datenbank
URL
E-MailAdresse
Programmierkurs
29
(0,m)
(1,m)
Datenmanagement
Datenbank Implementierung: SQL
Auf Verbindung zwischen URL und Emailaddresse
(Relationshiptyp) hier verzichtet  Vorlesung
Datenmanagement
CREATE TABLE url (
tld CHAR(5) NOT NULL,
sld VARCHAR(255) NOT NULL,
uld VARCHAR(255) DEFAULT NULL,
visited TINYINT(4) NOT NULL DEFAULT '0',
PRIMARY KEY (sld,tld),
INDEX visited (visited)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
CREATE TABLE emailaddress (
emailaddress VARCHAR(255) NOT NULL,
PRIMARY KEY (emailaddress)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
Programmierkurs
30
Entwicklungsfolie für die Tafel
JDBC
Java Database Connectivity
Datenbankschnittstelle der Java-Plattform für einheitlichen Zugriff auf
Datenbanken verschiedener Hersteller.
Ermöglicht, Datenbankverbindungen aufzubauen, abzubauen, SQLAnfragen an Datenbank zu stellen.
Setzt für jede spezifische Datenbank Treiber voraus.
Beispiel: Verbindung zur MySQL-Server aufbauen
import java.sql.*; //Nicht com.mysql.jdbc
String url = "jdbc:mysql://" + host + "/" + database;
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection connection = DriverManager.getConnection(url, username, password);
Programmierkurs
31
JDBC
Beispiel: SELECT eine Zeile
Statement s = connection.createStatement();
s.executeQuery("SELECT id, name FROM animal LIMIT 0,1"); //eine Zeile anfragen
ResultSet rs = s.getResultSet();
rs.next ();
int idVal = rs.getInt("id");
String nameVal = rs.getString("name");
rs.close();
s.close();
Beispiel: SELECT mehrere Zeilen
Statement s = connection.createStatement();
s.executeQuery("SELECT id, name FROM animal"); //alle Zeilen anfragen
ResultSet rs = s.getResultSet();
while (rs.next ()) { //über Datensätze iterieren
int idVal = rs.getInt("id");
String nameVal = rs.getString("name");
}
rs.close();
s.close();
Programmierkurs
32
JDBC
Beispiel: INSERT eine Zeile
String cmd = "INSERT INTO animal (name) VALUES (?)";
PreparedStatement s = connection.prepareStatement(cmd);
s.setString(1, name);
s.executeUpdate();
s.close();
Beispiel: UPDATE alle Zeilen, auf die WHERE passt
String cmd = "UPDATE animal SET name = ‘Lion’ WHERE name = ? AND age > ?";
PreparedStatement s = connection.prepareStatement(cmd);
s.setString(1, „Cat“);
s.setInt(2, age);
s.executeUpdate();
s.close();
Programmierkurs
33
SQL Injection
Einschleusen von Datenbankbefehlen
Problem: Fehlende Maskierung von Benutzereingaben
Benutzereingaben http://webserver/find.cgi?ID=42
-> SELECT text FROM artikel WHERE ID=42
Problemfall
http://webserver/find.cgi?ID=42;UPDATE+USER+SET+TYPE="admin"+WHERE+ID=23
-> SELECT text FROM artikel WHERE ID=42; UPDATE USER SET
TYPE="admin" WHERE ID=23
Lösung bei JDBC: Prepared Statement
PreparedStatement pstmt = con.prepareStatement("SELECT text FROM
artikel WHERE id = ?"); //? Ist Platzhalter für Wert
pstmt.setString(1, idParam); //idParam wird automatisch escaped
ResultSet rset = pstmt.executeQuery(); //Query ausführen
Programmierkurs
34
Hilfestellungen
Schritt 1: Interface von Folie 2 nach Eclipse kopieren
Schritt 2: Klasse Database als Singleton anlegen
public class Database implements IDatabase {
private Connection connection;
private static Database instance;
private Database() {}
public static Database getInstance() {
if (instance == null)
instance = new Database();
return instance;
}
public void saveUrls(ArrayList<URL> urls) throws Exception {
…
}
…
}
Programmierkurs
35
Hilfestellungen
public void saveEmailAddresses(ArrayList<String> emailAddresses) throws Exception{
//if mysql connection is closed or not established, yet
//connect to mysql server
//for each email address
//create sql statement for inserting email address into table emailaddress
//create prepared statement from sql statement
//set parameter
//execute prepared statement
//close prepared statement
}
Programmierkurs
36
Hilfestellungen
public void saveUrls(ArrayList<URL> urls) throws Exception {
//if mysql connection is closed or not established, yet
//connect to mysql server
//for each url
//split host of url in parts
//find top level domain (tld)
//find second level domain (sld)
//find upper level domain (uld)
//create sql statement for inserting values of tld, sld, uld and visited
into table url
//build a prepared statement
//set parameters in prepared statement
//execute the prepared statement
//close the prepared statement
}
Programmierkurs
37
Hilfestellungen
public void setUrlVisited(URL url) throws Exception {
//if mysql connection is closed or not established, yet
//connect to mysql server
//split host of url in parts
//find top level domain (tld)
//find second level domain (sld)
//create sql statement for updating table url. Set visited to 1, where tld and
sld match.
//create prepared statement
//set parameters
//execute prepared statement
//close prepared statement
}
Programmierkurs
38
Hilfestellungen
public URL getRandomUrl() throws Exception {
//if mysql connection is closed or not established, yet
//connect to mysql server
//create sql statement for selecting uld, sld, tld from table url where
visited is 0, limit to 1 row
//create prepared statement
//execute prepared statement
//get result set
//select next/first result in result set
//build URL from result
//close result set
//close prepared statement
//return url
}
Programmierkurs
39
Hilfestellungen
Klasse java.net.URL
Neue URL erstellen:
URL url = new URL("http://www.google.com");
URL zerlegen in top level domain (tld), sld und uld
String[] parts = url.getHost().split("\\.");
int length = parts.length;
String tld=""; //com
if(length > 2)
tld = parts[parts.length-1];
String sld=""; //google
if(length > 2)
sld = parts[parts.length-2];
String uld=""; //www
if(length > 2)
uld = parts[parts.length-3];
Programmierkurs
40
Herunterladen