mostrar - Programación Java: ¿dónde deberían almacenarse las declaraciones SQL?
mostrar datos de una base de datos en java (15)
¿Debería el código SQL ser considerado "código" o "metadatos"?
Código.
¿Deben los procedimientos almacenados usarse solo para la optimización del rendimiento o son una abstracción legítima de la estructura de la base de datos?
Los procedimientos almacenados permiten la reutilización, incluido el interior de otros procedimientos almacenados. Esto significa que puede hacer un viaje a la base de datos y hacer que ejecute las instrucciones de soporte; la menor cantidad de tráfico es ideal. ORM o sproc, el tiempo en el cable que va a la base de datos y viceversa es algo que no puede recuperar.
ORM no se presta a la optimización debido a su abstracción. IME, ORM también significa una falta de integridad de referencia: hace que una base de datos sea difícil de informar. Lo que se guardó en complejidad, ahora se ha incrementado para poder sacar los datos de manera viable.
¿El rendimiento es un factor clave en la decisión? ¿Qué pasa con el bloqueo de proveedor?
No, la simplicidad es. El bloqueo de proveedor ocurre también con la base de datos: SQL está relativamente estandarizado, pero todavía hay maneras específicas de hacer las cosas por parte del vendedor.
¿Dónde debería una aplicación compatible con JDBC almacenar sus declaraciones SQL y por qué?
Hasta ahora, logré identificar estas opciones:
- Hardcoded en objetos comerciales
- Incrustado en cláusulas SQLJ
- Encapsular en clases separadas, por ejemplo, objetos de acceso a datos
- Metadata conducida (desacopla el esquema del objeto del esquema de datos - describe las asignaciones entre ellos en los metadatos)
- Archivos externos (por ejemplo, archivos de propiedades o recursos)
- Procedimientos almacenados
¿Cuáles son los "Pros" y "Contras" para cada uno?
¿Debería el código SQL ser considerado "código" o "metadatos"?
¿Deben los procedimientos almacenados usarse solo para la optimización del rendimiento o son una abstracción legítima de la estructura de la base de datos?
¿El rendimiento es un factor clave en la decisión? ¿Qué pasa con el bloqueo de proveedor ?
¿Qué es mejor: acoplamiento flexible o acoplamiento hermético y por qué?
EDITADO: Gracias a todos por las respuestas - aquí hay un resumen:
Metadata impulsada es decir Mapeos relacionales de objetos (ORM)
Pros:
- Muy abstracto: el servidor de bases de datos se puede cambiar sin necesidad de cambiar el modelo
- Ampliamente difundido, prácticamente un estándar
- Reduce la cantidad de SQL necesaria
- Puede almacenar SQL en archivos de recursos
- El rendimiento es (generalmente) aceptable
- Enfoque impulsado por metadatos
- (Base de datos) independencia del vendedor
Contras:
- Oculta las intenciones de SQL y verdaderos desarrolladores
- SQL difícil de ser revisado / modificado por DBA
- SQL aún podría ser necesario para casos extraños
- Puede forzar el uso de un lenguaje de consulta propio, por ejemplo, HQL
- No se presta a la optimización (abstracción)
- Puede carecer de integridad referencial
- Sustitutos por falta de conocimiento SQL o falta de cuidado para codificar en el DB
- Nunca coincida con el rendimiento de la base de datos nativa (incluso si se trata de cerrar)
- El código del modelo es muy ajustado junto con el modelo de base de datos
Hardcoded / encapsulated en la capa DAO
Pros:
- SQL se mantiene en los objetos que acceden a los datos (encapsulación)
- SQL es fácil de escribir (velocidad de desarrollo)
- SQL es fácil de rastrear cuando se requieren cambios
- Solución simple (sin arquitectura desordenada)
Contras:
- SQL no puede ser revisado / cambiado por DBA
- SQL es probable que se convierta en DB-specific
- SQL puede ser difícil de mantener
Procedimientos almacenados
Pros:
- SQL guardado en la base de datos (cerca de los datos)
- SQL es analizado, compilado y optimizado por el DBMS
- SQL es fácil para DBA revisar / cambiar
- Reduce el tráfico de la red
- Seguridad incrementada
Contras:
- SQL está vinculado a la base de datos (lock-in del proveedor)
- El código SQL es más difícil de mantener
Archivos externos (por ejemplo, archivos de propiedades o recursos)
Pros
- SQL se puede cambiar sin necesidad de reconstruir la aplicación
- Desacopla la lógica de SQL de la lógica de negocios de la aplicación
- Repositorio central de todas las declaraciones SQL: más fácil de mantener
- Más fácil de entender
Contras:
- El código SQL puede volverse inmanejable
- Más difícil de verificar el código SQL para detectar errores (de sintaxis)
Incrustado en cláusulas SQLJ
Pros:
- Mejor comprobación de sintaxis
Contras:
- Se acerca demasiado a Java
- Menor rendimiento que JDBC
- La falta de consultas dinámicas
- No tan popular
Al igual que la mayoría de nosotros, he visto todo el gammut, pero debemos considerar el SQL como un lenguaje de primera clase. Incluso he visto SQL almacenado en el DB que se tira hacia abajo y luego se ejecuta una copia de seguridad.
Los sistemas más exitosos que he visto emplean procedimientos almacenados, funciones y vistas.
Los procesos almacenados mantienen el texto SQL atrás en el DB y permiten un cambio relativamente inmediato por parte de aquellos que DESPLIEGAN y PERSONALIZAN (lo que requiere mucho diseño adecuado para soportarlo).
Todas las proyecciones deben realizarse mediante vistas y selecciones simples por las mismas razones, toda la lógica de proyección debe estar contenida dentro de la vista.
Al usar un ORM (como hibernar), es de esperar que no tenga que preocuparse por las sentencias de SQL. El rendimiento generalmente es aceptable y usted también obtiene independencia del proveedor.
Como un rexem escribió que las sentencias de SQL son código, deben tratarse como código, no externalizarse (siempre que tenga una buena razón) pero colocarse con código que procese datos de SQL desde y hacia esas declaraciones. El framework de hoy ORMs / iBatis ofrece muchas simplificaciones para el desarrollo diario de JDBC.
Algunas respuestas a su pregunta las encontrará en esta pregunta :) El problema de cómo se almacenarán sus declaraciones SQL depende del rey de su aplicación. ¿Cuáles son tus necesidades? ¿Alta seguridad, facilidad de escritura de código o mantenimiento, plataforma cruzada o bloqueo de proveedor? La siguiente pregunta ¿necesita un SQL puro o un marco ORM será bueno?
* Hardcoded in business objects
* Encapsulate in separate classes e.g. Data Access Objects
La solución más simple (P), difícil de mantener (C)
* Embedded in SQLJ clauses
Verificación de sintaxis Beter (P), falta de consultas dinámicas (C), menor rendimiento que JDBC (C), no tan popular (C)
* Metadata driven (decouple the object schema from the data schema - describe the mappings between them in metadata)
Debe ser un caso específico que debe hacer eso (C) o si se refiere a ORM (P);)
* External files (e.g. Properties or Resource files)
Fácil de mantener (P) pero más difícil de verificar por errores (C)
* Stored Procedures
Alto nivel de seguridad (P), código difícil de mantener un proveedor de problemas de bloqueo (C)
El mío termina en paquetes de recursos. Sé que no es normal, pero es más fácil para mí y para cualquier persona "que yo" mantener. Es directo y lógico.
Tengo curiosidad de ver si alguien usa mi enfoque también.
El miedo al bloqueo de proveedores en el mundo de Java es interesante.
Espero que no hayas pagado CPU de $ 50000 pr para Oracle Enterprise, y luego solo usaste el mínimo común denominador para cambiar a Mysql en cualquier momento. Como cualquier buen DBA le dirá, existen diferencias sutiles entre las diferentes bases de datos de nombres grandes, especialmente con respecto a los modelos de bloqueo y cómo logran consistencia.
Por lo tanto, no tome una decisión sobre cómo implementar sus llamadas SQL solo en función del principio de SQL independiente del proveedor; tenga una razón real (comercial) para hacerlo.
Generalmente, cuanto más crece la aplicación en términos de tamaño y / o reutilización, más se necesita externalizar / abstraer las sentencias de SQL.
Hardcoded (como constantes finales estáticas) es el primer paso. Almacenado en un archivo (propiedades / archivo xml) es el siguiente paso. El último paso es el manejo de metadatos (como lo hace un ORM como Hibernate / JPA).
Hardcoded tiene la desventaja de que es probable que su código se convierta en específico de DB y que necesite reescribir / reconstruir / redistribuir en cada cambio. La ventaja es que lo tiene en 1 lugar.
Almacenado en un archivo tiene la desventaja de que puede volverse inmanejable cuando la aplicación crece. La ventaja es que no necesita volver a escribir / reconstruir la aplicación, a menos que necesite agregar un método DAO adicional.
La gestión de metadatos tiene la desventaja de que el código de su modelo es muy ajustado al modelo de la base de datos. Para cada cambio en el modelo de base de datos necesitarás reescribir / reconstruir / redistribuir el código. La ventaja es que es muy abstracto y que puede cambiar fácilmente del servidor de base de datos sin la necesidad de cambiar su modelo (pero pregúntese ahora: ¿con qué frecuencia cambiaría una compañía del servidor de base de datos? Probablemente al menos una vez cada 3 años, no lo haga). t él?).
No llamaré a los procedimientos almacenados una "buena" solución para esto. Tienen un propósito completamente diferente. Aunque, su código dependería de la DB / configuración utilizada.
La única pregunta que hace que tiene una respuesta definitiva es "¿Es código SQL o metadatos?" Definitivamente es código y, como tal, se debe mantener en algún tipo de control de código fuente y tener un sistema para actualizar fácilmente a la última versión y retroceder cuando no lo haga si las cosas van mal.
He visto tres formas de hacer SQL en una aplicación y cada una tiene sus pros y contras. No existe la mejor manera, pero lo mejor es elegir una que funcione bien con su aplicación y atenerse a ella.
- ORM: esto reduce la cantidad de SQL que necesita para escribir y maneja muchos detalles para usted. Tendrá que hacer algunos SQL personalizados. Asegúrate de tener un ORM que maneje esto con gracia.
- Objetos de acceso a datos: mantenga el SQL en los objetos que acceden a los datos. Esto encapsula su base de datos y la hace para que el resto de su aplicación no necesite conocer la estructura de base de datos subyacente, solo la interfaz de estos objetos.
- Procedimientos almacenados: esto mantiene todos sus SQL en su base de datos y facilita que sus DBA sepan lo que está sucediendo. Todo lo que necesita hacer es hacer que su código llame a los procs almacenados
No creo que nadie le proporcione el desglose pro / congo que desea ya que es una pregunta bastante grande. Entonces, en cambio, aquí está lo que he usado en el pasado y lo que usaré en el futuro.
Utilizo para usar SQL codificado en el DAL. Pensé que esto estaba bien hasta que los DBA querían jugar con el SQL. Luego debe desenterrarlo, formatearlo y dispararlo a los DBA. Quién se reirá de eso y lo reemplazará todo. Pero sin los bonitos signos de interrogación, o los signos de interrogación en el orden incorrecto, y te dejan volver a pegarlo en el código de Java.
También hemos utilizado un ORM, y aunque esto es genial para los desarrolladores, nuestros DBA lo odiaban ya que no hay ningún SQL para que se rían de él. También usamos un ORM impar (uno personalizado del proveedor de terceros) que tenía el hábito de matar la base de datos. He usado JPA desde entonces y fue genial, pero conseguir algo complicado al usarlo más allá de los DBA es una batalla cuesta arriba.
Ahora usamos procedimientos almacenados (con el enunciado de llamada codificado). Ahora, lo primero de lo que todos se quejarán es que están atados a la base de datos. Usted está. Sin embargo, ¿con qué frecuencia ha cambiado la base de datos? Sé con certeza que simplemente no podíamos intentarlo, la cantidad de otro código dependía de ello, además de reentrenar nuestros DBA y migrar los datos. Sería una operación muy costosa. Sin embargo, si en su mundo se necesitan DB cambiantes en un abrir y cerrar de ojos, es probable que salgan SP.
En el futuro, me gustaría usar procedimientos almacenados con herramientas de generación de código para crear clases Java a partir de paquetes Oracle.
Editar 2013-01-31 : unos años y DBA más tarde y ahora usamos Hibernate, yendo a SQL (procs almacenados en el DB) solo cuando es absolutamente necesario. Esta creo que es la mejor solución. El 99% de las veces los DB no necesitan preocuparse por el SQL, y el 1% que lo hacen está en un lugar con el que ya están cómodos.
No hay realmente ninguna diferencia sustancial entre estos tres:
- Hardcoded en objetos comerciales
- Incrustado en cláusulas SQLJ
- Encapsular en clases separadas, por ejemplo, objetos de acceso a datos
Supongo que vas a incrustar código SQL en forma de cadena directamente en tu código Java. Mientras que 1 y 3 probablemente usarán JDBC directamente (o alguna herramienta como Apache DbUtils ), 2 agrega una tecnología de preprocesador a la pila, generando el código JDBC relevante antes de la compilación.
Entonces, esencialmente, si estas soluciones implican incrustar SQL, también podría usar cualquiera de estas tecnologías:
- API de criterios JPA , modelado de JPQL como lenguaje interno específico de dominio en Java
- jOOQ , modelando SQL como un lenguaje interno específico de dominio en Java
También podría haber otras herramientas para ayudarle a incrustar SQL en Java de una manera más segura que a través de SQLJ o mediante la concatenación de cadenas real.
No sé si esto es óptimo, pero en mi experiencia terminan codificados (es decir, literales de cadena) en la capa DAO.
SQL dentro de los Procedimientos almacenados es optimizado por el sistema de la base de datos y compilado para la velocidad: ese es su hogar natural. SQL es entendido por el sistema de base de datos, analizado por el sistema de base de datos. Mantenga su SQL en la base de datos si puede; envuélvalo en procedimientos o funciones almacenados o en cualquier unidad de lógica que proporcione el sistema de base de datos, y realice llamadas simples utilizando cualquiera de las herramientas que usted o cualquier otra persona haya mencionado.
¿Por qué almacenar código SQL para el sistema de base de datos fuera del DB? A menudo para la velocidad de desarrollo. ¿Por qué usar mapeo ORM? - Algunos dicen que la asignación de ORM proporciona compatibilidad en diferentes sistemas de bases de datos; sin embargo, rara vez en el mundo real una aplicación se aleja de la plataforma de base de datos cuando se creó especialmente cuando comienza a usar características avanzadas como la replicación, y para las raras ocasiones en que ocurre que el sistema de bases de datos se intercambia, se justifica algún trabajo. . Creo que uno de los inconvenientes de ORM a menudo sustituye la falta de conocimiento de SQL o la falta de cuidado para codificar en el DB. Además, ORM nunca igualará el rendimiento de la base de datos nativa, incluso si se acerca.
Estoy del lado de mantener el código SQL en la base de datos y hacer llamadas simples a través de cualquier API o interfaz que desee utilizar. También abstraiga el punto en el que se realizan las llamadas de su base de datos colocando esas llamadas detrás de una clase abstracta o interfaz OO (expresada por métodos), de modo que si alguna vez intercambia un nuevo tipo de fuente de datos, será transparente para la capa empresarial .
Sin embargo, a partir de la experiencia que he tenido, las sentencias sql de codificación fija en los objetos DAO son las que se usan ampliamente, pero creo que debería ser el método menos preferido. La mejor práctica debería ser almacenar las sentencias sql en un archivo de propiedades. Y obtenga las declaraciones en el objeto DAO a través de una interfaz para archivos de propiedades, digamos java.util.Properties . Los enunciados sql pueden intercalarse con ''?'' S para pasar parámetros, a través de un enfoque de enunciado preparado .
Tal enfoque ayuda a desacoplar la lógica SQL de la lógica de negocio de la aplicación. Esto pone a disposición un repositorio central de todas las sentencias SQL, lo que facilita la modificación, eliminando la necesidad de buscar declaraciones de bases de datos dentro de la lógica de la aplicación. La incomunibilidad también mejora.
Sugiero usar DAO con un diseño de fábrica. Entonces, los objetos de ejemplo que necesita serían:
public class CoolBusinessObject
public class DAOFactory.java
public implementation CoolBusinessOjectDAO
public class CoolBusinessOjectDAOOracleImpl implements CoolBusinessOjectDAO
Este estilo agrupa la interacción de datos, por lo que solo debería cambiar una capa de código si cambia de base de datos o pasa a las tecnologías ORM.
Usamos el mapeador iBatis SQL, que está más cerca del metal que los ORM como Hibernate. En iBatis pones las declaraciones de SQL en archivos de recursos (XML), que deben estar en el classpath.
Su lista de enfoques parece bastante completa si agrega la opción ORM de @ocdecio. Diría que el uso de un ORM y el uso de un correlacionador SQL y los archivos de recursos son los dos mejores enfoques. Me mantendría alejado de SQLJ, que no ha tenido mucha aceptación y te vincula demasiado estrechamente con Java. Además, manténgase alejado de los procedimientos almacenados, ya que lo vinculan con un proveedor de base de datos específico (los estándares son casi inexistentes para los procedimientos almacenados).