8
votes

Constructeurs génériques Java

J'ai actuellement le code suivant qui récupère des données de la base de données, puis crée un utilisateur code>. Ce code est utilisé dans beaucoup de ma Classe pour créer d'autres objets tels que News code>, Commentaires code> etc ...

Il utilise Apache Commons Dbutils. P> xxx pré>

serait possible d'envelopper le QueryRunner code> dans une classe générique et remplacer la méthode de la requête afin que le gestionnaire instançant le générique t code> avec le Resultset. Je vérifierais que tout type t code> serait un constructeur acceptant un constructeur d'acceptation d'un résultatsset code>. P>

Comme: p>

public abstract class DatabaseEntity {
    public static abstract DatabaseEntity create(ResultSet rs);//even this doesn't work...
}


2 commentaires

Pourquoi avez-vous besoin de passer T type dans le constructeur?


Utilisez la réflexion Vous pouvez invoquer le constructeur de classe avec un ensemble de résultats


3 Réponses :


0
votes

Je ne pense pas qu'il soit possible de le faire en Java. Vous ne pouvez pas créer une instance de t dans un générique. Les génériques de Java ne sont pas vraiment des modèles comme en C ++, ils ne sont que Syntaxe Sugar autour d'un objet qui supprime les moulages et induit des avertissements de temps de compilation.

Il n'y a aucun moyen comme dans C # pour contraindre t de sorte qu'il doit avoir un constructeur.

Votre meilleur pari si cela est vraiment nécessaire pour résoudre la classe appropriée à l'aide de la réflexion, mais même lorsque vous rencontrez des problèmes car vous ne pouvez pas connaître la classe d'exécution de t comme la méthode est en cours d'appel - ces informations sont dépouillées de la Java Bytecode. Donc, vous êtes laissé en passant la classe à la méthode afin d'utiliser la réflexion sur elle. Et je ne suis pas trop sûr que ce soit une bonne idée de design quand même.


3 commentaires

Il peut le faire avec une réflexion tout comme JB NIZET.


Certainement possible. Vous avez juste besoin d'une référence à classe .


Oui, avec la réflexion. Vous auriez encore besoin de passer la classe réelle à la méthode. Vous ne pouvez pas T.class que vous voulez faire, a eu l'information de classe présent lors de l'exécution.



3
votes

Vous pouvez faire quelque chose comme ça (en faisant passer la classe de l'objet à créer et utiliser la réflexion pour appeler son constructeur), mais je trouverais la mauvaise conception d'avoir le pojo en fonction du JDBC et de savoir non seulement comment il s'agit stocké dans la base de données, mais aussi quels alias ont été utilisés dans la requête utilisée pour le charger.

En bref, il incombe au constructeur de pojo de l'utilisateur de gérer une série de résultats d'une requête inconnue externe.

Vous pouvez concevoir une superclasse abstraitement Pré> xxx

bloc, et déléguerait la création d'entité réelle à une méthode abstraite, mais vous ne gagneriez pas beaucoup.


4 commentaires

+1 pour être plus rapide que moi et écrire exactement ce que je voulais;)


J'essaie de le faire parce que le corps du gestionnaire que vous voyez ci-dessus dans le premier bloc du code, se répéter dans chaque requête pour n'importe quel objet. Je pensais qu'il aurait été agréable de s'assurer que mes objets provenant de la DB savent se construire d'un résultat de requête La méthode requête renvoie directement l'objet.


Et qu'entendez-vous par Pojo?


Pojo = objet java clair simple. Un objet qui ne dépend de aucun environnement, tel qu'un conteneur JEE ou, dans votre cas, l'API JDBC. Vous devrez avoir ce code quelque part: dans un gestionnaire ou dans le constructeur. Le moyen le plus approprié est de le placer dans un gestionnaire et non dans le constructeur. Je ne vois pas pourquoi la mettre dans le constructeur éviterait toute répétition.



8
votes

possible, oui? Mais c'est une mauvaise idée.

Vous pouvez faire: p>

h = new ResultSetHandler<Person>() {
  protected Person create(ResultSet rs) {
    return new Person(rs.getString("name"));
  }
}


4 commentaires

+1 pour fournir la même réponse que la mienne, mais avec des exemples de code Nice.


Vous dites que mélanger la base de données avec le domaine n'est pas une bonne idée et je reçois cela, mais que feriez-vous pour construire ces objets des résultats de la requête?


J'utilise une architecture MVC, donc mon modèle est là pour persistence et sait comment sauver et se mettre à jour dans la base de données mais j'utiliser un utilitaire pour effectuer les requêtes sur la base de données. Peut-être utiliser DAO?


Oui, une couche DAO est ce que vous finiriez de faire. Essentiellement, une couche qui sait convertir entre les deux.