2008-11-18 13 views
13

Pour implémenter le code d'accès aux données dans notre application, nous avons besoin d'un framework pour enrouler autour de jdbc (ORM n'est pas notre choix, en raison de l'évolutivité).simple wrapper jdbc

Le cadre le plus cool avec lequel je travaillais est Spring-Jdbc. Cependant, la politique de mon entreprise est d'éviter les dépendances externes, en particulier le ressort, J2EE, etc. Nous envisageons donc d'écrire notre propre framework jdbc pratique, avec des fonctionnalités similaires à Spring-jdbc: mappage des lignes, gestion des erreurs, fonctionnalités de support de java5, mais sans support de transaction.

Quelqu'un a-t-il l'expérience de l'écriture de tels framework wrapper jdbc? Si quelqu'un a déjà utilisé d'autres frameworks wrapper jdbc, partagez votre expérience.

Merci d'avance.

+10

"La politique de mon entreprise est d'éviter les dépendances externes, en particulier le ressort, J2EE, etc." wow cela ressemble à un cauchemar. Cela ressemble à une boucle sans fin de réinventer la roue –

+7

J2EE est une "dépendance externe" ?? – yegor256

+0

Si vous recherchez une exécution SQL simpliste pour mapper des objets, mybatis est une option. Je ne l'appellerais pas un ORM dans le sens où il ne fait pas de graphiques d'objets comme Hibernate. Il vous permet simplement d'exécuter sql et d'extraire les paramètres de votre entrée, ou de mapper des colonnes à des objets de sortie. – Matt

Répondre

13

Nous avons écrit notre propre emballage. Ce sujet est digne d'un document, mais je doute que je vais jamais le temps d'écrire, donc voici quelques points clés:

  • nous et embrassèrent sql n'a pas essayé de le cacher. le seul tweak était d'ajouter le support pour les paramètres nommés. Les paramètres sont importants car nous n'encourageons pas l'utilisation de sql à la volée (pour des raisons de sécurité) et nous utilisons toujours PreparedStatements. Pour la gestion des connexions, nous avons utilisé Apache DBCP. C'était pratique à l'époque, mais on ne sait pas combien cela est nécessaire avec les implémentations modernes de JDBC (les documents sur ce genre de choses manquent). DBCP regroupe également PreparedStatements.

  • Nous n'avons pas pris la peine de mapper des lignes. à la place (pour les requêtes), nous avons utilisé quelque chose de similaire au ResultSetHandler d'Apache dbutil, qui vous permet de "nourrir" le jeu de résultats dans une méthode qui peut ensuite vider l'information où vous le souhaitez. Ceci est plus flexible, et en fait il ne serait pas difficile d'implémenter un ResultSetHandler pour le mappage de ligne. Pour les insertions/mises à jour, nous avons créé une classe d'enregistrement générique (essentiellement un hashmap avec quelques cloches et sifflets supplémentaires). le plus gros problème avec la cartographie des lignes (pour nous) est que vous êtes bloqué dès que vous faites une requête "intéressante" parce que vous pouvez avoir des champs qui correspondent à différentes classes; parce que vous pouvez avoir une structure de classe hiérarchique mais un ensemble de résultats plat; ou parce que le mappage est complexe et dépendant des données.

  • nous avons construit dans la journalisation des erreurs. pour la gestion des exceptions: sur une requête, nous piégons et enregistrons, mais pour une mise à jour, nous piégons, enregistrons et renvoyons des exceptions non contrôlées.

  • Nous avons fourni un support de transaction en utilisant une approche wrapper. l'appelant fournit le code qui effectue la transaction, et nous nous assurons que la transaction est correctement gérée, sans aucune chance d'oublier de finir la transaction et avec le rollback et la gestion des erreurs intégrée. Par la suite, nous avons ajouté un schéma de relation très simpliste qui permet à une seule mise à jour/insertion de s'appliquer à un enregistrement et à toutes ses dépendances. Pour simplifier les choses, nous n'avons pas utilisé cette option sur les requêtes, et nous avons spécifiquement décidé de ne pas la prendre en charge avec les suppressions car il est plus fiable d'utiliser des suppressions en cascade.

Cette enveloppe a été utilisée avec succès dans deux projets à ce jour. Il est, bien sûr, léger, mais de nos jours tout le monde dit que leur code est léger. Plus important encore, il augmente la productivité des programmeurs, diminue le nombre de bogues (et rend les problèmes plus faciles à localiser), et il est relativement facile de les tracer si nécessaire, car nous ne croyons pas à l'ajout de nombreuses couches.

5

Spring-JDBC est fantastique. Considérons que pour un projet open source comme Spring, l'inconvénient de la dépendance externe est minimisé. Vous pouvez adopter la version la plus stable de Spring qui satisfait vos exigences d'abstraction JDBC et vous savez que vous serez toujours capable de modifier le code source vous-même si jamais vous rencontrez un problème - sans dépendre d'une partie externe. Vous pouvez également examiner l'implémentation pour tout problème de sécurité que votre organisation pourrait rencontrer avec du code écrit par une partie externe.

1

Essayez JdbcSession à partir de jcabi-jdbc. Il est aussi simple que JDBC devrait être, par exemple:

String name = new JdbcSession(source) 
    .sql("SELECT name FROM foo WHERE id = ?") 
    .set(123) 
    .select(new SingleOutcome<String>(String.class)); 

C'est tout.

1

Cela ressemble à une décision très courte vue. Considérez le coût de développement/maintien d'un tel cadre, surtout quand vous pouvez l'obtenir, et son code source gratuitement. Non seulement vous n'avez pas à faire vous-même le développement, vous pouvez le modifier à volonté si besoin est. Ceci étant dit, ce que vous avez vraiment besoin de dupliquer est la notion de JdbcTemplate et ses callbacks (PreparedStatementCreator, PreparedStatementCallback), ainsi que RowMapper/RowCallbackHandler. Il ne devrait pas être trop compliqué d'écrire quelque chose comme ça (surtout si l'on considère que vous n'avez pas à gérer les transactions).

Comment, comme je l'ai dit, pourquoi l'écrire quand vous pouvez l'obtenir gratuitement et modifier le code source comme bon vous semble?

2

Celui que je préfère: Dalesbred. C'est une licence MIT.

Un exemple simple d'obtention de toutes les lignes pour une classe personnalisée (Département).

List<Department> departments = db.findAll(Department.class, 
    "select id, name from department"); 

lorsque la classe personnalisée est définie comme:

public final class Department { 
    private final int id; 
    private final String name; 

    public Department(int id, String name) { 
     this.id = id; 
     this.name = name; 
    } 
} 

Avertissement: il est par une entreprise où je travaille.