I've found a few tutorials on how to build a Hibernate DAO with generics, but they all use EntityManager
instead of a SessionFactory
. My question is how to build a DAO with generics using SessionFactory
. I have the below so far:
我已经找到了一些关于如何使用泛型构建Hibernate DAO的教程,但它们都使用EntityManager而不是SessionFactory。我的问题是如何使用SessionFactory使用泛型构建DAO。到目前为止,我有以下内容:
Interface:
接口:
public interface GenericDao<T> {
public void save(T obj);
public void update(T obj);
public void delete(T obj);
public T findById(long id);
}
Class:
类:
@Repository
public class GenericDaoImpl<T> implements GenericDao<T> {
@Autowired
private SessionFactory sessionFactory;
public void save(T obj) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.save(obj);
tx.commit();
} catch (HibernateException e) {
if(tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
public void update(T obj) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.update(obj);
tx.commit();
} catch (HibernateException e) {
if(tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
public void delete(T obj) {
Session session = sessionFactory.openSession();
Transaction tx = null;
try {
tx = session.beginTransaction();
session.delete(obj);
tx.commit();
} catch (HibernateException e) {
if(tx != null)
tx.rollback();
e.printStackTrace();
} finally {
session.close();
}
}
public T findById(long id) {
// ??
return null;
}
I'm unsure how to go about findById
using generics. I believe the other methods are right, but correct me if I'm wrong.
我不确定如何使用泛型来查找findById。我相信其他方法是正确的,但如果我错了,请纠正我。
SIDE QUESTION: Is using EntityManager
more beneficial than using SessionFactory
? I saw a few posts on the subject, but would like a few more opinions.
侧面问题:使用EntityManager比使用SessionFactory更有益吗?我看了几篇关于这个主题的帖子,但是想多点几点意见。
1 个解决方案
#1
5
You need to have access to the Class<T>
from within that method. You have two options, you can pass the Class<T>
into the method:
您需要从该方法中访问Class
public T findById(long id, Class<T> clazz) {
// method implementation
}
Or you can pass the Class<T>
into the constructor of the class for use in the method:
或者,您可以将Class
@Repository
public class GenericDaoImpl<T> implements GenericDao<T> {
private Class<T> clazz;
protected GenericDaoImpl(Class<T> clazz) {
this.clazz = clazz;
}
// other methods omitted
public T findById(long id) {
// method implementation
}
}
And subclasses would pass their class into the superclass:
子类将它们的类传递给超类:
public class UserDao extends GenericDaoImpl<User> {
public UserDao() {
super(User.class);
}
}
Then, using your clazz
instance you can get the entity in your generic method using the Session#get method:
然后,使用您的clazz实例,您可以使用Session#get方法获取泛型方法中的实体:
T entity = session.get(clazz, id);
See the following questions for more information:
有关更多信息,请参阅以下问题:
- How to get a class instance of generics type T
- 如何获取泛型类型T的类实例
- Get object by ID in Hibernate
- 在Hibernate中通过ID获取对象
As far as the side question, the EntityManager
is part of JPA (the Java Persistence API). Developing your application using the Java API specification instead of the Hibernate API allows your application to not become dependent on Hibernate. This allows you to switch between popular JPA implementations like Hibernate, OpenJPA, or TopLink without making and changes to your code.
就副问题而言,EntityManager是JPA(Java Persistence API)的一部分。使用Java API规范而不是Hibernate API开发应用程序允许您的应用程序不依赖于Hibernate。这允许您在流行的JPA实现(如Hibernate,OpenJPA或TopLink)之间切换,而无需对代码进行更改。
This question has more information on the difference.
这个问题有关于差异的更多信息。
#1
5
You need to have access to the Class<T>
from within that method. You have two options, you can pass the Class<T>
into the method:
您需要从该方法中访问Class
public T findById(long id, Class<T> clazz) {
// method implementation
}
Or you can pass the Class<T>
into the constructor of the class for use in the method:
或者,您可以将Class
@Repository
public class GenericDaoImpl<T> implements GenericDao<T> {
private Class<T> clazz;
protected GenericDaoImpl(Class<T> clazz) {
this.clazz = clazz;
}
// other methods omitted
public T findById(long id) {
// method implementation
}
}
And subclasses would pass their class into the superclass:
子类将它们的类传递给超类:
public class UserDao extends GenericDaoImpl<User> {
public UserDao() {
super(User.class);
}
}
Then, using your clazz
instance you can get the entity in your generic method using the Session#get method:
然后,使用您的clazz实例,您可以使用Session#get方法获取泛型方法中的实体:
T entity = session.get(clazz, id);
See the following questions for more information:
有关更多信息,请参阅以下问题:
- How to get a class instance of generics type T
- 如何获取泛型类型T的类实例
- Get object by ID in Hibernate
- 在Hibernate中通过ID获取对象
As far as the side question, the EntityManager
is part of JPA (the Java Persistence API). Developing your application using the Java API specification instead of the Hibernate API allows your application to not become dependent on Hibernate. This allows you to switch between popular JPA implementations like Hibernate, OpenJPA, or TopLink without making and changes to your code.
就副问题而言,EntityManager是JPA(Java Persistence API)的一部分。使用Java API规范而不是Hibernate API开发应用程序允许您的应用程序不依赖于Hibernate。这允许您在流行的JPA实现(如Hibernate,OpenJPA或TopLink)之间切换,而无需对代码进行更改。
This question has more information on the difference.
这个问题有关于差异的更多信息。