【问题标题】:Implement Generic Abstract Entity class with dao interface and implemantation使用 dao 接口和实现实现通用抽象实体类
【发布时间】:2014-11-06 15:02:12
【问题描述】:

嘿,我想要一个通用模型/实体类,它可以通过 id 类型的 long 元素从 db 下载。方法是这样的:

public class GenericModel   {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long id;

    public static GenericModel getBy(Long id) {
        return JPA.em().find(GenericModel.class, id);
    }
}

但在将由子模型类扩展的通用模型中,我必须动态声明实体类名称才能在 db 中找到。

我想有一个通用实体类,我将有像 getById() 这样的通用方法。并且该通用类将由具体实体类扩展。我不必在每个模型类中编写相同的方法,因为它会从泛型类继承——

我怎样才能做到这一点?

这是我的 DAO 界面。我不太确定:

public interface GenericModelDao<T> {
    public void add(T entityClass);
    public void update(T entityClass);
    public void delete(long id);
    public T get(long id);
    public List<T> get();
}

以及这个接口的My DAO实现类

 @Repository
public class GenericModelDaoImpl <T extends GenericModel> implements GenericModelDao {
    public Class<T> entityClass;

    GenericModelDaoImpl(){
        setEntityClass(((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));
    }
    public void setEntityClass(Class<T> entityClass) {
        this.entityClass = entityClass;
    }
    @Autowired
    private SessionFactory sessionFactory;
    private Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public T get(long id) {
        return (T) getCurrentSession().get(entityClass, id);
    }
    @Override
    public void delete(long id) {
        T entityClass = get(id);
            getCurrentSession().delete(entityClass);
    }
    @Override
    public List<T> get() {
        return getCurrentSession().createQuery("from " + entityClass ).list();
    }
    @Override
    public void add(Object entityClass) {
        getCurrentSession().save(entityClass);
    }
    @Override
    public void update(Object entityClass) {
        getCurrentSession().update(entityClass);
    }
}

还有我的 GenericModel 类

@MappedSuperclass
public abstract class GenericModel<T extends GenericModel> {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long id;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

}

请再给我一些额外的帮助:D

【问题讨论】:

  • 我很难理解你想做什么。
  • 我想要一个通用的实体类,我将有像 getById() 这样的通用方法。并且该通用类将由具体实体类扩展。我不必在每个模型类中编写相同的方法,因为它将继承自泛型类

标签: java spring jpa model entity


【解决方案1】:

您不能在静态方法中使用泛型参数(有关详细信息,请参阅https://stackoverflow.com/a/936951/1643132),因此您必须从 getBy() 方法中删除 static 关键字。

作为第一步,您可以在 GenericModel 类中引入泛型:

public abstract class GenericModel<T extends GenericModel> {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long id;

    public T getBy(Long id) {
        return JPA.em().find(????, id);
    }
}

问题是,像 T.class 这样的东西不起作用(在 getBy() 方法中)。 感谢 java.lang.reflect.ParameterizedType,您可以在运行时检索 T 类。因此,将您的 GenericModel 更新为:

@MappedSuperclass
public abstract class GenericModel<T extends GenericModel> {

    private Class<T> entityClass;

    GenericModel(){
        entityClass = ((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
    }

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    public Long id;

    public T getBy(Long id) {
        return JPA.em().find(entityClass, id);
    }

    public Long getId() {
        return id;
    }
}

您的子实体可能如下所示:

@Table(name="child_model")
@javax.persistence.Entity
public class ChildModel extends GenericModel<ChildModel> {

    @Column
    private String data;

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

【讨论】:

  • 我已经按照您指出的方式做了,它就像一个魅力。但我需要一个DAO接口和该接口的DAO实现类。你能给我一些建议吗?
  • 这篇文章对我有很大帮助:link
  • Manuel Verriez 可以看看这个帖子:stackoverflow.com/questions/26846192/…
【解决方案2】:

这是我的工作代码。希望能帮助别人:D

通用模型/实体类

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

@MappedSuperclass
public abstract class GenericModel<T extends GenericModel<?>> {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    private String name;

    public long getId() {return id;}
    public void setId(long id) {this.id = id;}
    public String getName() {return name;}
    public void setName(String name) {this.name = name;}

}

GenericModelDao 接口

import java.util.List;

public interface GenericModelDao<T> {
    public void add(T entityClass);
    public void update(T entityClass);
    public void delete(long id);
    public T get(long id);
    public T getByName(String name);
    public List<T> get();
}

GenericModelDaoImpl 类

import java.lang.reflect.ParameterizedType;
import java.util.List;

import javax.persistence.MappedSuperclass;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import model.GenericModel;

@Repository
@MappedSuperclass
public abstract class GenericModelDaoImpl <T extends GenericModel> implements GenericModelDao<T> {
    GenericModelDaoImpl(){
        setEntityClass(((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]));
    }

    public Class<T> entityClass;

    public Class<T> getEntityClass() {
        return entityClass;
    }
    public void setEntityClass(Class<T> entityClass) {
        this.entityClass = entityClass;
    }
    @Autowired
    private SessionFactory sessionFactory;
    private Session getCurrentSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public void add(T entityClass) {
        getCurrentSession().save(entityClass);
    }
    @Override
    public void update(T entityClass) {
        getCurrentSession().update(entityClass);
    }
    @Override
    public void delete(long id) {
        getCurrentSession().delete(get(id));
    }
    @Override
    public T get(long id) {
        return (T) getCurrentSession().get(entityClass, id);
    }
    @Override
    public T getByName(String name) {
        return (T) getCurrentSession().createQuery("FROM e " + entityClass.getSimpleName() + " WHERE name:=name").setParameter("name", name);
    }
    @Override
    public List<T> get() {
        return getCurrentSession().createQuery("FROM " + entityClass.getSimpleName() ).list();
    }
}

我的工人阶级例子: 客户模型/实体类

import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name="common__Customer")
public class Customer extends GenericModel<Customer> {}

CustomerDao 界面

import com.common.model.Customer;
public interface CustomerDao  extends GenericModelDao<Customer> {}

CustomerDaoImpl 类

import org.springframework.stereotype.Repository;
import com.common.model.Customer;

@Repository
public class CustomerDaoImpl extends GenericModelDaoImpl<Customer> implements CustomerDao {}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-17
    • 2014-08-18
    • 1970-01-01
    • 2013-01-30
    • 2012-01-20
    • 2012-09-02
    • 2014-02-05
    • 2019-05-27
    相关资源
    最近更新 更多