J'introduis une couche DAO dans notre application qui fonctionne actuellement sur SQL Server car j'ai besoin de la porter sur Oracle.
J'aimerais utiliser Hibernate et écrire une fabrique (ou utiliser une dependency injections) pour choisir les DAO corrects en fonction de la configuration du deployment. Quelles sont les meilleures pratiques dans ce cas? Dois-je avoir deux packages avec différents files hibernate.cfg.xml et * .hbm.xml et les choisir en conséquence dans mon usine? Est-il possible que mes DAO fonctionnent correctement avec les deux SGBD sans (trop) tracas?
En supposant que les noms de table et les colonnes sont les mêmes entre les deux, vous devriez pouvoir utiliser les mêmes files hbm.xml
. Cependant, vous devrez certainement fournir une valeur de configuration Hibernate différente ( hibernate.cfg.xml
), car vous devrez changer le dialecte d'Hibernate de SQLServer à Oracle.
S'il existe de légères différences de nom entre les deux, je créerais deux sets de files de mappage – un par server de database – et les regrouperais dans des files JAR distincts (tels que yourproject-sqlserver-mappings.jar
et yourproject-oracle-mappings.jar
), et déployer l'application avec un file JAR ou l'autre en fonction de l'environnement.
Je l'ai fait pour un client il y a un certain time – au deployment en fonction d'une propriété définie dans un file production.properties
j'ai changé le hibernate.dialect
dans le file cfg
en utilisant Ant (vous pouvez utiliser n'importe quel transformateur xml). Cependant, cela ne fonctionnerait que si le code Hibernate est btw sans faille entre les DBs, c.-à-d. Aucun appel de fonction spécifique à db, etc. HQL / JPAQL a des appels de fonction standard qui aident à cet égard.
Si les implémentations db doivent nécessairement être différentes, vous devrez faire quelque chose comme @matt.
J'ai travaillé sur une application qui supporte beaucoup de bases de données (Oracle, Informix, SQL Server, MySQL). Nous avons un file de configuration et un set de mappages. Nous utilisons jndi pour la connection à la database afin que nous n'ayons pas à traiter avec différentes URL de connection dans l'application. Lorsque nous initialisons SessionFactory, nous avons une méthode qui déduit le type de database de la connection sous-jacente. Par exemple, obtenez manuellement une connection via JNDI, puis utilisez connection.getMetaData (). GetDatabaseProductName () pour connaître la database. Vous pouvez également utiliser une variable d'environnement conteneur pour le définir explicitement. Définissez ensuite le dialecte en utilisant configuration.setProperty (Environment.DIALECT, deducedDialect) et initialisez le SessionFactory comme d'habitude.
Certaines choses que vous avez à faire:
Il y a un tableau qui trace les différences entre Oracle et SQLServer ici: http://psoug.org/reference/sqlserver.html
À mon avis les plus grands pièges sont: 1) Dates. Les fonctions et la mécanique sont complètement différentes. Vous devrez utiliser un code différent pour chaque DB. 2) Génération de keys – Oracle et SQLServer utilisent des mécanismes différents et si vous essayez d'éviter la génération "native" en ayant votre propre table de keys – eh bien, vous venez de sérialiser complètement tous vos "inserts". Pas bon pour la performance. 3) La concurrency / locking est un peu différent. Les parties du code sensibles aux performances seront probablement différentes pour chaque database. 4) Oracle est sensible à la casse, SQLServer ne l'est pas. Vous devez être prudent avec ça.
Il y en a beaucoup plus 🙂 L'écriture de code SQL qui s'exécutera sur deux DB est difficile. Faire vite peut parfois sembler presque impossible.