De qué manera es mejor al ejecutar consultas desde Java

Tengo la siguiente duda. Cuando tiene que consultar una base de datos desde una aplicación Java, hay varias formas de hacerlo. Se me ocurrieron algunos enfoques, pero cada uno de ellos tiene una estafa.

El primero es que tienes una clase, por ejemplo. QueryManagerque le proporciona funcionalidades de consulta, como executeUpdate(...)y executeQuery(...)mientras oculta detalles de la gestión de conexiones, etc. (tipo de patrón de fachada ). Cuando necesite interactuar con la base de datos, pasará la consulta como una cadena y administrará el ResultSet.

El problema que veo es que si el DB cambia, ya sea el DBMS o el DB en sí mismo, terminarás yendo archivo por archivo modificando el SQL. Veo esto como una gran dependencia. Además, está exponiendo a todos la estructura de su base de datos y está haciendo que cada clase se encargue de ello ResultSet. Por otro lado, podría lograr una mayor modularidad utilizando este método, ya que los modelos (soy un fanático de MVC Pattern ) de sus clases podrían tener visibilidad de paquete.

La segunda idea que se me ocurrió fue crear una QueryManagerclase que, en lugar de proporcionarle los métodos para realizar consultas, le proporcione los métodos que necesita. En otras palabras, cada vez que necesite usar la base de datos, creará un método en esta clase, con el SQL dentro, que le devolverá la información que necesita. Pero, el problema que enfrentamos aquí es que debe elegir entre devolver ResultSetun modelo de los datos que necesita.
El primero hará que sus clases dependan de la base de datos, menos que en el ejemplo anterior, ya que ahora no existe una dependencia ampliamente extendida con el DBMS, porque todo el SQL está contenido en una clase / archivo. Sin embargo, todavía existe una dependencia con la estructura de base de datos y también está exponiendo su estructura de base de datos a todos.
Lo último implica que estos modelos ya no podrían ser visibilidad del paquete, deben ser públicos, permitiendo que cualquier clase los modifique y rompiendo la encapsulación.

¿Hay algún otro enfoque que resuelva todos los problemas anteriores? Si no, ¿cuál crees que es un mejor enfoque?

No creo que haya una respuesta absoluta (tal vez la hay), pero debo decir que esperamos cambios tanto en la estructura del DB como en el DBMS. Esto podría ayudarlo en su ropa interior. Pero trate de hacerlo lo más general posible, ya que podría estar en otro proyecto con la misma duda, pero no con las mismas restricciones.

Respuesta 1

El segundo es el bueno: debe extraer sus métodos de acceso a datos en Data Access Objects (DAO), que aíslan el resto de la aplicación de los problemas relacionados con la persistencia. Y los DAO definitivamente deberían devolver objetos, y no conjuntos de resultados.

Esto proporciona las siguientes ventajas:

  • desacoplamiento de preocupaciones y responsabilidades
  • evolución más fácil del resto de la aplicación cuando cambia el esquema
  • evolución más fácil del resto de la aplicación cuando elige usar un ORM en lugar de JDBC para acceder a la base de datos
  • Prueba unitaria más sencilla de las consultas (y de la capa de persistencia en general), ya que el código de persistencia no se mezcla con el código funcional
  • pruebas unitarias más sencillas de la capa empresarial (servicio), ya que permite inyectar DAO simulados para proporcionar los datos, en lugar de necesitar datos reales en la base de datos para probarlos.
Respuesta: 2

No me gusta ninguno de tus enfoques.

Puede escribir una única interfaz que maneje todo: el DAO genérico. Aquí hay un ejemplo simple que no pretende ser la respuesta completa, porque no permite consultas ad hoc o mapeo a objetos arbitrarios, pero es un comienzo:

public interface GenericDao<K, V> {
    List<V> find();
    V find(K key);
    K save(V value);
    void update(V value);
    void delete(V value);
}

Debe tener una interfaz clara entre la persistencia y las clases de modelo; el último no necesita saber sobre el primero.

No debe permitir ResultSetni Statementsalir de la capa de persistencia.

Debe tener una capa de servicio que obtenga conexiones y gestione las transacciones.

Debería escribir SQL de tal manera que el cambio de bases de datos, lo que debería ocurrir raramente, si es que lo hace, es tan simple como cambiar el JAR del controlador JDBC y los parámetros de conexión.

Respuesta: 3

Sugiero crear clases DAO ( http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html ) para todas las entidades, que ocultarán SQL / HQL / lo que sea que esté dentro. Devolverán el modelo de objeto, por lo que las clases de lógica de negocios no se preocuparán por las consultas / recuperación de la base de datos / etc.

Respuesta: 4

Creo que lo que buscas es el patrón de objeto de acceso a datos (DAO). Si usa un marco para el mapeo relacional de objetos como Hibernate , sus DAO realmente pueden especificar el esquema de la base de datos directamente (lo que creo que es bastante bueno). De lo contrario, es típico proporcionar un conjunto de clases DAO enrolladas a mano que resuelven todas las preocupaciones subyacentes de la base de datos (por ejemplo, las clases DAO no deberían devolver ResultSet).

Respuesta: 5

Es un problema que me está molestando durante 3 días. Tengo que reescribir la interfaz de usuario de un pequeño juego de tictactoe (Gomoku of nxn). El problema es que cuando creé la GUI de swing, creé una nueva clase que ...

Mi pregunta general es: ¿Es una práctica ineficiente / mala llamar a prepareStatement.executeBatch () si solo hay una consulta en el lote? Estoy escribiendo un método genérico para la Biblioteca auxiliar de Java para ...

¿El contrato de la interfaz Shape de Java y las rutinas de la biblioteca permiten combinar múltiples formas en un objeto que extiende la interfaz Shape? Por ejemplo, ¿puedo definir la clase Flor, que consistirá en varios ...

Este problema son las dependencias de Java no estáticas, sino dinámicas. Leí este enlace de stackoverflow, pero se trata de dependencias estáticas y buscar en Google me da resultados similares. Pues aqui esta mi problema: ...