Johann Mildner, Basel JEE – Web Component Developer Seminar JEE WEB Component Developer Seminar II _jeeWCDS-II-1.docx 1 Johann Mildner, Basel JEE – Web Component Developer Seminar JEE - Web Component Developer Seminar Teil II – Datenbanken Inhaltsverzeichnis JEE - Web Component Developer Seminar ......................................................................................... 2 Teil II – Datenbanken ...................................................................................................................... 2 Inhaltsverzeichnis............................................................................................................................. 2 Kapitel 7 ............................................................................................................................................... 3 Datenbanken..................................................................................................................................... 3 Datenbank H2 .............................................................................................................................. 3 Datenbank MySQL ...................................................................................................................... 3 Datenbank Oracle oder Postgres .................................................................................................. 3 Lib-Verzeichnisse ............................................................................................................................ 3 DRIVER, URL, USER, PASSWORD ............................................................................................. 4 DB Connection über DriverManager.getConnection() .................................................................... 5 DataSource ....................................................................................................................................... 8 TOMCAT ..................................................................................................................................... 8 JBOSS .......................................................................................................................................... 9 DB Connection über DataSource.getConnection() ........................................................................ 10 JPA – Java Persistence API ........................................................................................................... 12 Kapitel 8 – Workshops ....................................................................................................................... 15 Workshop 1 – Adressverwaltung ................................................................................................... 15 Workshop 2 – Gästebuch ............................................................................................................... 16 _jeeWCDS-II-1.docx 2 Johann Mildner, Basel JEE – Web Component Developer Seminar Kapitel 7 Datenbanken Datenbank H2 Installation Es muss nichts installiert werden. Es ist lediglich die Datei h2.jar erforderlich. Der User ist standardmässig sa und hat kein Passwort. Starten javaw -cp h2.jar org.h2.tools.Console -tcpAllowOthers Beenden Rechts-Klick auf das DB Icon im System Tray – EXIT Datenbank MySQL Installieren Sie XAMPP. Die Datenbank heisst test, der User root, das Passwort ist leer. Datenbank Oracle oder Postgres Wenn Sie Oracle oder Postgres installiert haben, können Sie auch mit diesen Datenbanken arbeiten. Sie müssen für die Datenbanken, mit denen Sie arbeiten eine jar-Datei in die lib-Verzeichnisse stellen. • h2.jar • mysql.jar • oracle.jar • postgres.jar Lib-Verzeichnisse • • entweder SERVER wenn man DataSource verwenden will $CATALINA_HOME/lib $JBOSS_HOME/server/default/lib oder PROJECT project/WEB-INF/lib _jeeWCDS-II-1.docx 3 Johann Mildner, Basel JEE – Web Component Developer Seminar DRIVER, URL, USER, PASSWORD Weiter unten wird immer wieder auf DRIVER, URL, USER und PASSWORD Bezug genommen. • • • • H2 o DRIVER o URL o USER o PASSWORD MySql o DRIVER o URL o USER o PASSWORD Postgres o DRIVER o URL o USER o PASSWORD Oracle o DRIVER o URL o USER o PASSWORD _jeeWCDS-II-1.docx = = = = "org.h2.Driver"; "jdbc:h2:tcp://localhost/~/test"; "SA"; ""; = = = = "com.mysql.jdbc.Driver"; "jdbc:mysql://localhost:3306/test"; "root"; ""; = = = = "org.postgresql.Driver"; "jdbc:postgresql://localhost:5432/jees"; "jees"; "jees"; = = = = "oracle.jdbc.driver.OracleDriver"; "jdbc:oracle:thin:@localhost:1521:xe"; "jees"; "jees"; 4 Johann Mildner, Basel JEE – Web Component Developer Seminar DB Connection über DriverManager.getConnection() Es benötigt lediglich die database.jar Files damit die DB-Treiber geladen werden können. In einem Java Programm oder eine JSP-Seite sind folgende 5 Schritte erforderlich: 1) Treiber registrieren und die Anwendung mit der Datenbank über den registrierten Treiber verbinden 2) SQL Anweisungsobjekt vorbereiten 3) SQL Anweisung ausführen 4) Resultat der SQL Anweisung verarbeiten 5) Verbindung mit Datenbank schliessen dbzugriff1.jsp <%@ <%@ <%@ <%@ <%@ page page page page page import="java.sql.DriverManager"%> import="java.sql.Connection"%> import="java.sql.Statement"%> import="java.sql.ResultSet"%> import="ch.wcds.tools.WebTools"%> <h1>DB Zugriff 1 - ohne DataSource</h1> <% String String String String URL DRIVER USER PASSWORD = = = = "jdbc:h2:tcp://localhost/~/test"; "org.h2.Driver"; "sa"; ""; String DROP = "drop table test1"; String SELECT = "select * from test1"; String CREATE = "create table test1(id int primary key, wert int)"; try { // 1 a) Treiber Registrieren Class.forName(DRIVER); // 1 b) Anwendung mit der Datenbank verbinden Connection conn = DriverManager.getConnection(URL, USER, PASSWORD); // 2) SQL Anweisungsobjekt vorbereiten Statement stm = conn.createStatement(); // 3) SQL Anweisungen ausfuehren try { stm.execute(DROP); } catch (Exception e) { } stm.execute(CREATE); for (int i = 1001; i <= 1015; i++) { stm.execute("insert into test1 values(" + i + "," + i * i + ")"); } _jeeWCDS-II-1.docx 5 Johann Mildner, Basel JEE – Web Component Developer Seminar ResultSet rs = stm.executeQuery(SELECT); // 4) Resultat der SQL Anweisung (SELECT) verarbeiten while (rs.next()) { int id = rs.getInt(1); int wert = rs.getInt(2); out.println(wert + " " + id + "<br/>"); } // 5) Verbindung mit Datenbank schliessen conn.close(); } catch (Exception e) { out.println("FEHLER AUFGETRETEN <br />" + e); } %> _jeeWCDS-II-1.docx 6 Johann Mildner, Basel JEE – Web Component Developer Seminar DbZugriff1Servlet.java package ch.wcds.servlets; import import import import import import import import import java.io.IOException; java.io.PrintWriter; java.sql.Connection; java.sql.DriverManager; java.sql.ResultSet; java.sql.Statement; javax.servlet.ServletException; javax.servlet.http.HttpServletRequest; javax.servlet.http.HttpServletResponse; public class DbZugriff1Servlet extends AbstractServlet { private final String DROP = "drop table test1"; private final String INSERT1 = "insert into test1 values(1,'hugo')"; private final String INSERT2 = "insert into test1 values(2,'max')"; private final String SELECT = "select * from test1"; private final String CREATE = "create table test1 (id int primary key, name varchar(100))"; private final String DRIVER = "org.h2.Driver"; private final String URL = "jdbc:h2:tcp://localhost/~/test"; private final String USER = "sa"; private final String PASSWD = ""; protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<h1>DbZugriff1 ...</h1>"); try { Class.forName(DRIVER); Connection connection = DriverManager.getConnection(URL,USER, PASSWD); Statement statement = connection.createStatement(); try { statement.execute(DROP); } catch (Exception e) { } statement.execute(CREATE); statement.execute(INSERT1); statement.execute(INSERT2); ResultSet resultSet = statement.executeQuery(SELECT); while (resultSet.next()) { out.println("<br />" + resultSet.getString("id") + " / " + resultSet.getString("name")); } connection.close(); } catch (Exception e) { out.println("FEHLER AUFGETRETEN <br />" + e); } out.close(); } } _jeeWCDS-II-1.docx 7 Johann Mildner, Basel JEE – Web Component Developer Seminar DataSource Das gerade gezeigte Vorgehen auf DB’s zuzugreifen ist für kleinere Objekte OK. In grösseren Projekten sollte man dem Web Container die Verantwortung für die Verbindung zur Datenbank überlassen. Dazu ist eine DataSource nötig. String JNDI_NAME="java:comp/env/jdbc/jeesH2"; InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(JNDI_NAME); Connection conn = ds.getConnection(); TOMCAT Im Verzeichnis META-INF des Projekts muss die Datei context.xml stehen. context.xml <Context> <Resource name="jdbc/jeesH2" auth="Container" type="javax.sql.DataSource" driverClassName="org.h2.Driver" url="jdbc:h2:tcp://localhost/~/test" username="sa" password="" /> <Resource name="jdbc/jeesMySql" auth="Container" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/test" username="root" password="" /> <Resource name="jdbc/jeesPostgres" auth="Container" type="javax.sql.DataSource" driverClassName="org.postgres.Driver" url="jdbc:postgresql://localhost:5432/jees" username="jees" password="jees" /> <Resource name="jdbc/jeesOracle" auth="Container" type="javax.sql.DataSource" driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:xe" username="jees" password="jees" /> </Context> _jeeWCDS-II-1.docx 8 Johann Mildner, Basel JEE – Web Component Developer Seminar JBOSS Im Verzeichnis $JBOSS_HOME/server/default/deploy muss eine XML-Datei mit dem Namen ***-ds.xml stehen. jees-ds.xml <datasources> <local-tx-datasource> <jndi-name>jdbc/jeesH2</jndi-name> <connection-url>jdbc:h2:tcp://localhost/~/test</connection-url> <driver-class>org.h2.Driver</driver-class> <user-name>sa</user-name> <password></password> </local-tx-datasource> <local-tx-datasource> <jndi-name>jdbc/jeesMySql</jndi-name> <connection-url>jdbc:mysql://localhost:3306/test</connection-url> <driver-class>com.mysql.jdbc.Driver</driver-class> <user-name>root</user-name> <password></password> </local-tx-datasource> </datasources> In WEB-INF muss jboss-web.xml stehen. jboss-web.xml <?xml version="1.0" encoding="UTF-8"?> <jboss-web> <resource-ref> <res-ref-name>jdbc/jeesH2</res-ref-name> <res-type>javax.sql.DataSource</res-type> <jndi-name>java:jdbc/jeesH2</jndi-name> </resource-ref> <resource-ref> <res-ref-name>jdbc/jeesMySql</res-ref-name> <res-type>javax.sql.DataSource</res-type> <jndi-name>java:jdbc/jeesMySql</jndi-name> </resource-ref> </jboss-web> Es würde auch ohne jboss-web.xml gehen. Dann wäre aber lookout("java:comp/env/jdbc/jeesOracle") auf lookout("java:jdbc/jeesOracle") abzuändern. _jeeWCDS-II-1.docx 9 Johann Mildner, Basel JEE – Web Component Developer Seminar DB Connection über DataSource.getConnection() Es sind hier ebenso die 5 Schritte erforderlich. Der Schritt 1 ändert sich aber. dbzugriff2.jsp <%@ <%@ <%@ <%@ <%@ <%@ page page page page page page import="java.sql.Connection"%> import="java.sql.ResultSet"%> import="java.sql.Statement"%> import="javax.naming.InitialContext"%> import="javax.servlet.jsp.JspWriter"%> import="javax.sql.DataSource"%> <h1>DB Zugriff 2 - mit DataSource ...</h1> <% String String String String DROP = "drop table test1"; SELECT = "select * from test1"; CREATE = "create table test1(id int primary key, wert int)"; JNDI_NAME = "java:comp/env/jdbc/jeesH2"; try { InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(JNDI_NAME); Connection conn = ds.getConnection(); Statement stm = conn.createStatement(); try { stm.execute(DROP); } catch (Exception e) { } stm.execute(CREATE); for (int i = 2001; i <= 2015; i++) { stm.execute("insert into test1 values(" + i + "," + i * i + ")"); } ResultSet rs = stm.executeQuery(SELECT); while (rs.next()) { int id = rs.getInt(1); int wert = rs.getInt(2); out.println(wert + " " + id + "<br/>"); } conn.close(); } catch (Exception e) { out.println("FEHLER AUFGETRETEN <br />" + e); } %> _jeeWCDS-II-1.docx 10 Johann Mildner, Basel JEE – Web Component Developer Seminar DbZugriff2Servlet.java package ch.wcds.servlets; import import import import import import java.io.*; java.sql.*; javax.naming.InitialContext; javax.servlet.ServletException; javax.servlet.http.*; javax.sql.DataSource; public class DbZugriff2Servlet extends AbstractServlet { private final String DROP = "drop table test1"; private final String CREATE = "create table test1 (id int primary key, name varchar(100))"; private final String INSERT1 = "insert into test1 values(1,'hugo')"; private final String INSERT2 = "insert into test1 values(2,'max')"; private final String SELECT = "select * from test1"; String JNDI_NAME = "java:comp/env/jdbc/jeesH2"; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<h1>DbZugriff2 ...</h1>"); try { InitialContext ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup(JNDI_NAME); Connection connection = ds.getConnection(); Statement statement = connection.createStatement(); try { statement.execute(DROP); } catch (Exception e) { } statement.execute(CREATE); statement.execute(INSERT1); statement.execute(INSERT2); ResultSet resultSet = statement.executeQuery(SELECT); while (resultSet.next()) { out.println("<br />" + resultSet.getString("id") + " / " + resultSet.getString("name")); } connection.close(); } catch (Exception e) { out.println("FEHLER AUFGETRETEN <br />" + e); } out.close(); } } _jeeWCDS-II-1.docx 11 Johann Mildner, Basel JEE – Web Component Developer Seminar JPA – Java Persistence API Eine weitere Möglichkeit, Datenbank Zugriffe zu realisieren bietet JPA. JPA in Servlets und JSPs wird nur in Tomcat verwendet. Soll JPA auch in JBoss verwendet werden, nutzt man EJB’s. Der JPA Provider soll EclipseLink sein. Wie für alle DB Zugriffe braucht es die JAR-Files mit den DB-Treibern. Zusätzlich benötigt es für Tomcat noch die beiden EclipseLink-JAR-Files • elipselink.jar • javax.persistence.jar die nach projekt/WEB-INF/lib kopiert werden müssen. Des Weiteren benötigt es ein persistence.xml File das im CLASSPATH gefunden werden muss (src/META-INF/persistence.xml). src/META-INF/persistence.xml <?xml version="1.0" encoding="UTF-8" ?> <!-- persistence.xml WCDS JPA 2.0 ECLIPSELINK JTA=RESOURCE_LOCAL --> <persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"> <!-- persistence-unit name=|H2|MYSQL|ORACLE|POSTGRES| --> <!-- eclipselink.ddl-generation=|none|create-tables|drop-and-create-tables| --> <!-- eclipselink.logging.level=|OFF|SEVERE|WARNING|INFO|CONFIG|FINE|FINER|FINEST|ALL| --> <!-- eclipselink.ddl-generation.output-mode=|sql-script|database|both| --> <persistence-unit name="H2" transaction-type="RESOURCE_LOCAL"> <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> <exclude-unlisted-classes>false</exclude-unlisted-classes> <properties> <property name="javax.persistence.jdbc.driver" value="org.h2.Driver" /> <property name="javax.persistence.jdbc.url" value="jdbc:h2:tcp://localhost/~/test"/> <property name="javax.persistence.jdbc.user" value="sa" /> <property name="javax.persistence.jdbc.password" value="" /> <property name="eclipselink.ddl-generation" value="drop-and-create-tables" /> <property name="eclipselink.logging.level" value="finer" /> <property name="eclipselink.ddl-generation.output-mode" value="both" /> </properties> </persistence-unit> </persistence> _jeeWCDS-II-1.docx 12 Johann Mildner, Basel JEE – Web Component Developer Seminar Person.java @Entity public class Person { @Id @GeneratedValue private int id; private String name; public Person() { } public Person(String name) { this.name = name; } // getter und setter @Override public String toString() { return "Person [id=" + id + ", name=" + name + "]"; } } dbzugriff3.jsp <%@ page import="java.sql.*"%> <%@ page import="javax.naming.*"%> <%@ page import="javax.servlet.jsp.*"%> <%@ page import="javax.persistence.*"%> <%@ page import="ch.wcds.entities.*"%> <h1>DB Zugriff 3 -­‐ mit JPA ...</h1> <% EntityManagerFactory emf = Persistence.createEntityManagerFactory("H2"); EntityManager em = emf.createEntityManager(); Person p = new Person("fritz"); em.getTransaction().begin(); em.persist(p); em.getTransaction().commit(); em.close(); out.println(p); %> _jeeWCDS-II-1.docx 13 Johann Mildner, Basel JEE – Web Component Developer Seminar DbZugriff3Servlet.java package ch.wcds.servlets; import java.io.*; import javax.persistence.*; import javax.servlet.*; import javax.servlet.http.*; import ch.wcds.entities.Person; public class DbZugriff3Servlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<h1>DbZugriff3 ...</h1>"); EntityManagerFactory emf = Persistence.createEntityManagerFactory("H2"); EntityManager em = emf.createEntityManager(); Person p = new Person("hugo"); em.getTransaction().begin(); em.persist(p); em.getTransaction().commit(); em.close(); out.println(p); out.close(); } } _jeeWCDS-II-1.docx 14 Johann Mildner, Basel JEE – Web Component Developer Seminar Kapitel 8 – Workshops Nutzen Sie Eclipse für Ihre Workshop Projekte – new Project, Web, Dynamic Web Workshop 1 – Adressverwaltung Die erste Aufgabe für unseren Workshop ist es, einen Adressbestand pflegen zu können. Die Adressdaten sollen in H2 oder MySql gespeichert werden. Fest verdrahtet im Programm aber leicht änderbar. Die Datenbank Connection soll über den DriverManager gemacht werden. Grund: dieses kleine Projekt soll in jedem WEB-Server deployed werden können und ohne Anpassungen laufen. Der Web Server hat keine Ahnung von den Datenbanken. Dazu ist es nötig, dass alle benötigten DB-jar-Files im lib-Verzeichnis des Projekts vorhanden sind. Eingabe: addrVerw.jsp Die Eingabemaske soll ein Formular beinhalten. Die Aktionen im Formular sollen in ein Servlet zur Erstellung einer JavaBean führen. ADRESSVERWALTUNG ID NAME ADDR CREATE DROP SELECT INSERT UPDATE DELETE Verarbeitung: AddrVerwServlet.java Das Servlet liest die Parameter aus der Eingabe, erstellt eine Bean in der die Parameter verarbeitet werden und ein Ergebnis erstellt wird, speichert diese Bean mit Scope REQUEST ab. Das Ergebnis wird in einer JSP ausgegeben. Ausgabe: addrVerw.jsp Ausgabe des Ergebnisses aus der ErgebnisBean. Diese Bean könnte eventuell gleich wieder das Formular für eine erneute Aktion beinhalten. Da die Ausgabe meistens auch das Eingabeformular beinhaltet (Fehlerkorrektur muss möglich sein) wird die Eingabe und die Ausgabe im selben JSP gemacht. Zu erstellende Artefakte: 1. AddrVerw.jsp 2. AddrVerwServlet.java 3. AddrVerwBean.java 4. Address.java 5. AddressDAO.java _jeeWCDS-II-1.docx 15 Johann Mildner, Basel JEE – Web Component Developer Seminar Workshop 2 – Gästebuch Die zweite Aufgabe in unseren Workshop ist es, ein Gästebuch zu erstellen. Auch hier sollte darauf geachtet werden, dass als Datenbanken sowohl H2 als auch MySql dienen können. Der Zugriff auf die Datenbanken soll über DataSources und DAO’s gemacht werden. Des Weiteren soll das Gästebuch sowohl in Tomcat als auch in JBOSS ausgeführt werden können. Dieses Projekt könnte auch mit JPA realisiert werden (optional). Tabellen: gbUser (name ,passw ,email ); gbEntry (id ,date ,userName ,stichwort ,text ); varchar(8) primary key varchar(8) varchar(40) int primary key timestamp varchar(8) references gbUser(name) varchar(20) varchar(500) Use Cases: Login: Ein Benutzer kann sich einloggen: Als neuer User anmelden: Ist der Benutzer noch nicht registriert, kann er sich neu registrieren. Anzeigen Einträge des Gästebuches: Alle Einträge werden tabellarisch angezeigt. Die einzelnen Einträge können vom Verfasser geändert oder gelöscht werden. Erfassen eines neuen Eintrags im Gästebuch: Ein User kann einen neuen Eintrag erstellen Administration: Der Administrator (admin/admin) kann die Datenbank auswählen (H2/MySql/Oracle) und die Tabellen neu aufsetzten (drop/create). _jeeWCDS-II-1.docx 16 Johann Mildner, Basel JEE – Web Component Developer Seminar Workflow welcome.jsp login.jsp ANMELDEN/NEW_USER => LoginServlet.java ANMELDEN,ID,PW ID und PW muessen in DB sein USER -> REQUEST GB Daten in DB_BEAN speichern DB_BEAN –> REQUEST => anzeigen.jsp NEW_USER,ID,PW ID und PW duerfen nicht in DB sein USER wird erfasst (newUser.jsp) und in DB gespeichert => LoginServlet (ANMELDEN, ID, PW) HOME => welcome.jsp anzeigen.jsp welcome.jsp WCDS - Gaestebuch Dies ist eine Uebung im Zuge des Web Component Developer Seminars. Es freut mich, dass Sie mein Gaestebuch besuchen. Es ist jetzt ... Mon Nov 13 09:00:00 CET 2006 Ihre Glueckszahl koennte sein ... 408 Nachdem Sie sich eingeloggt haben, koennen Sie sich die Eintraege im Gaestebuch ansehen, neue Eintraege erfassen und eigene Eintraege loeschen oder aendern. Sollten Sie Ihre User Id oder Ihr Passwort vergessen haben, melden Sie sich einfach als neuer User an. Keine Sorge, Sie koennen das System nicht zumuellen. Ihre Eintraege werden sowieso nicht gelesen und immer wieder geloescht. Der Weg ist das Ziel. LOGIN ADMIN _jeeWCDS-II-1.docx 17 Johann Mildner, Basel JEE – Web Component Developer Seminar login.jsp Login UserID joe Passwort london ANMELDEN NEW_USER HOME anzeigen.jsp Anzeigen Gaestebuch EINTRAG VERFASSEN User: joe die letzten Eintraege DELETE UPDATE SELECT 1 1 2006-10-24 HUGO WAS HERE DELETE UPDATE SELECT 2 1 2006-10-24 HUGO WAS HERE AGAIN DELETE UPDATE SELECT 3 2 2006-10-24 MORITZ WAS HERE DELETE UPDATE SELECT 4 2 2006-10-24 MORITZ WAS HERE AGAIN HOME insert.jsp update.jsp delete.jsp _jeeWCDS-II-1.docx 18 Johann Mildner, Basel JEE – Web Component Developer Seminar Zu erstellende Artefakte: 1. welcome.jsp (login/admin) 2. 3. 4. admin.jsp AdminServlet.java AdminBean.java (useDB/create/drop/HOME) 5. 6. 7. login.jsp LoginServlet.java LoginBean.java (anmelden/newUser/HOME) 8. anzeigen.jsp (eintragVerfassen/HOME) 9. eintragVerfassen.jsp 10. EintragVerfassenServlet.java 11. EintragVerfassenBean.java 12. GaestebuchDAO.java 13. GbUser.java 14. GbEntry.java 15. Tools.java 16. DBTools.java 17. ServiceLocator.java _jeeWCDS-II-1.docx 19