Pregunta

Estoy introduciendo una capa DAO en nuestra aplicación que actualmente trabaja en SQL Server porque necesito portarla a Oracle.

Me gustaría usar Hibernate y escribir una fábrica (o usar la inyección de dependencia) para elegir los DAO correctos de acuerdo con la configuración de implementación. ¿Cuáles son las mejores prácticas en este caso? ¿Debo tener dos paquetes con diferentes archivos hibernate.cfg.xml y * .hbm.xml y seleccionarlos en mi fábrica? ¿Existe alguna posibilidad de que mis DAO funcionen correctamente con ambos DBMS sin (demasiada) molestia?

¿Fue útil?

Solución

Suponiendo que los nombres y las columnas de la tabla son los mismos entre los dos, debería poder usar los mismos archivos hbm.xml . Sin embargo, sin duda deberá proporcionar un valor de configuración de Hibernate diferente ( hibernate.cfg.xml ), ya que deberá cambiar el dialecto de Hibernate de SQLServer a Oracle.

Si hay pequeñas diferencias de nombre entre los dos, crearía dos conjuntos de archivos de mapeo, uno por servidor de base de datos, y los empaquetaría en archivos JAR separados (como yourproject-sqlserver-mappings.jar y yourproject-oracle-mappings.jar ), e implemente la aplicación con un JAR u otro según el entorno.

Otros consejos

Hice esto para un cliente hace un tiempo, en la implementación, dependiendo de una propiedad establecida en un archivo production.properties , cambié el hibernate.dialect en el cfg usando Ant (puede usar cualquier transformador xml). Sin embargo, esto solo funcionaría si el código de Hibernate es transparente entre ambos DB, es decir, no hay llamadas a funciones específicas de db, etc. HQL / JPAQL tiene llamadas a funciones estándar que ayudan en este aspecto como UPPER (s) , LONGITUD (es) etc.

Si las implementaciones de db deben ser necesariamente diferentes, entonces tendrías que hacer algo como lo que @matt sugirió.

He trabajado en una aplicación que admite muchas bases de datos (Oracle, Informix, SQL Server, MySQL). Tenemos un archivo de configuración y un conjunto de asignaciones. Utilizamos jndi para la conexión de la base de datos, por lo que no tenemos que lidiar con diferentes URL de conexión en la aplicación. Cuando inicializamos la SessionFactory tenemos un método que deduce el tipo de base de datos de la conexión subyacente. Por ejemplo, obtenga manualmente una conexión a través de JNDI y luego use connection.getMetaData (). GetDatabaseProductName () para averiguar qué es la base de datos. También puede usar una variable de entorno contenedor para establecerla explícitamente. Luego, configure el dialecto utilizando configuration.setProperty (Environment.DIALECT, deducedDialect) e inicie SessionFactory de la forma habitual.

Algunas cosas con las que tiene que lidiar:

  • Generación de clave primaria. Utilizamos una versión personalizada de la estrategia TableGenerator, por lo que tenemos una tabla clave con columnas para el nombre de la tabla y la siguiente clave. De esta manera, cada base de datos puede usar la misma estrategia en lugar de secuenciar en Oracle, nativo para SQL Server, etc.
  • Funciones específicas de bases de datos. Los evitamos cuando sea posible. Los dialectos de Hibernate manejan los más comunes. Ocasionalmente, tendremos que agregar el nuestro a nuestras clases de dialectos personalizados, .e.g. La aritmética de fechas es bastante no estándar, por lo que solo inventamos un nombre de función y lo asignamos a la forma en que lo hace cada base de datos.
  • Generación de esquema: usamos la clase de generación de esquema de Hibernate: funciona con los dialectos para crear el DDL correcto para cada tipo de base de datos y obliga a la base de datos a coincidir con las asignaciones. Debe conocer las palabras clave para cada base de datos, p. Ej. no intente tener una tabla USER en Oracle (USUARIOS funcionará) o una tabla TRANSLATION en MySQL.

Aquí hay una tabla que asigna las diferencias entre Oracle y SQLServer: http://psoug.org/ reference / sqlserver.html

En mi opinión, los mayores escollos son: 1) Fechas. Las funciones y la mecánica son completamente diferentes. Deberá usar un código diferente para cada DB. 2) Generación de claves: Oracle y SQLServer utilizan diferentes mecanismos y si intenta evitar el "nativo" generación en conjunto al tener su propia tabla de claves, bueno, simplemente serializó por completo todas sus '' inserciones ''. No es bueno para el rendimiento. 3) La concurrencia / bloqueo es un poco diferente. Las partes del código que son sensibles al rendimiento probablemente serán diferentes para cada DB. 4) Oracle distingue entre mayúsculas y minúsculas, SQLServer no. Tienes que tener cuidado con eso.

Hay muchas más :) Escribir código SQL que se ejecutará en dos bases de datos es un reto. Hacerlo rápido puede parecer casi imposible a veces.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top