实体类如何在AbstractGenericDao中工作?

时间:2019-06-08 14:51:09

标签: java spring hibernate jpa

以下是我的一个办公室项目中的代码吗?

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)'em.persist'是什么? (3)“合并”是什么? (4)findReferece方法在做什么? (5)getSession方法在做什么?它返回什么样的会话?

请帮助,我是Java新手!

1 个答案:

答案 0 :(得分:0)

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个问题。