Utilisation de DBCP2, Archive, JDBC, Archive, Apache Pool, Archive et Apache Logging, Archive (installation).
Cette méthode utilise executeQuery
qui ne protège pas contre les risques d'injection. prepareStatement
de la méthode 2 est préférable si la requête contient des données saisies par l'utilisateur.
package org.llgc; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import org.apache.commons.dbcp2.BasicDataSource; public class SQL1 { public static void main (String[] args) { try (BasicDataSource bds = new BasicDataSource ()) { bds.setDriverClassName ("com.mysql.jdbc.Driver"); String url = "jdbc:mysql://localhost/elearning"; bds.setUrl (url); bds.setUsername ("root"); bds.setPassword ("aui"); try (Connection cn = bds.getConnection (); Statement st = cn.createStatement ()) { ResultSet rs = st.executeQuery ("SELECT * FROM civilite"); ResultSetMetaData rsmd = rs.getMetaData (); int NbCol = rsmd.getColumnCount (); for (int i = 1; i <= NbCol; i++) { System.out.print (rsmd.getColumnName (i) + "\t"); } System.out.println (); while (rs.next ()) { for (int i = 1; i <= NbCol; i++) { System.out.print (rs.getString (i) + "\t"); } System.out.println (); } } } catch (SQLException e) { e.printStackTrace (); return; } } }
Les indices dans les fonctions SQL commencent généralement à 1.
Protection contre les risques d'injection par l'utilisation de la méthode prepareStatement
.
DriverManager
n'a besoin que de la librairie JBDC
(Connector/J
).
DriverManager
ne doit être utilisé qu'en test et pas en production Why do we use a DataSource instead of a DriverManager? Archive du 04/03/2013 le 26/04/2020.
package org.llgc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class SQL2 { public static void main (String[] args) { try { Class.forName ("com.mysql.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace (); return; } String url = "jdbc:mysql://localhost/elearning"; try (Connection cn = DriverManager.getConnection (url, "root", "aui"); PreparedStatement pstmt = cn .prepareStatement ("INSERT INTO civilite (LibelleCourt, LibelleLong) Values (?, ?)");) { pstmt.setString (1, "Pr"); pstmt.setString (2, "Président"); // Compilation au niveau serveur pstmt.executeUpdate (); pstmt.clearParameters (); pstmt.setString (1, "Ch"); pstmt.setString (2, "Chien"); // Méthode en cache au niveau serveur pstmt.executeUpdate (); } catch (SQLException e) { e.printStackTrace(); return; } } }
package modeles; public class Film { private String titre; private Integer annee; public Film() { } public void setTitre(String leTitre) { titre = leTitre; } public void setAnnee(Integer lAnnee) { annee = lAnnee; } public String getTitre() { return titre; } public Integer getAnnee() { return annee; } }
package modeles; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class TestsJdbc { private static final Integer port = 3306; /** * Pour communiquer avec MySQL */ private Connection connexion; /** * Constructeur sans connexion */ public TestsJdbc() throws ClassNotFoundException { /* On commence par "charger" le pilote MySQL */ Class.forName("com.mysql.jdbc.Driver"); } public void connect(String server, String bd, String u, String p) throws SQLException { String url = "jdbc:mysql://" + server + ":" + port + "/" + bd; connexion = DriverManager.getConnection(url, u, p); } public List<Film> chercheFilms() throws SQLException { List<Film> resultat = new ArrayList<Film>(); Statement statement = connexion.createStatement(); ResultSet films = statement.executeQuery("SELECT * FROM Film"); while (films.next()) { Film film = new Film(); film.setTitre(films.getString("titre")); film.setAnnee(films.getInt("annee")); resultat.add(film); } // Et on renvoie return resultat; } }
package controleurs; import java.io.IOException; import java.sql.ResultSet; import java.util.List; import java.util.Map; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import modeles.Film; import modeles.TestsJdbc; /** * Servlet implementation class Jdbc */ @WebServlet("/jdbc") public class Jdbc extends HttpServlet { /** * */ private static final long serialVersionUID = 1353888533525324020L; private static final String SERVER = "localhost", BD = "webscope", LOGIN = "orm", PASSWORD = "orm", VUES = "/vues/jdbc/"; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // On devrait récupérer l'action requise par l'utilisateur String action = request.getParameter("action"); // Notre objet modèle: accès à MySQL TestsJdbc jdbc; // La vue par défaut String maVue = VUES + "index.jsp"; try { jdbc = new TestsJdbc(); if (action == null) { // Rien à faire } else if (action.equals("requete")) { jdbc.connect(SERVER, BD, LOGIN, PASSWORD); List<Film> resultat = jdbc.chercheFilmsC(); request.setAttribute("films", resultat); maVue = "/vues/jdbc/films.jsp"; } } catch (Exception e) { maVue = VUES + "exception.jsp"; request.setAttribute("message", e.getMessage()); } // On transmet à la vue RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(maVue); dispatcher.forward(request, response); } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Liste des films</title> </head> <body> <h1>Liste des films</h1> <ul> <c:forEach items="${requestScope.films}" var="film"> <li><c:out value="${film.titre} (${film.annee})" /></li> </c:forEach> </ul> <p> <a href="${pageContext.request.contextPath}/jdbc">Accueil</a> </p> </body> </html>
Dans le but de ne pas mettre en dur dans le code applicatif l'utilisateur et le mot de passe ni la création d'une connexion à la base de données pour chaque utilisateur (mais une seule mutualisée entre tous les clients). La donnée sera alors stockée coté serveur Tomcat.
Pour cela, il est nécessaire d'avoir un projet Web Dynamic.
Les fichiers de configuration coté serveur :
<?xml version="1.0" encoding="UTF-8"?> <Server port="8005" shutdown="9ea1d95c6db3c25"> ... <GlobalNamingResources> ... <Resource auth="Container" driverClassName="com.mysql.jdbc.Driver" maxActive="10" maxIdle="3" maxWait="10000" name="jdbc/UFRIMA" password="aui" type="javax.sql.DataSource" url="jdbc:mysql://localhost/elearning" username="root" /> </GlobalNamingResources> ... </Server>
<?xml version="1.0" encoding="UTF-8"?> <Context> ... <ResourceLink name="jdbc/UFRIMA" global="jdbc/UFRIMA" type="javax.sql.DataSource"/> </Context>
Coté client :
package com.llgc; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.naming.Context; import javax.naming.InitialContext; import javax.naming.NamingException; import javax.sql.DataSource; public class Principale { public static void f() { Context initCtx; try { initCtx = new InitialContext(); Context envCtx = (Context) initCtx.lookup("java:comp/env"); // Look up our data source DataSource ds = (DataSource) envCtx.lookup("jdbc/UFRIMA"); try (Connection conn = ds.getConnection(); Statement st = conn.createStatement()) { ResultSet rs = st.executeQuery("SELECT * FROM civilite"); while (rs.next()) { System.out.print(rs.getString("LibelleLong") + "\n"); } } catch (SQLException e) { e.printStackTrace(); } } catch (NamingException e) { e.printStackTrace(); } } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="com.llgc.Principale"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <% Principale.f(); %> </body> </html>
Liste des drivers disponibles les plus courants.
sun.jdbc.odbc.JdbcOdbcDriver com.mysql.jdbc.Driver oracle.jdbc.driver.OracleDriver com.microsoft.jdbc.sqlserver.SQLServerDriver
executeQuery
: pour les requêtes qui retournent un ResultSet
,
executeUpdate
: pour les requêtes INSERT
, UPDATE
, DELETE
, CREATE TABLE
et DROP TABLE
,
execute
: pour les procédures stockées.