当前位置: 首页 > 知识库问答 >
问题:

关于如何在Spring应用程序中实现Hibernate DAO的一些疑问

益锦程
2023-03-14
package org.andrea.myexample.HibernateOnSpring.dao;

import java.util.List;

import org.andrea.myexample.HibernateOnSpring.entity.Person;

import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;
import org.springframework.transaction.annotation.Transactional;

public class PersonDAOImpl implements PersonDAO {

    // Factory per la creazione delle sessioni di Hibernate:
    private static SessionFactory sessionFactory;

    // Metodo Setter per l'iniezione della dipendenza della SessionFactory:
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    /** CREATE CRUD Operation:
     * Aggiunge un nuovo record rappresentato nella tabella rappresentato
     * da un oggetto Person
     */
    @Transactional(readOnly = false)
    public Integer addPerson(Person p) {

        System.out.println("Inside addPerson()");

        Session session = sessionFactory.openSession();

        Transaction tx = null;
        Integer personID = null;

        try {
            tx = session.beginTransaction();

            personID = (Integer) session.save(p);
            tx.commit();
        } catch (HibernateException e) {
            if (tx != null)
                tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

        return personID;

    }

    // READ CRUD Operation (legge un singolo record avente uno specifico id):
    public Person getById(int id) {

        System.out.println("Inside getById()");

        Session session = sessionFactory.openSession();

        Transaction tx = null;          
        Person retrievedPerson = null;  

        try {
            tx = session.beginTransaction();
            retrievedPerson = (Person) session.get(Person.class, id);
            tx.commit();
        }catch (HibernateException e) { 
            if (tx != null)                 
                tx.rollback();          
            e.printStackTrace();
        } finally {                 
            session.close();
        }

        return retrievedPerson;
    }

    // READ CRUD Operation (recupera la lista di tutti i record nella tabella):
    @SuppressWarnings("unchecked")
    public List<Person> getPersonsList() {

        System.out.println("Inside getPersonsList()");

        Session session = sessionFactory.openSession();
        Transaction tx = null;
        List<Person> personList = null;

        try {
            tx = session.beginTransaction();
            Criteria criteria = session.createCriteria(Person.class);
            personList = criteria.list();
            System.out.println("personList: " + personList);
            tx.commit();
        }catch (HibernateException e) { 
            if (tx != null)                 
                tx.rollback();          
            e.printStackTrace();
        } finally {
            session.close();
        }
        return personList;
    }

    // DELETE CRUD Operation (elimina un singolo record avente uno specifico id):
    public void delete(int id) {

        System.out.println("Inside delete()");

        Session session = sessionFactory.openSession();
        Transaction tx = null;

        try {
            tx = session.beginTransaction();
            Person personToDelete = getById(id);
            session.delete(personToDelete);
            tx.commit();
        }catch (HibernateException e) { 
            if (tx != null)                 
                tx.rollback();          
            e.printStackTrace();
        } finally {
            session.close();
        }

    }

    @Transactional
    public void update(Person personToUpdate) {

        System.out.println("Inside update()");

        Session session = sessionFactory.openSession();
        Transaction tx = null;

        try {
            System.out.println("Insite update() method try");
            tx = session.beginTransaction();
            session.update(personToUpdate);

            tx.commit();
        }catch (HibernateException e) { 
            if (tx != null)                 
                tx.rollback();          
            e.printStackTrace();
        } finally {
            session.close();
        }   

    }

}

1)第一个疑问与这样一个事实有关:在这个类中,对于每个CRUD方法,我都打开一个新的会话。

我之所以这样做是因为在本教程http://www.tutorialspoint.com/hibernate/hibernate_sessions.htm中我读到:

Session对象是轻量级的,设计成每次需要与数据库交互时都要实例化。持久性对象通过会话对象保存和检索。会话对象不应该保持长时间打开,因为它们通常不是线程安全的,并且应该根据需要创建和销毁它们。

所以...是我的建筑这么差吗?我有一个接口,它提供我的DAO和使用Hibernate实现DAO的具体类,我调用它的方法在DB上进行CRUD操作

共有1个答案

曾昂然
2023-03-14

关于#1。是的,当您在DAO的CRUD操作方法中使用@transactional注释时,您不需要显式地处理会话的打开和关闭。Spring为你做了这件事。在此过程中,您只需调用当前会话的CRUD方法,该方法通过调用SessionFactory.getCurrentSession()获得。不需要像您在上面的代码中所做的那样显式地打开、提交和回滚事务。当您使用@transactional注释该方法时,Spring将为您做到这一点。

关于2号。Spring有自己的方式来实现DAO。它可能在使用AOP。这并不意味着你的架构是错误的。使用接口和具体类实现的体系结构是正确的做法。我要做的是让所有CRUD操作由一个基类实现,然后让子类实现特定于DAO的方法。我的意思是(仅给出psuedo代码):

interface BaseDAO {//declare all the CRUD methods}

interface PersonaDAO extends BaseDAO {//declare all Person related methods like getPersonsList}

class BaseDAOImpl implements BaseDAO {//CRUD method implementations }

class PersonaDAOImpl extends BaseDAOImpl implements PersonDAO {//implementation of Person related methods}

我觉得这会是一个更好的arch,使您可以重用CRUD操作代码。希望这有帮助。

 类似资料:
  • 我正在研究如何在Spring框架中使用JDBC在数据库上执行查询。 我遵循这个教程:http://www.tutorialspoint.com/spring/spring_jdbc_example.htm 在本教程中,我定义了一个StudentDAO接口,它只定义我想要的CRUD方法。 然后定义了Student类,它是我希望在Student数据库表中持久化的实体。 然后,定义了作为RowMappe

  • 我正在学习如何在Spring应用程序中使用JDBC,但我对此有些怀疑。 因此,让我解释一下我对一个实际例子的怀疑: 如果我有一个实现我的DAO接口的类,并且这个类包含以下方法,在我的数据库的学生表中插入一个新行: 好的...我认为SQL字符串Rapper呈现了我的SQL查询,必须执行这些查询才能在我的表中插入新行 我不明白这段代码到底是什么意思:值(?,?) 我认为,当我在JdbcTemplate

  • 我正在编写基于int-IP:TCPendpoint的客户机-服务器应用程序。用Kotlin写的代码。应用程序包含两个tcp clienst,当它们首先建立了与服务器的连接并进行了一些初始化时,它们应该按照sertain顺序一个接一个地连接到服务器。 作为这种同步的解决方案,我想使用启动依赖tcp客户端的endpoint组。为此,在depended(第二个)客户机中,我将和属性添加到tcp-outb

  • 本文向大家介绍如何在Spring Boot应用程序中实现Spring安全性?相关面试题,主要包含被问及如何在Spring Boot应用程序中实现Spring安全性?时的应答技巧和注意事项,需要的朋友参考一下 实施需要最少的配置。您需要做的就是spring-boot-starter-security在pom.xml文件中添加starter。您还需要创建一个Spring配置类,它将覆盖所需的方法,同时

  • 问题内容: 我想在AngularJS应用程序中添加一些实用程序功能。例如: 将它们添加为服务的最佳方法是吗?从我所阅读的内容中我可以做到,但是然后我想在HTML页面中使用它们,因此如果它们在服务中仍然可行吗?例如,我可以使用以下内容: 有人可以举例说明如何添加这些内容。我应该创建服务还是有其他实现方法。最重要的是,我希望将这些实用程序功能存储在文件中,而不要与主要设置的另一部分结合使用。 我了解有

  • 我是Spring框架的新手,我对@Autow的注释和接口声明的使用有一些问题。 参考此示例: http://viralpatel.net/blogs/spring3-mvc-hibernate-maven-tutorial-eclipse-example/ 我知道@Autow的注释可用于自动链接属性上的bean。 在上一个示例中,我遇到了以下情况: 我有一个ContactDAO接口,它的实现类名为