Logiciel de saisie des requêtes nommées dans un résumé, DAO, JPA
J'ai un résumé de DAO classe qui utilise le type paramétré E
(Entité) et K
(Clé Primaire). Dans chaque entité, j'ai un @NamedQuery
. Je veux invoquer dynamiquement cette requête nommée sans connaître son nom exact et le nom du paramètre.
Comme un exemple, imaginer la suite de l'entité City
@Entity(name="CITY")
@NamedQuery(
name="findCityByname",
query="FROM CITY c WHERE name = :CityName"
)
public class City {
//...
}
et ce CityDao
public class CityDao extends AbstractDao<City, Long> {
public CityDao() {
super(City.class);
}
}
Comment dois-je mettre en œuvre les findByName()
méthode dans AbstractDao
de sorte que je n'ai pas besoin de connaître le nom exact et le nom du paramètre?
public abstract class AbstractDao<E, K> implements Dao<E, K> {
@PersistenceContext
protected EntityManager entityManager;
protected Class<E> entityClass;
protected AbstractDao(Class<E> entityClass) {
this.entityClass = entityClass;
}
@Override
public E findByName(String name) {
try {
return (E) entityManager
.createNamedQuery("findCityByName")
.setParameter("CityName", name)
.getSingleResult();
} catch(Exception e) {
return null;
}
}
//...
}
OriginalL'auteur yoav.str | 2011-02-03
Vous devez vous connecter pour publier un commentaire.
La convention de nommage pour les requêtes nommées est généralement
<Entity Name>.findBy<PropertyAndAnotherProperty>
, "de la Ville.findByName" dans votre exemple, je voudrais donc essayer de modifier les requêtes nommées à suivre ce modèle. Le paramètre de cette requête devrait également avoir le même nom, ou vous pouvez utiliser les paramètres positionnels. Votre méthode de recherche se transforme alors enOriginalL'auteur Jörn Horstmann
La méthode la plus simple est de passer le nom de la requête pour le constructeur de l'abstrait DAO:
Puis de définir un public static final String dans la Ville pour conserver le nom:
Vous pouvez également déclarer DaoAbstreact abstraite, et ensuite une méthode comme ceci:
Et à mettre en œuvre que dans ConcreteCityDao.
Enfin, vous pourrez également introduire une énumération:
Alors votre DAO pouvez déterminer le type de la classe passée. Pour vous assurer que vous n'oubliez pas d'ajouter une entité à l'énumération, vous pouvez faire de chaque entité de mettre en œuvre une interface avec un getNamedEntityType() la méthode. Ensuite, vous pouvez spécifier que votre abstraite générique DAO acceptera uniquement les entités qui implémentent cette interface.
OriginalL'auteur Russ Hayward
Le moyen le plus évident serait de transmettre des valeurs de classes concrètes de la super-classe abstraite à l'aide de
abstract
méthodeou comme un argument du constructeur:
Bien que cela nécessite cohérent de nommage des paramètres de requête pour différentes entités.
Également note des améliorations mineures dans ces extraits.
OriginalL'auteur axtavt
Ce que vous avez l'air de vouloir consiste à annoter les annotations qui définissent les requêtes nommées, de telle manière que vous pouvez par programme à découvrir ce qu'est la "findByName" requête est (et éventuellement d'autres requêtes).
Puisque ce n'est pas possible en Java, vous pouvez utiliser le fait que @NamedQuery prend en charge les indicateurs de requête, qui sont définis comme étant spécifiques au fournisseur. Inconnu conseils sont ignorés. Vous pouvez ajouter vos propres données ici, que le générique de DAO peuvent lire de la
entityClass
:OriginalL'auteur Arjan Tijms