JPA:一个DAO管理所有实体还是每个实体都有一个DAO?

4

首先,抱歉我的英语不好。

我正在为一个朋友制作一个使用JPA(EclipseLink)访问SQLite数据库的桌面应用程序。

我已经在Eclipse中创建了数据库和实体。但我还创建了一个名为UniversalDAO的类,它是所有实体用于访问和持久化数据库的实用程序类:

package model.DAO;

import java.util.ArrayList;

import javax.persistence.*;

import model.entities.Entities;


public class UniversalDAO {


    private static EntityManagerFactory emf = Persistence.createEntityManagerFactory("TheDatabase");
    private static EntityManager em = emf.createEntityManager();

    private UniversalDAO (){}


    public static void close(){
        em.close();
        emf.close();
    }

    public static Entities getOne(Class<? extends Entities> table, Object primaryKey) {

        return em.find(table, primaryKey);
    }

    public static ArrayList<Entities> getAll(Class<? extends Entities> table) {

        ArrayList<Entities> ret = new ArrayList<>();

        for(Object obj : em.createQuery("SELECT o FROM " + table.getName() + " o").getResultList())
            ret.add((Entities) obj);

        return ret;
    }

    public static ArrayList<Entities> getWithCondition(Class<? extends Entities> table, String condition) {

        ArrayList<Entities> ret = new ArrayList<>();

        for(Object obj : em.createQuery("SELECT o FROM " + table.getName() + " o WHERE " + condition).getResultList())
            ret.add((Entities) obj);

        return ret;
    }

    public static void insert(Entities row) {
        em.getTransaction().begin();

        em.persist(row);

        em.flush();

        em.getTransaction().commit();
    }

    public static void update(Entities row) {

        em.getTransaction().begin();

        em.merge(row);

        em.flush();

        em.getTransaction().commit();
    }

    public static void delete(Class<? extends Entities> table, Object primaryKey) {

        em.getTransaction().begin();

        Entities row = em.find(table, primaryKey);

        em.remove(row);

        em.flush();

        em.getTransaction().commit();
    }
}

为了将所有实体分组并在此类中使用它们,我创建了一个空接口称为Entities
以下是其中一种实体的样子:
package model.entities;

import java.util.ArrayList;

import javax.persistence.*;


@Entity
@Table(name="emails")
public class EntityEmail implements Entities {

    @Id
    @Column(name="id_email")
    @GeneratedValue(strategy=GenerationType.SEQUENCE)
    private int idEmail;

    @Column(name="email")
    private String email;

    @Column(name="description")
    private String description;

    @ManyToMany(fetch=FetchType.EAGER)
    @JoinTable(name="people_emails",
               joinColumns=@JoinColumn(name="id_email", referencedColumnName="id_email"),
               inverseJoinColumns=@JoinColumn(name="id_person", referencedColumnName="id_person"))
    private ArrayList<EntityPerson> people;

    public EntityEmail() {

    }   

    public int getIdEmail() {
        return this.idEmail;
    }
    public void setIdEmail(int idEmail) {
        this.idEmail = idEmail;
    }   

    public String getEmail() {
        return this.email;
    }
    public void setEmail(String email) {
        this.email = email;
    }

    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    public ArrayList<EntityPerson> getPeople() {
        return people;
    }
    public void setPeople(ArrayList<EntityPerson> people) {
        this.people = people;
    }   
}

我理解我不是专业人士,仍有许多需要学习。因此,我在想这种方法是否正确,或者我应该为每个实体设置一个DAO。


你可能想阅读http://www.tutorialspoint.com/design_pattern/data_access_object_pattern.htm - JohannesDienst
1个回答

7

看起来您正在尝试发明通用DAO模式。如果是这样,您基本上走在了正确的路上。

通用DAO模式的工作原理如下:

  • Create a generic base class that all your DAOs will extend:

    public abstract class GenericDao<E, ID extends Serializable> {
        ...
        // Implement common operations that are relevant to all entities here:
        public E findById(ID id) { ... }
        public void save(E entity) { ... }
        // etc
        ...
    }
    
  • Create concrete DAO implementations by extending GenericDao:

    public class EntityEmailDao extends GenericDao<EntityEmail, Integer> {
        // This class may contain operations that are relevant to specific entity:
        public E findByEmail(String email) { ... }
    }
    
  • Since GenericDao is generic, you don't need to make your entities extend any common interface

这种模式已经有很多现有的实现,例如可以看一下这里


我喜欢这个想法。由于我的所有实体将做几乎相同的事情,拥有重复的dao类是不好的。拥有一个抽象类,然后为每个实体创建一个扩展该抽象类的类是正确的做法。每个dao都有共享行为和特定行为。我会这样做,非常感谢 ;) - ivan0590

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接