DAO

Disponible

Présentation de DAO

Lorsque vous travaillez avec une base de données via JDBC ou même via Hibernate, le code s'avère souvent plus lourd que nous ne le souhaiterions. Une requête de base de données contient souvent :

  • la validation des données
  • définition des paramètres de requête
  • Sélection de requête HQL en fonction des paramètres de requête
  • construction d'une requête à l'aide de l'API Criteria
  • paramètres de mise en cache
  • traitement initial des erreurs, etc.

Par conséquent, la pratique courante consiste à créer des classes spéciales pour travailler avec la base de données. Ces classes sont appelées DAO, Data Access Object. Leur tâche est de cacher toutes les complexités du travail avec la base de données et de fournir une interface belle et pratique à l'extérieur.

Exemple:

public class EmployeeDAO {

   public List<Employee> getEmployeeList(int from, int count) {
   	String hqlQuery = “from Employee;
   	Query<Employee> query = session.createQuery(hqlQuery, Employee.class);
   	query.setFirstResult(from);
   	query.setMaxResults(count);
   	return query.getResultList();
  }

	public int getEmployeeCount() {
	     String hqlQuery = “select count(*) from Employee;
     	Query<Integer> query = session.createQuery(hqlQuery, Integer.class);
     	return query.getSingleResult();
   }

	public Employee getEmployeeByUniqName(String name) {
	     String hqlQuery = “from Employee where name = :name”;
     	Query<Integer> query = session.createQuery(hqlQuery, Employee.class);
     	query.setParameterr(“name”, name);
     	return query.getSingleResult();
   }
}

Nous avons une classe EmployeeDAO , à l'aide de laquelle nous obtenons des objets de type Employee à partir de la base de données. La classe elle-même, bien que truffée d'annotations, ne contient pas de méthodes pour s'enregistrer dans la base de données.

Avantages du DAO

Il y a de nombreux avantages à cette approche :

Tout d'abord, nous avons complètement caché le travail avec la base de données dans la classe DAO. Si vous décidez à l'avenir de réécrire toutes les requêtes de HQL vers l'API Criteria ou la requête native, cela n'affectera en rien le code en dehors de cette classe.

Deuxièmement, vous pouvez compliquer le comportement de ces méthodes. Vous pouvez ajouter la mise en cache, les événements, la validation des paramètres. Tout cela sera caché du code extérieur.

Troisièmement, si vous avez besoin d'une méthode qui n'existe pas encore, il vous suffit de l'ajouter ici. Par exemple, j'ai besoin d'une méthode qui renverra toutes les tâches utilisateur qui ont déjà expiré. Ensuite je vais juste faire ça :

public class EmployeeDAO {

   public List<Task> getExpiredTasks(int userId, int from, int count) {
   	String hqlQuery = “from Task where task.user.id = :id and deadline < curdate();
   	Query<Task> query = session.createQuery(hqlQuery, Task.class);
   	query.setFirstResult(from);
   	query.setMaxResults(count);
   	return query.getResultList();
  }

   public int getExpiredTasksCount(int userId) {
   	String hqlQuery = “select count(*) from Task where task.user.id = :id and deadline < curdate();
   	Query<Integer> query = session.createQuery(hqlQuery, Integer.class);
   	return query.getSingleResult();
  }
}

J'ai ajouté deux méthodes à la classe:

  • getExpiredTasksCount() - renvoie le nombre de tâches expirées pour l'utilisateur
  • getExpiredTasks() - renvoie une liste des tâches expirées pour l'utilisateur

J'ai besoin de méthodes - je les ai ajoutées. Et je peux l'utiliser tout de suite. Je les optimiserai plus tard.

De plus, ces méthodes peuvent être recouvertes de tests unitaires avant réécriture et optimisations, nous saurons donc que le travail avec la base de données est resté le même qu'il était.

Approche standard

Très souvent, les classes DAO ont des méthodes qui sont les mêmes. Par exemple, ceux-ci :

T getById (identifiant long final) Obtenir un objet par son identifiant
List<T> getItems (int from, int count) Obtenir une liste d'objets dans une plage donnée
Liste<T> getAll () Obtenir tous les objets d'un type donné
int getCount () Découvrez le nombre d'objets
T save (entité T finale) Enregistrer l'objet dans la base de données
Mise à jour T (entité T finale) Mettre à jour l'objet dans la base de données
void delete (entité T finale) Supprimer un objet de la base de données
annuler deleteById (final long entityId) Supprimer l'objet de la base de données par identifiant

Ces méthodes se retrouvent dans presque toutes les classes DAO dans le monde. Maintenant, s'il existe une sorte de classe DAO, alors avec une probabilité de 90%, elle aura de telles méthodes.

Oui, il y en aura peut-être d'autres, mais il y en aura aussi. Parce que c'est très pratique. Et cela vous permet de ne pas interagir directement avec la base ou Hibernate.

Et s'il existe des méthodes identiques, alors de quoi ont-elles besoin? C'est vrai, mettez-le dans la classe de base.

Cela ressemble à ceci :

public abstract class AbstractHibernateDao<T > {
    private final Class<T> clazz;
    private SessionFactory sessionFactory;

    public AbstractHibernateDao(final Class<T> clazzToSet)   {
    	this.clazz = clazzToSet;
    }

    public T getById(final long id) {
    	return (T) getCurrentSession().get(clazz, id);
    }

    public List<T> getItems(int from, int count) {
    	Query query = getCurrentSession().createQuery(clazz , "from " + clazz.getName())
    	query.setFirstResult(offset);
    	query.setMaxResults(count);
  	  return query.singleResult();
    }

    public List<T> findAll() {
    	return getCurrentSession().createQuery(clazz, "from " + clazz.getName()).list();
    }

    public T create(final T entity) {
    	getCurrentSession().saveOrUpdate(entity);
    	return entity;
    }

    public T update(final T entity) {
    	return (T) getCurrentSession().merge(entity);
    }

    public void delete(final T entity) {
    	getCurrentSession().delete(entity);
    }

    public void deleteById(final long entityId) {
    	final T entity = getById(entityId);
    	delete(entity);
    }

    protected Session getCurrentSession() {
    	return sessionFactory.getCurrentSession();
    }
}

Et puis notre EmployeeDAO ressemblera à ceci :

public class EmployeeDAO extends AbstractHibernateDAO<Employee> {

   public EmployeeDAO (){
  	super(Employee.class );
   }
}

Et TaskDAO est comme ça :

public class TaskDAO extends AbstractHibernateDAO<Task> {

   public TaskDAO (){
  	super(Task.class );
   }
}

Et ces deux classes auront toutes les méthodes que nous avons déclarées sur AbstractHibernateDAO . L'unification est très pratique et pratique.

Commentaires
  • Populaires
  • Nouveau
  • Anciennes
Tu dois être connecté(e) pour laisser un commentaire
Cette page ne comporte pas encore de commentaires