Clase abstracta para el manejo de bases de datos MySQL en Java

Manejar bases de datos MySQL con los métodos nativos de Java puede ser harto complicado, en el presente artículo se describe cómo crear una clase abstracta de base de datos genérica, reutilizable, simple y muy fácil de utilizar.

Esta clase esta basada en el artículo “Creando una capa de abstracción con PHP y mysqli”.

Primeramente, nuestra clase abstracta deberá proveer de métodos públicos, que puedan ser llamados de forma estática, para crear un objeto conector, no sea necesario.

Propiedades

public class db {
  protected static Connection conn; // objeto conector
  protected static PreparedStatement stmt; // objeto sentencia preparada
  protected static String sql; // sentencia SQL a ser preparada
  public static ResultSet rs; // colección de resultados de la consulta
  protected static List<String> data; // lista de los tipos de datos
  public static List<Map<String, String>> results; // colección de datos para ser retornados
  public static String insertId; // último id insertado
}

La consulta SQL, deberá ser seteada en los modelos (clases) donde se requiera, incluyendo marcadores de parámetros (embebidos con el signo ?), en la posición donde un dato deba ser enlazado. Un ejemplo de ella, podría ser el siguiente:

String sql = "INSERT INTO productos (categoria, nombre, precio) VALUES (?, ?, ?)";

Mientras que la lista “data”, deberá contener los datos a ser enlazados (todos de tipo string):

List<String> data = Arrays.asList(categoria,nombre,precio);

Métodos

Conectar a la base de datos:

protected static void conectar() {
  db.conn = DriverManager.getConnection(DB_URL, DB_USER, DB_PASSWORD);
}

Preparar una sentencia SQL (con marcadores de parámetros):

protected static void preparar() throws SQLException {
  db.stmt = db.conn.prepareStatement(db.sql, Statement.RETURN_GENERATED_KEYS);
}

Enlazar los datos con la sentencia SQL preparada:

private static void setParams() throws SQLException {
  if (db.data != null) {
    int dataSize = db.data.size();
    for (int i = 0; i < dataSize; i++) {
      db.stmt.setString(i + 1, db.data.get(i));
    }
  }
}

Enlazar resultados de una consulta de selección:

private static void getData() throws SQLException {
  db.results.clear();
  db.rs = db.stmt.getResultSet();
  ResultSetMetaData metaData = rs.getMetaData();
  int columnCount = metaData.getColumnCount();
  while (db.rs.next()) {
    Map<String, String> columns = new LinkedHashMap<String, String>();
    for (int i = 1; i <= columnCount; i++) {
      columns.put(metaData.getColumnLabel(i), db.rs.getString(i));
    }
    db.results.add(columns);
  }
  db.rs.close();
}

Cerrar conexiones abiertas:

public static void finalizar() throws SQLException {
  db.stmt.close();
  db.conn.close();
}

Un método público que ejecute todas las acciones:

public static void ejecutar(String sql, List<String> data) throws SQLException {
  db.sql = sql;
  db.data = data;
  db.conectar();
  db.preparar();
  db.setParams();
  boolean rpta = db.stmt.execute();
  if (sql.toLowerCase().contains("INSERT".toLowerCase())) {
    ResultSet keys = db.stmt.getGeneratedKeys();
    keys.next();
    db.insertId = keys.getString(1);
  } else if (rpta) {
    db.getData();
  }
  db.finalizar();
}

La estructura de control de flujo condicional, que utiliza el método ejecutar(), es la encargada de discernir si se trata de una consulta de “lectura” a la base de datos para así, llamar al método getData, o si se trata de una consulta de “escritura” (INSERT, UPDATE ó DELETE). En ese caso, verifica si es una escritura de tipo “INSERT” para retornar la id del nuevo registro creado.

¿Cómo utilizar la clase creada?

En todos los casos, siempre será necesario invocar estáticamente al método ejecutar, pasándole al menos dos parámetros: la sentencia SQL a preparar y una lista con los datos a enlazar a la sentencia SQL preparada:

String sql = "INSERT INTO productos (categoria, nombre, precio) VALUES (?, ?, ?)";
List<String> data = Arrays.asList(categoria,nombre,precio);
db.ejecutar(sql, data);
this.idPaciente = db.insertId;

Consulta de selección:

String sql = "SELECT nombre, descripcion, precio FROM productos WHERE categoria = ?";
List<String> data = Array.asList(categoria);
db.ejecutar(sql, data);

Autor: Alain

Especialista en desarrollo de aplicaciones web

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.