Disseny de la persistència JDBC

31
Enginyeria del SW II: Disseny de la persistència. JDBC Disseny de la persistència JDBC Toni Navarrete Enginyeria del Software II – UPF 2007

description

Disseny de la persistència JDBC. Toni Navarrete Enginyeria del Software II – UPF 200 7. Què és JDBC?. JDBC és un middleware que permet la nostra aplicació Java connectar i accedir d’una forma estandaritzada a qualsevol base de dades relacional (que disposi d’un driver JDBC) - PowerPoint PPT Presentation

Transcript of Disseny de la persistència JDBC

Page 1: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Disseny de la persistènciaJDBC

Toni NavarreteEnginyeria del Software II – UPF 2007

Page 2: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 2

Què és JDBC?

• JDBC és un middleware que permet la nostra aplicació Java connectar i accedir d’una forma estandaritzada a qualsevol base de dades relacional (que disposi d’un driver JDBC)

• JDBC és present al Java SDK (des de JDK 1.1). Paquets:– java.sql– javax.sql

• El codi és independent del gestor que utilitzem– Portable– Escalable

Page 3: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 3

JDBC: 4 tipus de drivers• Hi ha quatre tipus de drivers JDBC

– Tipus 1: JDBC-ODBC bridge + ODBC driver– Tipus 2: Native-API partly-Java driver

• Converteix les crides de JDBC a crides de l’API pròpia del SGBD. Els applets no els poden utilitzar per raons de seguretat

– Tipus 3: JDBC-Net pure Java driver• Converteix les crides JDBC a un protocol de xarxa independent del

SGBD (per exemple SQL*Net), que després és traduït al protocol del SGBD per un servidor. Aquest servidor middleware permet connectar a diferents SGBDs. Molt flexible, però han de solventar aspectes de seguretat, firewalls,...

– Tipus 4: Native-protocol pure Java driver• Converteix les crides JDBC directament al protocol de xarxa usat pel

SGBD (per exemple Oracle CLI). Suposa una crida directa de la màquina client al servidor SGBD. Com que solen ser protocols propietaris, els drivers els desenvolupen els fabricants dels propis SGBDs

• El codi dels nostres programes són independents del tipus de driver (quasi)

Page 4: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 4 JDBC: Establint la connexió• La primera cosa que cal fer és establir una connexió

amb el SGBD que volem utilitzar. Això inclou dues etapes– 1. Carregar el driver– 2. Realitzar la connexió

• Carregar el driver– Instrucció:

• Class.forName(“nom_driver”);O• Class.forName(“nom_driver”).newInstance();

– La documentació del driver ens dirà quin nom hem de posar-hi. Per exemple, el driver que fa el bridge JDBC-ODBC (inclòs en el J2SDK):

• Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");– Això ho registra automàticament en el DriverManager i ja

podem crear-hi connexions– Les classes del driver han d’estar al classpath

Page 5: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 5

JDBC: Connections

• Establir la connexió – Una vegada tenim registrar el driver corresponent (a

l’objecte DriverManager), ja podem crear la connexió amb el SGBD

– Objecte Connection. Exemple:• Connection con = DriverManager.getConnection(url,

“usuari", “password"); – Exemple:

String url = "jdbc:odbc:miBD"; Connection con = DriverManager.getConnection(url,

“usuari", “password"); – La documentació del driver dirà com es forma la

URL

Page 6: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 6

JDBC: Statements

• Un objecte Statement és el que envia sentències SQL al SGBDStatement stmt = con.createStatement();

• Sobre un statement podem:– executar consultes

• amb el mètode executeQuery– executar operacions de modificació (insert,

delete, update)• Amb el mètode executeUpdate

Page 7: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 7

JDBC: ResultSets

• Els resultats després d’executar una consulta són un conjunt de files que es guarden a un objecte de la classe ResultSet

• Per exemple– ResultSet rs =

stmt.executeQuery("SELECT codi, nom FROM alumne");

• Un ResultSet té una sèrie de mètodes per recòrrer-lo fila a fila i per recuperar els valors dels camps d’una fila

Page 8: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 8

JDBC: manegant els ResultSet• Exemple:

String query = "SELECT codi, nom FROM alumne"; ResultSet rs = stmt.executeQuery(query); while (rs.next()) { int codi = rs.getInt(“codi");

String nom = rs.getString(“nom"); System.out.println(codi + ": " + nom);

}• Mètodes per recórrer el ResultSet:

first() ens situa a la primera fila del ResultSetnext() avança a la següent filaisFirst() retorna un booleanisLast() retorna un boolean

• Mètodes per recuperar el valor del camp d’una fila:getString(“nom_camp”) o getString(1) Les columnes numerades des de 1getFloat(“nom_camp”) o getFloat(1)getInt(“nom_camp”) o getInt(1)...

Page 9: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 9 Un exemple d’aplicació amb JDBCimport java.sql.*;public class ExempleJDBC { public recuperaAlumnes() { try {

Class.forName("com.mysql.jdbc.Driver"); //Nom del driver de MySQL (MySQL Connector/J) //Class.forName("oracle.jdbc.driver.OracleDriver"); //Nom del driver d'Oracle

} catch(java.lang.ClassNotFoundException e) {System.err.print("ClassNotFoundException: "); System.err.println(e.getMessage());}String url = "jdbc:mysql://host:3306/nomBD“; //cadena de connexió per al driver de MySQL (si el port és el 3306 no cal posar-ho)//String url = "jdbc:oracle:thin:@host:1521:nomBD"; //cadena de connexió per al driver “thin” d’Oracle

try { Connection con = DriverManager.getConnection(url, "user", "password"); //definim la connexió //Connection con = DriverManager.getConnection(url, "", ""); //si no es fa autentificat Statement stmt = con.createStatement(); // creem un statement sobre la connexió

String myquery = "SELECT codi,nom from alumnes"; ResultSet rs = stmt.executeQuery(myquery); //executem la consulta " SELECT codi,nom from alumnes "

while (rs.next()) // recorrem el recordset, fila a fila i anem afegint les "persones" al vector { int codi = rs.getInt(“codi"); String nom = rs.getString("nom"); System.out.println(codi +": " + nom); } rs.close(); // tanquem el recordset stmt.close(); // tanquem el statement con.close(); // tanquem el recordset } catch(Exception ex) { System.err.println("Exception: " + ex.getMessage()); } }...}

Page 10: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 10

JDBC en una aplicació web

• Utilitzarem servlets i JSPs (Java Server Pages)

• S’executen en un motor de servlets (servlet-engine), també anomenat contenidor web (web-container)

Page 11: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 11

Integrant JDBC i JSP/Servlets

• Dins del servlet (doGet o doPost) o del JSP (entre <% i %>) es poden incloure crides JDBC per recuperar dades de la BD i a partir dels resultats generar la pàgina de resultats

• En un JSP s’utilitza la directiva page (que hem vist abans per declarar el content-type) també per importar llibreries. Exemple:

<%@ page import=“java.sql.*”><%@ page import=“java.util.*”>

O<%@ page import=“java.sql.*, java.util.*”>

• Les classes del driver JDBC han d’estar en el classpath del motor de servlets (no en el client)

Page 12: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 12

Integrant JDBC i JSP/Servlet. Exemple<%@ page import="java.sql.*" %><html><body><h1>Llista d'alumnes</h1><% Class.forName("com.mysql.jdbc.Driver").newInstance();

String url = "jdbc:mysql://localhost/test";

Connection con = DriverManager.getConnection(url, "", ""); //definim la connexió Statement stmt = con.createStatement(); // creem un statement sobre la connxió

String mysql = "SELECT codi,nom from alumnes"; ResultSet rs = stmt.executeQuery(mysql); //executem la consulta

while (rs.next()) // recorrem el recordset, fila a fila i anem afegint les "persones" al vector { int codi = rs.getInt("codi"); String nom = rs.getString("nom");%>Codi: <B><% out.print(codi); %></B>; Nom: <B><% out.print(nom);%></B><BR><% } rs.close(); // tanquem el recordset stmt.close(); // tanquem el statement con.close(); // tanquem el recordset %></body></html>

Page 13: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 13

PERILL!

• És molt habitual que s’acabin barrejant totes les capes en un únic JSP (o servlet) i que l’arquitectura del sistema quedi com una xarxa immanegable de JSPs que fan cadascú una funció específica

• Desenvolupament funcional, no OO

• Solució: MVC (Model-View-Controller) i separació en capes (presentació, “negoci” i dades)

Page 14: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 14

Avantatges i inconvenients de JDBC

• Dóna accés a SQL• Usa el model relacional de SQL

– No l’orientat a objectes de Java– Procedural en lloc d’OO– El processament de dades es fa mitjançant SQL i no

Java• Les operacions són expressades en relació a

taules, files i columnes• SQL no està realment estandaritzat, amb la

qual cosa la portabilitat no sempre és real• Procedimental en lloc d’orientat a objectes

Page 15: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 15

Millores a JDBCJDBC 2.0 i posteriors

• ResultSets scrollables i updatables• PreparedStatements• Transaccions

– Nivells d’aillament• Pool de connexions

– Datastores i registre JNDI– Exemple: DBCP per Tomcat

Page 16: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 16

ResultSets scrollables i updatables• Els ResultSets scrollable permeten un accés directe (no seqüencial)

a les files d’un ResultSet • Els ResultSets updatable permeten fer modificacions sobre la BD, no

amb sentències SQL (insert, update o delete) sinó amb uns mètodes de ResultSet

• A l’hora de crear un statement des d’una connexió es poden utilitzar dos arguments:Statement stmt = con.createStatement( ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);

ResultSet srs = stmt.executeQuery("SELECT id1, nom1 FROM t1");– El primer és una de tres constants (definides a ResultSet) per indicar el

tipus d’objecte ResultSet que es generarà quan s’executi una consulta.• TYPE_FORWARD_ONLY • TYPE_SCROLL_INSENSITIVE• TYPE_SCROLL_SENSITIVE

– El segon és una de dues constants (definides a ResultSet) per indicar si l’objecte ResultSet que es genera és modificable o de només lectura:

• CONCUR_READ_ONLY • CONCUR_UPDATABLE .

– Valors per defecte: TYPE_FORWARD_ONLY i CONCUR_READ_ONLY

Page 17: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 17

ResultSets scrollables i updatables

• Els ResultSet de tipus TYPE_SCROLL_INSENSITIVE i TYPE_SCROLL_SENSITIVE permeten accedir a posicions concretes del ResultSet (mentre que el TYPE_FORWARD_ONLY només es pot recórrer sequencialment)– TYPE_SCROLL_INSENSITIVE no reflecteix els canvis que poden

haver al ResultSet mentre és obert, mentre que TYPE_SCROLL_SENSITIVE sí

• Example:srs.absolute(4); // el cursor se situa a la fila 4 srs.relative(-3); // el cursor se situa a la fila 1 srs.relative(2); // el cursor se situa a la fila 3

• Quatre mètodes addicionals permeten verificar si el cursos és a una determinada posició: isFirst , isLast , isBeforeFirst , isAfterLast

• Amb els mètodes updateInt, updateString,..., es poden fer canvis en el ResultSet (si s’ha declarat CONCUR_UPDATABLE) i després d’executar el mètode updateRow es modifiquen directament a la taula

Page 18: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 18

ResultSets scrollables i updatablesExemple de modificació de filaConnection con =

DriverManager.getConnection("jdbc:mysql://localhost/test"); Statement stmt = con.createStatement(

ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);

ResultSet uprs = stmt.executeQuery(“Select codi,nom,edat from alumnes”);

uprs.last(); uprs.updateString(“nom", “Pep”);uprs.updateInt(“edat”,19); uprs.updateRow();

Page 19: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 19

ResultSets scrollables i updatablesInserció i esborrat d’una fila

• També es poden inserir i eliminar files directament des del RecordSet:uprs.moveToInsertRow(); uprs.updateInt(“codi”,27);uprs.updateString(“nom", “Pep”);uprs.updateInt(“edat”,19); uprs.insertRow();

uprs.absolute(4); uprs.deleteRow();

Page 20: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 20

Prepared Statements

• Si s’ha d’executar la mateixa sentència SQL moltes vegades, podem reduir el temps d’execució utilitzant un objecte PreparedStatement en lloc del Statement

• La principal característica d’un objecte PreparedStatement és que ja se li dóna un SQL quan és creat

• Aquesta sentència SQL té variables de binding a les quals es donaran valors concrets abans d’executar

• Així s’estalvia a l’intèrpret SQL del SGBD haver de parsejar cada cop la mateixa sentència, només ho fa un cop i la guarda

• Example:PreparedStatement updateAlus = con.prepareStatement(“UPDATE

alumnes SET nom = ? WHERE id = ? ");updateAlus.setString(1, “Anna"); updateAlus.setInt(2, 3); updateSales.executeUpdate();

Page 21: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 21

Prepared Statements (en un bucle)Exemple...PreparedStatement updateAlus;String updateString = "update ALUMNES set nom = ?

where codi = ?";updateAlus = con.prepareStatement(updateString);int [] codis = {3, 5,8,12};String [] noms = {“Pep", "Joana“,”Núria”,”Anna”};int len = codis.length;for(int i = 0; i < len; i++) {

updateAlus.setString(1, noms[i]);updateAlus.setInt(2, codis[i]);updateAlus.executeUpdate();

}

Page 22: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 22

Transaccions (desactivar autocommit)• Per defecte, cada sentència SQL quan és executada provoca un

commit• Per definir una transacció podem desactivar això i especificar quan

volem que es faci el commit• Exemple:

con.setAutoCommit(false); PreparedStatement updateAlus;

String updateString = "update ALUMNES set nom = ? where codi = ?";updateAlus = con.prepareStatement(updateString);int [] codis = {3, 5, 8, 12};String [] noms = {“Pep", "Joana“, ”Núria”, ”Anna”};int len = codis.length;for(int i = 0; i < len; i++) {updateAlus.setString(1, noms[i]);updateAlus.setInt(2, codis[i]);updateAlus.executeUpdate();}con.commit();con.setAutoCommit(true);

Page 23: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 23

Transaccions (rollback)

• En cas de què es produeixi una excepció, cal fer un rollback per desfer totes les sentències que ja s’haguessin executat

• Exemple (continuant l’anterior) } catch(SQLException ex) {System.err.println("SQLException: " + ex.getMessage());if (con != null) {try {System.err.print("Transacció abortada");con.rollback();} catch(SQLException excep) {System.err.print("Excepció de SQL: ");System.err.println(excep.getMessage());}}}

Page 24: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 24

Transaccions (Save points)

• Es poden definir punts als quals es torna quan hi ha un rollback (save points)

• Des de JDBC 3.0

Statement stmt = conn.createStatement(); stmt.executeUpdate("INSERT INTO ALUMNES VALUES (…)");

// set savepoint Savepoint:svpt1 = conn.setSavepoint("SAVEPOINT_1");

stmt.executeUpdate("INSERT INTO ALUMNES VALUES (…)");

…conn.rollback(svpt1);

... conn.commit();

Page 25: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 25

Transaccions (tipus de nivells de aïllament)• La classe Connection té el mètode:

public void setTransactionIsolation(int level) throws SQLException• Aquest mètode permet canviar el nivell d’aïllament de les

transaccions, sempre que el SGBD el soporti. Aquests nivells estan especificats per les següents constants

• Aquest mètode no pot ser cridat al mig d’una transacció static int TRANSACTION_NONE

Indica que el SGBD no soporta transaccionsstatic int TRANSACTION_READ_UNCOMMITTED

Poden ocórrer “dirty reads”, “non-repeatable reads” i “phantom reads”static int TRANSACTION_READ_COMMITTED

Evita que es produeixin “dirty-reads”. Un dirty-read passa quan una transacció modifica una fila i aquesta és llegida per una altra transacció abans que s’hagi fet el commit. Si després es produís un rollback en la primera transacció, la segona tindria una dada errònia. Resumint, no permet llegir d’una fila que s’ha modificat fins que no es fa el commit

• Continua ...

Page 26: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 26

Transaccions (tipus de nivells de aïllament)• ... continuastatic int TRANSACTION_REPEATABLE_READ

Evita també les “non-repeatable reads”. Això passa quan una transacció llegeix una fila, una segona l’altera i la primera torna a llegir-la, obtenint un valor diferent

static int TRANSACTION_SERIALIZABLE Evita totes: “dirty reads”, “non-repeatable reads” i “phantom reads”. Un “phantom read” es produeix quan una transacció llegeix totes les files que satisfan una condició where i una segona transacció inserta una nova fila que satisfà aquesta condició where. Si la primera transacció re-llegeix es trobarà amb aquesta “fila fantasma” que abans no existia

• La classe Connection també té un mètode per saber el nivell d’aïllament actual:int getTransactionIsolation()

TRANSACTION_NONE: 0 TRANSACTION_READ_UNCOMMITTED: 1 TRANSACTION_READ_COMMITTED: 2 TRANSACTION_REPEATABLE_READ: 4 TRANSACTION_SERIALIZABLE: 8

Page 27: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 27

JDBC: Connection pooling

• Una de les operacions més costoses és establir la connexió amb la base de dades

• Solució: utilització d’un pool de connexions– Es generen un conjunt de connexions– Quan una classe (o JSP) demana una connexió se li assigna

una que ja existeix al pool– Si no n’hi ha disponibles, s’espera un cert temps– Un cop que s’ha utilitzat una connexió no es destrueix, queda

al pool (cal tancar-la expressament!)– Una implementació d’un pool simple a pool_simple.zip

• Amb una pila• Si quan s’ha de fer una connexió el pool està buit, se’n crea una

de nova. Si no, se’n treu una del pool• Problemes d’aquesta implementació: el pool creix sense límit

Page 28: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 28

• JDBC va incorporar una forma estandaritzada per definir un pool de forma transparent (mitjançant una sèrie d’interfícies): serà el servidor d’aplicacions qui ho manegarà i no el programador– Cal utilitzar JNDI i definir un DataSource

• JNDI ("Java Naming Directory Interface") és una especificació que permet localitzar informació en diferents directoris distribuïts

• Tomcat ho implementa mitjançant DBCP (DataBase Connection Pool)– En la versió 5.5 i posteriors està integrat en la distribució de

Tomcat, en el paquet “naming-factory-dbcp.jar”

JDBC: Connection pooling

Page 29: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 29

JDBC: Connection pooling

• El codi de l’aplicació gairebé no canvia– Per obtenir la connexió no es fa a partir del DriverManager sinó

d’un DataSource Context init = new InitialContext(); Context ctx = (Context) init.lookup("java:comp/env");

//els datasources sempre estan definits a comp/env DataSource ds = (DataSource)ctx.lookup("jdbc/poolBD"); if (ds != null) Connection conn = ds.getConnection();

/* serà Tomcat qui s’encarregarà d’assignar una connexió * del pool, de forma transparent pel nostre codi */

– Cal tancar sempre la connexió!! Moltes vegades s’afegeix al try principal:

try { ...} finally { if (conn != null) conn.close();}

Page 30: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 30

JDBC: Connection pooling

• En el fitxer web.xml de l’aplicació cal dir que s’utilitzarà el recurs poolBD, que és un DataSource:

<web-app> <description>Prova del pool amb DBCP

</description> <resource-ref> <description>Connexio amb BD</description> <res-ref-name>jdbc/poolBD</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref></web-app>

Page 31: Disseny de la persistència JDBC

Eng

inye

ria d

el S

W II

: Dis

seny

de

la p

ersi

stèn

cia.

JD

BC

Pàgina 31

• A més, cal definir el recurs poolDB. Es fa quan es defineix el context en el context.xml de l’aplicació, al directori META-INF:

<?xml version="1.0" encoding="UTF-8"?><Context path="/dbcp"> <Logger className="org.apache.catalina.logger.FileLogger"

prefix="dbcp." suffix=".log" timestamp="true"/> <Resource name="jdbc/poolBD" auth="Container" type="javax.sql.DataSource" username="usuari" password="password" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://host:3306/poolBD" maxActive="8" maxIdle="4"

maxWait="10000" /></Context>

• Per defecte utilitza el pool de DBCP, però es pot configurar un altre

JDBC: Connection pooling