Cours WebApps-servlets 2014
Transcription
Cours WebApps-servlets 2014
Architectures Outils Java Servlets État servlet JSP Accès BD Conception 231 Plan Architectures n-tiers et applications Web Outils Java et applications Web Servlets État d’un servlet Les JSP Accès aux BD avec servlets Conception Olivier Perrin, Université de Lorraine LicencePro, 2014 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Rappels JDBC: API qui permet de stocker, ‣ de rechercher, ‣ de manipuler les données et les structures d’une source de données ‣ JDBC est constitué de deux parties API JDBC ‣ JDBC Driver Manager qui s’occupe de la communication avec la base de données ‣ Olivier Perrin, Université de Lorraine LicencePro, 2014 232 Architectures Outils Java Servlets État servlet JSP Accès BD Conception 233 JDBC - Rappels (2)Types JDBC Data Types JDBC JDBC Type Java Type BIT TINYINT SMALLINT INTEGER BIGINT REAL FLOAT DOUBLE BINARY VARBINARY LONGVARBINARY CHAR VARCHAR LONGVARCHAR 8 JDBC boolean byte short int long float double byte[] String JDBC Type NUMERIC DECIMAL DATE TIME TIMESTAMP CLOB BLOB ARRAY DISTINCT STRUCT REF JAVA_OBJECT Java Type BigDecimal java.sql.Date java.sql.Timestamp Clob* Blob* Array* mapping of underlying type Struct* Ref* underlying Java class *SQL3 data type supported in JDBC 2.0 Olivier Perrin, Université de Lorraine LicencePro, 2014 www.moreservlets.com Architectures Outils Java Servlets État servlet JSP Accès BD JDBC - Rappels (3) Étapes ‣ ‣ ‣ ‣ ‣ ‣ ‣ charger le driver JDBC pour le SGBD considéré définir la connexion établir la connexion créer un objet Statement exécuter la requête gérer le résultat (ResultSet) fermer la connexion Olivier Perrin, Université de Lorraine LicencePro, 2014 Conception 234 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Étapes Chargement du driver try { // optionnel désormais ! Class.forName("oracle.jdbc.driver.OracleDriver"); } catch { ClassNotFoundException cnfe) { ! System.out.println("Error loading driver: " + cnfe); } Définition de l’URL de connexion String host= "hoteDB.serveur.fr"; String dbName = "nomBase"; int port = 1234; String oracleURL = "jdbc:oracle:thin:@" + host + ":" + port + ":" ! ! ! ! ! ! ! ! ! ! ! + dbName; Olivier Perrin, Université de Lorraine LicencePro, 2014 235 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Étapes (2) Établir la connexion String user = "olivier"; String pass = "lmdpalc"; Connection connection = ! ! ! ! ! DriverManager.getConnection(oracleURL, user, pass); Possibilité d’avoir des informations sur la base DatabaseMetaData dbMetaData = connection.getMetaData(); String productName = dbMetaData.getDatabaseProductName(); System.out.println("Database: " + productName); String productVersion = dbMetaData.getDatabaseProductVersion(); System.out.println("Version: " + productVersion); Olivier Perrin, Université de Lorraine LicencePro, 2014 236 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Étapes (3) Créer un objet Statement Statement statement = ! ! ! ! ! ! ! connection.createStatement(); Exécuter la requête String query = "SELECT col1, col2, col3 FROM sometable"; ResultSet resultSet = statement.executeQuery(query); pour modifier la base, executeUpdate ‣ ne pas hésiter à utiliser setQueryTimeout pour fixer un délai maximum ‣ Olivier Perrin, Université de Lorraine LicencePro, 2014 237 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Étapes (4) Gérer le résultat while(resultSet.next()) { ! System.out.println(!resultSet.getString(1) + " " + ! ! ! ! ! ! ! ! ! ! resultSet.getString(2) + " " + ! ! ! ! ! ! ! ! ! ! ! resultSet.getString(3)); } la première colonne possède l’indice 1, pas 0 ‣ ResultSet fournit les méthodes getXXX pour récupérer les données à partir de l’indice ou du nom de colonne ‣ on a également accès aux méta-données du résultat ‣ Fermer la connexion connection.close(); Olivier Perrin, Université de Lorraine LicencePro, 2014 238 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Méta-données Méta-données système connection.getMetaData().getDatabaseProductName() ‣ connection.getMetaData().getDatabaseProductVersion() ‣ … ‣ Méta-données table resultSet.getMetaData().getColumnCount() ‣ resultSet.getMetaData().getColumnName() ‣ … ‣ Olivier Perrin, Université de Lorraine LicencePro, 2014 239 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Statement Les instructions SQL sont transmises au SGBD via l’objet Statement Trois types d’objets Statement ‣ Statement • pour exécuter une requête SQL simple ‣ PreparedStatement • pour exécuter une requête SQL précompilée avec passage de paramètres ‣ CallableStatement • pour exécuter une procédure stockée au niveau du SGBD Olivier Perrin, Université de Lorraine LicencePro, 2014 240 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Statement (2) Quelques méthodes executeQuery() ‣ exécute la requête SQL et renvoie les résultats dans un ResultSet ResultSet results = ! ! ! ! ! ! statement.executeQuery("SELECT a, b FROM table"); executeUpdate() pour les instructions SQL UPDATE, INSERT, DELETE ‣ renvoie le nombre de n-uplets affectés par la modification ‣ support des instructions DDL (CREATE/DROP/ALTER table) ‣ int rows = statement.executeUpdate("DELETE FROM EMPLOYEES " + ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! "WHERE STATUS=0"); Olivier Perrin, Université de Lorraine LicencePro, 2014 241 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Statement (3) execute() ‣ méthode générique pour les procédures stockées ou requêtes précompilées getMaxRows/setMaxRows fixe le nombre de n-uplets qu’un ResultSet doit contenir ‣ par défaut, illimité ‣ getQueryTimeout/setQueryTimeout ‣ délai après lequel le driver renverra une exception SQLException Olivier Perrin, Université de Lorraine LicencePro, 2014 242 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Statement (4) Requêtes précompilées Idée utilisation multiple d’une requête, avec utilisation de paramètres ‣ créer une requête classique, puis l’envoyer au SGBD pour compilation ‣ instanciation des paramètres avec setXXX ‣ Méthodes héritées de Statement, mais sans paramètres ‣ execute() ‣ executeQuery() ‣ executeUpdate() Olivier Perrin, Université de Lorraine LicencePro, 2014 243 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Statement (5) Exemple Connection connection = ! ! ! DriverManager.getConnection(url, user, password); PreparedStatement statement = ! ! ! connection.prepareStatement("UPDATE employees "+ ! ! ! ! ! ! ! ! ! "SET salary = ? " + ! ! ! ! ! ! ! ! ! "WHERE id = ?"); int[] newSalaries = getSalaries(); int[] employeeIDs = getIDs(); for(int i=0; i<employeeIDs.length; i++) { ! statement.setInt(1, newSalaries[i]); ! statement.setInt(2, employeeIDs[i]); ! statement.executeUpdate(); } Olivier Perrin, Université de Lorraine LicencePro, 2014 244 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Statement (6) Intérêt dans le cas des servlets les paramètres sont obtenus à partir d’un formulaire ‣ la requête est précompilée pour les accès multiples ‣ les paramètres sont transmis grâce à setXXX ‣ clearParameters permet de tout réinitialiser ‣ si des caractères spéciaux sont nécessaires, utiliser setString sur l’objet preparedStatement ‣ Olivier Perrin, Université de Lorraine LicencePro, 2014 245 Architectures Outils Java Servlets État servlet JSP Accès BD Conception JDBC - Transactions Possibilité de préciser le comportement Par défaut, pas de commit connection.setAutoCommit(false) Appel de commit pour valider les modifications de manière permanente Appel de rollback pour annuler les modifications Olivier Perrin, Université de Lorraine LicencePro, 2014 246 Architectures Outils Java Servlets État servlet JSP Accès BD Conception Servlet et JDBC Accès par le servlet de données stockées dans un SGBD Initialisation dans init() Fermeture dans destroy() Penser généricité: driver, URL, utilisateur, mot de passe dans web.xml ‣ associer une référence vers la ressource BD ‣ <resource-ref> ! <description>Ma base de données</description> ! <res-ref-name>jdbc/EmployeDB</res-ref-name> ! <res-type>javax.sql.dataSource</res-type> ! <res-auth>Container</res-auth> </resource-ref> Olivier Perrin, Université de Lorraine LicencePro, 2014 247 Architectures Outils Java Servlets État servlet JSP Accès BD Conception Servlet et JDBC (2) <resource-ref> ! <description>Ma base de données</description> ! <res-ref-name>jdbc/EmployeDB</res-ref-name> ! <res-type>javax.sql.dataSource</res-type> ! <res-auth>Container</res-auth> </resource-ref> Code Context ctx = new InitialContext(); DataSource ds = (DataSource)envContext.lookup(“jdbc/EmployeDB”); Connection conn = ds.getConnection(); … conn.close(); Olivier Perrin, Université de Lorraine LicencePro, 2014 248 Architectures Outils Java Servlets État servlet JSP Accès BD Conception Servlet et JDBC (3) Remplacé désormais par l’annotation @Resource @Resource(name=”jdbc/EmployeDB”) private DataSource ds; Connection conn = ds.getConnection(); … conn.close(); Ce code fait 2 choses: déclaration d’une dépendance de composant d’environnement “java:comp/env/jdbc/EmployeDB” ‣ enregistre le champ “ds” pour l’injection de dépendance ‣ Olivier Perrin, Université de Lorraine LicencePro, 2014 249