java 使用 dao 接口和实现实现通用抽象实体类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26782583/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Implement Generic Abstract Entity class with dao interface and implemantation
提问by masterdany88
Hey I would like to have generic model/entity class that would download by id of type long element from db. The method for that is like this:
嘿,我想要通用模型/实体类,它可以通过 db 中的 long 元素类型的 id 下载。方法是这样的:
public class GenericModel {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long id;
public static GenericModel getBy(Long id) {
return JPA.em().find(GenericModel.class, id);
}
}
But in Generic model that will be extended by child model class I'have to dynamically declare entity class name to find in db.
但是在将由子模型类扩展的通用模型中,我必须动态声明实体类名称以在 db 中查找。
I would like to have generic entity class where I will have common methods like getById(). And that generic class will be extended by concret entity class. I will not have to write in each model class the same method, cause it will be inherited from generic class –
我想要通用实体类,我将在其中使用 getById() 等常用方法。并且该通用类将通过具体实体类进行扩展。我不必在每个模型类中编写相同的方法,因为它将从泛型类继承 –
How can I achive this?
我怎样才能做到这一点?
Here is my DAO interface. I am not quite sure of it:
这是我的 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();
}
And My DAO implementation class of this interface
而这个接口的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);
}
}
And my GenericModel Class
还有我的 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;
}
}
Please give me some extra help once more :D
请再给我一些额外的帮助:D
回答by Manuel Verriez
You cannot use generics parameters in a static method (see https://stackoverflow.com/a/936951/1643132for more details), so you will have to remove static keyword from getBy() method.
您不能在静态方法中使用泛型参数(有关更多详细信息,请参阅https://stackoverflow.com/a/936951/1643132),因此您必须从 getBy() 方法中删除 static 关键字。
As a first step, you can introduce generics in your GenericModel class:
作为第一步,您可以在 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);
}
}
The problem is, something like T.class will not work (in getBy() method). Thanks to java.lang.reflect.ParameterizedType, you can retrieve T class at runtime. So update you GenericModel to :
问题是,像 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;
}
}
Your child entity may look like:
您的子实体可能如下所示:
@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;
}
}
回答by masterdany88
Here is my working code. Hopes helps someone else :D
这是我的工作代码。希望能帮助别人:D
Generic Model/Entity class
通用模型/实体类
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 interface
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 class
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();
}
}
My working class example: Customer Model/Entity class
我的工作班示例: 客户模型/实体类
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name="common__Customer")
public class Customer extends GenericModel<Customer> {}
CustomerDao interface
CustomerDao 接口
import com.common.model.Customer;
public interface CustomerDao extends GenericModelDao<Customer> {}
CustomerDaoImpl class
CustomerDaoImpl 类
import org.springframework.stereotype.Repository;
import com.common.model.Customer;
@Repository
public class CustomerDaoImpl extends GenericModelDaoImpl<Customer> implements CustomerDao {}