Java 减少hibernate会话中的代码重复
我正在开发一个RESTWeb服务,使用Jersey和Hibernate以及Postgres作为后端。我有3个模型包、资源包和服务包。对于服务中的每个方法,我将复制代码:Java 减少hibernate会话中的代码重复,java,hibernate,design-patterns,Java,Hibernate,Design Patterns,我正在开发一个RESTWeb服务,使用Jersey和Hibernate以及Postgres作为后端。我有3个模型包、资源包和服务包。对于服务中的每个方法,我将复制代码: SessionFactory sessionFactory = HibernateUtil.getSessionFactory(); Session session = sessionFactory.openSession(); Transaction transaction = null; try { transact
SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = null;
try {
transaction = session.beginTransaction();
***SOME UNIQUE OBJECT*** = (***SOME UNIQUE OBJECT TYPE***) session.save(***SOME UNIQUE OBJECT***);
session.getTransaction().commit();
} catch (HibernateException e) {
if (transaction != null) {
transaction.rollback();
}
} finally {
session.close();
}
return ***SOME UNIQUE OBJECT***;
有人能告诉我如何在不重复代码的情况下做到这一点吗。我正在考虑为实体模型类编写一个接口。然后将该接口传递给上述代码。不确定这是否是执行此操作的最佳方法。您可以使用该模块并创建一个存储库界面
默认情况下,它将包含所有标准CRUD方法,如save
。通常,您不必定义实现——Spring将为接口提供一个实现。对于非常复杂的存储库代码,您可以混合使用自己的java实现方法
它还允许您在界面中定义许多查询,而无需编写一行代码
Crudepository提供的功能:
public interface CrudRepository<T, ID extends Serializable>
extends Repository<T, ID> {
(1)
<S extends T> S save(S entity);
(2)
T findOne(ID primaryKey);
(3)
Iterable<T> findAll();
Long count();
(4)
void delete(T entity);
(5)
boolean exists(ID primaryKey);
(6)
// … more functionality omitted.
}
公共接口CrudRepository
扩展存储库{
(1)
S save(S实体);
(2)
T findOne(ID primaryKey);
(3)
Iterable findAll();
长计数();
(4)
无效删除(T实体);
(5)
存在布尔值(ID primaryKey);
(6)
//…省略了更多功能。
}
在任何设计模式中,界面的使用都得到了大力鼓励和推广。它将允许您在将来添加不同的实现/特性,以减少依赖性,这只是抽象
一个例子:
public interface StudentDao {
public void save(Student student);
}
我们有一个实现类
@Repository
public interface StudentDaoImpl implements StudentDao {
@Autowired
SessionFactory sessionFactory;
public void save(Student student){
Session currentSession = sessionFactory.getCurrentSession();
currentSession.save(student);
currentSession.close();
}
}
和服务类,例如:
@Service
public class StudentService {
@Autowired
StudentDao studentDao;
@Transactional
public void save(Student student){
studentDao.save(student);
}
}
完整的解释将取决于您的项目和需求。然而,我为您解释了一个基于注释的简单示例。通过结合和各种关于泛型类型的建议,我成功地实现了我想要的,如下所示
创建实体类EntityA
,EntityB
和EntityC
。创建了一个名为Object
的接口,如下所示:
public interface Object<T> {
public T addObject(Class<T> entityClass, T newObject);
}
HibernateUtil
提供singletonSessionFactory
对象。通过这种方式,我可以添加任意数量的不同实体,并将它们的实例保存到数据库中,而不会有太多的代码重复。如果有人有更好的建议/意见,请告诉我。谢谢大家的想法 使用泛型,您可以执行以下操作:
public static <T>T addObject(Object object, Class<T> type) {
Session session = HibernateUtil.getSessionFactory().openSession();
org.hibernate.Transaction tx = null;
try{
tx = session.beginTransaction();
session.save(object);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}
session.close();
return type.cast(object);
}
publicstatict addObject(对象对象,类类型){
Session Session=HibernateUtil.getSessionFactory().openSession();
org.hibernate.Transaction tx=null;
试一试{
tx=session.beginTransaction();
session.save(对象);
tx.commit();
}捕获(休眠异常e){
如果(tx!=null)tx.rollback();
e、 printStackTrace();
}
session.close();
返回类型.cast(对象);
}
使用DAO设计模式。所有持久化方法和数据库交互都应该只通过数据访问类进行。您的服务类应该调用数据访问类上的方法。只有数据访问对象应该调用持久性方法,比如session.save()在DAO类中创建一个方法,并且可以从不同的服务类多次引用它。还要使您的所有服务类方法(通过DAO类持久化的方法)具有事务性。在方法签名之上使用@transactional。@RahulRaj您可以展示一个示例或包含指向某些资源的链接吗?我找到了这个。可以泛型类型解决您的问题吗。只需将此块提取为一个save
方法。对DAO类使用@Repository
注释,对所有持久化的服务类方法使用@Transactional
。@RahulRaj如果您能给出一个示例,这将非常有用。这对设计模式的实习生很有帮助。但这并不能解决我最初的问题。现在想象一下,我有另一个实体老师
。然后我需要用TeacherDaoImpl
重复这一点,TeacherDaoImpl
中我将在StudentDaoImpl
和TeacherDaoImpl
中复制大量代码。记住,当您遵循设计模式时,您可能会通过创建更多的类/方法以这种方式编写更多的代码(而不是重复的代码),但考虑到应用程序可能会因未来需求而发生变化,这是设计应用程序的最首选方法。它很容易维护和更改,并且任何开发人员都很容易理解流程。这里并没有添加任何重复的代码,只是在dao上添加了一个方法,并通过调用它们在服务类的多个实例上使用它。你能详细说明一下这里重复的是什么吗?首先,我不喜欢在这里使用Spring注释。无论如何,StudentDaoImpl接受类型Student
。因此,对于另一个实体Teacher
,我需要编写一个新的TeacherDaoImpl
,它需要打开一个新会话。如果没有Spring注释,这将复制类似于sessionFactory.openSession()和session.beginTransaction()的内容
和我问题中的尝试和捕获。那么您是使用普通JPA来持久化还是休眠?上面的示例使用hibernate注释,只是为了让您知道hibernate有多么强大和简单:)您保存了多个
public class EntityAService {
public EntityAService() {
}
public EntityA addRedemption(EntityA entityA) {
Object<EntityA> newEntityA = new ObjectImpl<EntityA>();
return newEntityA.addObject(EntityA.class, newEntityA);
}
}
public static <T>T addObject(Object object, Class<T> type) {
Session session = HibernateUtil.getSessionFactory().openSession();
org.hibernate.Transaction tx = null;
try{
tx = session.beginTransaction();
session.save(object);
tx.commit();
}catch (HibernateException e) {
if (tx!=null) tx.rollback();
e.printStackTrace();
}
session.close();
return type.cast(object);
}