繁体   English   中英

道课的通用课

[英]Generic class for the Dao classes

我正在尝试设置一个通用类,该通用类将作为我的应用程序中所有Dao类的基类,但是我现在遇到错误。 我的通用类是这样定义的;

public class Dao<E> {

    private final E entity;

    @Autowired
    SessionFactory sessionFactory;

    protected Session getCurrentSession(){
        return sessionFactory.getCurrentSession();
    }

    public Dao(E entity) {  
        this.entity = entity;
    }

    public E getEntity() {
        return this.entity;
    }

    @Transactional
    public boolean persist(E transientInstance) {
        try {
            sessionFactory.getCurrentSession().persist(transientInstance);
            return true;
        } catch (RuntimeException re) {
            return false;
        }
    }

    @Transactional
    public boolean remove(E transientInstance) {
        try {
            sessionFactory.getCurrentSession().delete(transientInstance);
            return true;
        } catch (RuntimeException re) {
            return false;
        }
    }

    @SuppressWarnings("unchecked")
    @Transactional
    public E merge(E detachedInstance) {
        try {
            E result = (E) sessionFactory.getCurrentSession().merge(detachedInstance);
            return result;
        } catch (RuntimeException re) {
            return null;
        }
    }

    @Transactional
    public E findById(int id) {
        try {
            E instance = (E) sessionFactory.getCurrentSession().get(E, id);
            return instance;
        } catch (RuntimeException re) {
            return null;
        }
    }

    @SuppressWarnings("unchecked")
    @Transactional
    public E findByUsername(String username) {
        try {
            E instance = (E) sessionFactory.getCurrentSession().createCriteria(E, username).add(Restrictions.like("login", username)).list().get(0);
            return instance;
        } catch (RuntimeException re) {
            return null;
        }
    }

    @SuppressWarnings("unchecked")
    @Transactional
    public List<E> findAll() {
        try {
            List<E> instance = sessionFactory.getCurrentSession().createCriteria(E).list();
            return instance;
        } catch (RuntimeException re) {
            return null;
        }
    }

}

带有错误的方法是最后三个方法,它们在实现中与get()和createCriteria()对E的引用有关 (错误是E无法解析为变量 )。 通常,当我不使用这种基于泛型的方法时,我会使用类似“ Usuario.class”的名称。

任何人都知道如何在我的通用类中解决此错误(如果可能的话)。

首先,类型参数E不等于Class的实例。 其次,由于Java中的类型擦除,关于E的所有内容在运行时都会丢失。 但它表明,作为参数传递给构造函数的entity是在尝试查询类时使用的类型标记。 因此,请如下更改方法:

@Transactional
public E findById(int id) {
    try {
        E instance = (E) sessionFactory.getCurrentSession().get(entity.getClass(), id);
        return instance;
    } catch (RuntimeException re) {
        return null;
    }
}

@SuppressWarnings("unchecked")
@Transactional
public E findByUsername(String username) {
    try {
        E instance = (E) sessionFactory.getCurrentSession().createCriteria(entity.getClass(), username).add(Restrictions.like("login", username)).list().get(0);
        return instance;
    } catch (RuntimeException re) {
        return null;
    }
}

@SuppressWarnings("unchecked")
@Transactional
public List<E> findAll() {
    try {
        List<E> instance = sessionFactory.getCurrentSession().createCriteria(entity.getClass()).list();
        return instance;
    } catch (RuntimeException re) {
        return null;
    }
}

或者,如果entity不是您的类型令牌,则向构造函数添加参数Class<E> clazz ,如下所示:

private final E entity;
private final Class<E> clazz;

public Dao(E entity, Class<E> clazz) {  
    this.entity = entity;
    this.clazz = clazz;
}

并在建议的方法中使用clazz而不是entity.getClass()

只需添加上面的答案即可。 如果您不想将参数传递给构造函数,则可以执行以下操作:

private Class<T> type;

public Dao(){

    Type t = getClass().getGenericSuperclass();
    ParameterizedType pt = (ParameterizedType) t;
    type = (Class<T>) pt.getActualTypeArguments()[0];
}

然后在进行查询时在条件中引用类型。

附录:从DAO层中删除@Transactional批注,@ @Transactional属于您的服务层

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM