Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/hibernate/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 减少hibernate会话中的代码重复_Java_Hibernate_Design Patterns - Fatal编程技术网

Java 减少hibernate会话中的代码重复

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

我正在开发一个RESTWeb服务,使用Jersey和Hibernate以及Postgres作为后端。我有3个模型包、资源包和服务包。对于服务中的每个方法,我将复制代码:

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
提供singleton
SessionFactory
对象。通过这种方式,我可以添加任意数量的不同实体,并将它们的实例保存到数据库中,而不会有太多的代码重复。如果有人有更好的建议/意见,请告诉我。谢谢大家的想法

使用泛型,您可以执行以下操作:

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);
}