以下是我的一个项目办公室中的代码?
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.lang.reflect.ParameterizedType;
import org.hibernate.Session;
import org.springframework.transaction.annotation.Transactional;
import com.sha.microservicecoursemanagement.model.IModel;
@Transactional
public class AbstractGenericDao<T extends IModel> implements IGenericDao<T> {
@PersistenceContext
protected EntityManager em;
protected Class<T> entityClass =
(Class<T>) ((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
@Override
public T find(Long id) {
return em.find(entityClass, id);
}
@Override
public List<T> findAll() {
try {
final List<T> resultList =
(this.em.createQuery("SELECT v FROM " + this.entityClass.getCanonicalName() + " v").getResultList());
return resultList;
}
catch(final RuntimeException e) {
e.printStackTrace();
}
return null;
}
@Override
public void save(T entity) {
em.persist(entity);
}
@Override
public T update(T entity) {
return em.merge(entity);
}
@Override
public void delete(final Long id) {
em.remove(findReference(id));
}
@Override
public T findReference(final Long id) {
return em.getReference(entityClass, id);
}
@Override
public Session getSession() {
return (Session) this.em.getDelegate();
}
}
我有很多问题,首先请看下面的代码:
在上面的代码中:
(1)以下是什么意思?
protected Class<T> entityClass =
(Class<T>) ((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
我们在上面的代码行中实际上在做什么?什么是“ ParameterizedType”,我们正在执行“ getGenericSuperClass()”。什么是getActualTypeAruments。
为什么我们采用第[0]个元素?
(2)什么是“持久”?
(3)什么是“合并”?
(4)findReferece方法在做什么?
(5)getSession方法在做什么?它返回什么样的会话?
请帮助,我是Java新手!
最佳答案
Java保留有关超类的泛型类型信息,您可以通过Class.getGenericSuperclass()
获得它。
由于您的AbstractGenericDao
应该被继承,因此this.getClass()
将始终返回AbstractGenericDao
的子类型。这意味着this.getClass().getGenericSuperclass()
将为您提供AbstractGenericDao
的完整通用类型,例如类似于AbstractGenericDao<Book>
。由于您知道AbstractGenericDao
是参数化类型(类型参数为T
),因此可以将其强制转换为ParameterizedType
,然后获取T
的实际类型,例如调用Book
来getActualTypeArguments()[0]
(因为T
是第一个也是唯一的参数)。从根本上说,在DAO中获取实体的实际类型是一种技巧。
现在,按照编写的方式,此代码存在问题。 AbstractEntityDao
不是抽象的,可以直接实例化,这将中断该行,因为其通用超类将是Object
。此外,如果某个类不是直接扩展AbstractEntityDao
而是通过一个以上的类扩展,则该行可能会再次中断,因为超类将不是AbstractEntityDao
。
至于其他4个问题-persist
将实体保存(持久)到数据库中。 merge
在数据库中更新它。这些都是基本的JPA / Hibernate概念,您将在阅读任何教程的5分钟之内学到这些概念。因此,在提出问题之前,请先进行自己的研究,不要在一个帖子中提出5个问题。