java générique constructeurs
Actuellement j'ai le code suivant qui récupère les données de la base de données, puis créer un User
. Ce code est utilisé dans de nombreux de ma classe pour créer d'autres objets tels que des News
, Comments
etc...
Il utilise apache commons dbutils.
final ResultSetHandler<User> handler = new ResultSetHandler<User>() {
@Override
public User handle(ResultSet rs) throws SQLException {
User user = null;
if (rs.next()) {
user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
}
return user;
}
};
final User user = run.query(
"SELECT id, username, password FROM users WHERE username = ? AND active = 2 LIMIT 1;", handler,
username);
Serait-il possible d'encapsuler le QueryRunner
dans une classe générique et de remplacer la méthode de requête afin que le gestionnaire instancier le générique T
avec le jeu de résultats. Je voudrais assurez-vous que tout T
type devrait avoir un constructeur acceptant un ResultSet
.
Comme suit :
public class QueryExecuter<T> extends QueryRunner {
private ResultSetHandler<T> _handler;
public QueryExecuter(){//The T type was for testing haha
super();
handler = new ResultSetHandler<T>() {
@Override
public T handle(ResultSet rs) throws SQLException {
T object = null;
if (rs.next()) {
object = new T(rs);
}
return object;
}
};
}
}
Je ne sais pas si vous allez comprendre, mais je l'espère, me demander si vous voulez plus de détails ou une meilleure explication.
MODIFIER
Je pensais que je pouvais utiliser un AbstractClass plutôt du type générique que tous les différents objets s'étend, mais il me semble que je ne peux pas écrire un résumé constructeur. Vais-je devoir faire une méthode statique qui renvoie une instance de l'objet comme:
public abstract class DatabaseEntity {
public static abstract DatabaseEntity create(ResultSet rs);//even this doesn't work...
}
T type
dans le constructeur?utiliser la réflexion, vous pouvez appeler le constructeur de la classe avec le jeu de résultats
OriginalL'auteur David | 2012-02-07
Vous devez vous connecter pour publier un commentaire.
Possible, oui? Mais ses une mauvaise idée.
Que vous pouvez faire:
Mélange de domaine et la base de données est une mauvaise idée, cependant. Ce qui serait mieux, cependant, serait de définir un abtract méthode qui crée l'objet basé sur le jeu de résultats:
Ensuite, dans la mise en œuvre de votre classe, vous avez seulement besoin de fournir un
create()
méthode au lieu de la manipulation de l'ensemble de résultats vous-même, par exemple:Vous dites que le mélange de la base de données avec le domaine n'est pas une bonne idée, et je le conçois, mais que voulez-vous faire pour construire ces objets à partir de résultats de la requête?
Je suis en utilisant l'architecture MVC, donc mon modèle est-il de la persistance et de la sait comment enregistrer et mettre à jour dans la base de données mais j'utilise un utilitaire pour effectuer les requêtes sur la base de données. Peut-être que vous utilisez DAO?
Oui, une couche DAO est ce que vous souhaitez faire. Essentiellement, une couche qui sait comment convertir entre les deux.
OriginalL'auteur Reverend Gonzo
Vous pourriez faire quelque chose comme ça (en passant par la classe de l'objet à créer, et d'utiliser la réflexion pour appeler son constructeur), mais je pense qu'il serait mauvais design afin d'avoir le POJO dépend de JDBC, et non seulement la connaissance de la façon dont il est stocké dans la base de données, mais aussi les alias ont été utilisés dans la requête utilisée pour le charger.
En bref, c'est pas de la responsabilité de l'Utilisateur POJO constructeur de gérer un ensemble de résultats d'une externe, l'inconnu de la requête.
Vous pouvez concevoir un AbstractSingleEntityHandler superclasse qui aurait juste le
bloc, et délèguent l'entité réelle création d'une méthode abstraite, mais vous ne pouvez pas gagner beaucoup.
Je suis en train de le faire parce que le gestionnaire de corps que vous voyez ci-dessus dans le premier bloc de code, se répète à chaque requête pour n'importe quel objet. J'ai pensé qu'il aurait été agréable de faire en sorte que mes objets qui vient de la db de savoir comment se construisent à partir d'un résultat de la requête, le
query
méthode doit retourner directement l'objet.Et qu'entendez-vous par POJO?
POJO = Plain Old Java Object. Un objet qui ne dépend pas de n'importe quel environnement, tel qu'un conteneur JEE ou, dans votre cas, l'API JDBC. Vous devrez avoir ce code quelque part: soit dans un gestionnaire, ou dans le constructeur. La manière la plus appropriée est de la placer dans un gestionnaire, et non pas dans le constructeur. Je ne vois pas pourquoi le mettre dans le constructeur d'éviter toute répétition.
OriginalL'auteur JB Nizet
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 médicaments génériques en java ne sont pas vraiment les templates en C++, ils sont seulement la syntaxe de sucre autour d'unobject
qui supprime la jette et induit des temps de compilation des avertissements.Il n'existe aucun moyen comme en C# pour contraindre
T
de sorte qu'il doit avoir un constructeur.Votre meilleur pari si c'est vraiment nécessaire, c'est de résoudre la classe appropriée à l'aide de la réflexion, mais même alors, vous allez courir dans problème puisque vous ne pouvez pas connaître la classe d'exécution de T que la méthode est invoquée - cette information est supprimée à partir du bytecode java. Donc, vous êtes de gauche avec passage de la classe de la méthode pour utiliser la réflexion sur celle-ci. Et je ne suis pas trop sûr que c'est une bonne idée de la conception de toute façon.
Certainement possible. Vous avez juste besoin d'une référence à
Class<T>
.Oui, avec la réflexion. Vous souhaitez toujours besoin de passer à la classe réelle de la méthode. Vous ne pouvez pas aller T.class que vous aimeriez faire, a la classe de renseignements été présent au moment de l'exécution.
OriginalL'auteur Dervall