java - example - Buenas prácticas: Conexión JDBC
jdbc java descargar (4)
Posible duplicado:
cuándo cerrar Connection, Statement, PreparedStatement y ResultSet en JDBC
He escrito un envoltorio simple para una conexión JDBC y funciona, pero quiero mejorarlo con las mejores prácticas posibles. Básicamente tiene métodos como open()
, close()
, isOpened()
, select()
, insert()
, update()
, delete()
y batch()
. Por simplicidad, solo publicaré aquí los primeros 4 métodos.
public class Query{
private Connection con;
private PreparedStatement ps;
private ResultSet rs;
//Database.open() returns a Connection ready to use
public void open (Database database) throws DatabaseException, SQLException{
if (!isOpened ()){
con = database.open ();
}
}
public void close () throws SQLException{
if (isOpened ()){
if (ps != null) ps.close ();
con.close ();
con = null;
}
}
public boolean isOpened (){
return con != null;
}
//The query string is the query without the word "select" and can use placeholders (?)
//The args param it''s just an array owith the values of this placeholders
public ResultSet select (String query, Object[] args) throws SQLException{
if (ps != null) ps.close ();
if (isOpened ()){
ps = con.prepareStatement ("select " + query);
if (args != null){
for (int i=0; i<args.length; i++){
ps.setObject (i+1, args[i]);
}
}
rs = ps.executeQuery ();
}
return rs;
}
}
Notas:
- El mismo objeto de consulta puede reutilizarse, por ejemplo abrirlo y cerrarlo, y luego de abrirlo nuevamente.
- No estoy cerrando la conexión para cada consulta, solo estoy cerrando la declaración preparada (¿esto es correcto o puedo dejar la declaración preparada abierta porque el objeto Connection lo cerrará?)
- Cuando cierro la
Connection
, todos losPreparedStatement
y susResultSet
también están cerrados, ¿verdad?
Uso:
Database database;
//Database initialization
Query query = new Query ();
query.open (database);
ResultSet rs = query.select ("* from user where name=?", new String[]{ "MyName" });
doSomethingWithResult1 (rs);
//Connection is not closed here
ResultSet rs = query.select ("coordx from point where coordy=? and coordz=?", new Float[]{ 0.1, 0.2 });
doSomethingWithResult2 (rs);
query.close ();
query.open (database);
ResultSet rs = query.select ("* from user where name=?", new String[]{ "MyName" });
doSomethingWithResult1 (rs);
//Connection is not closed here
ResultSet rs = query.select ("coordx from point where coordy=? and coordz=?", new Float[]{ 0.1, 0.2 });
doSomethingWithResult2 (rs);
query.close ();
¿Qué piensas? ¿Debo cerrar y abrir la conexión después de cada consulta? ¿Puedo dejar abierto PreparedStatement después de cada consulta en la misma conexión? Es un buen diseño?
La mejor paectise es: utilizar un único objeto de conexión para todas las consultas si esas queire son parte del mismo método y para cada consulta cerrar el estado preparado, después de su uso.
Use un grupo de conexiones. Entonces no sigues creando
Agrupación de conexiones
Use un grupo de conexiones. Cada transacción en su aplicación obtendrá una conexión de este grupo, ejecutará todas las cosas necesarias, revertirá o confirmará y cerrará la conexión (devolverá la conexión al grupo).
Podría darle a Objeto Query una referencia al grupo y abrir obtendrá la conexión y cerrará la conexión (devolviéndola de hecho).
Declaración preparada
Intente reutilizar su declaración preparada para consultas similares. De esta forma, el DB reutilizará el plan de consulta anterior y será más rápido. Tiene mucho sentido si está ejecutando muchas consultas de la misma forma.
¿Cómo?
- Mantener último PS abierto
- Si cierra la conexión o lo que sea, ciérrela
- si consulta la misma cadena de consulta que la reutilización anterior, la PS que guardó
- si no es la misma cadena de consulta ... ciérrela y cree una nueva
Debe cerrar PreparedStatement después de que haya terminado con él y antes de crear uno nuevo en la misma conexión. He tenido problemas graves porque no cerré PreparedStatements. Resultó que en el servidor de la base de datos había recursos asignados que solo se liberaban después de una llamada explícita de PreparedStatement.close ().
Como comentó bdares, la conexión debe abrirse y cerrarse con la menor frecuencia posible.