Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.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 关于如何在Spring应用程序中实现Hibernate DAO的一些疑问_Java_Spring_Hibernate_Spring Mvc - Fatal编程技术网

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

Java 关于如何在Spring应用程序中实现Hibernate DAO的一些疑问,java,spring,hibernate,spring-mvc,Java,Spring,Hibernate,Spring Mvc,我在Spring世界是个新手,我正在尝试开发一个集成Spring和Hibernate的DAO。我已经创建了一个工作项目,但我对它有一些架构上的疑问 我已经基于以下独立的Hibernate教程创建了我的Spring+Hibernate项目standalone,因为它不使用Spring或其他框架,它是一个简单的Java+Hibernate项目: 在我的项目中,我有一个接口,我在其中定义了我需要的所有CRUD方法和该接口的具体实现,这是我的具体类的代码: package org.andrea.myex

我在Spring世界是个新手,我正在尝试开发一个集成Spring和Hibernate的DAO。我已经创建了一个工作项目,但我对它有一些架构上的疑问

我已经基于以下独立的Hibernate教程创建了我的Spring+Hibernate项目standalone,因为它不使用Spring或其他框架,它是一个简单的Java+Hibernate项目:

在我的项目中,我有一个接口,我在其中定义了我需要的所有CRUD方法和该接口的具体实现,这是我的具体类的代码:

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方法打开了一个新的会话

我这样做是因为在本教程中:我读到:

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

但是后来有人告诉我,集成Spring和Hibernate,我不需要在每个CRUD方法中打开新会话,因为如果我将@Transactional注释添加到所有CRUD方法中,那么Spring已经将会话与当前事务关联,并且在事务结束时Spring也将关闭该会话。它是Spring,它将在每次打开/关闭事务时打开和关闭会话

因此,如果这是真的,我必须只打开一次会话,然后获取当前会话

这是真的还是我的具体类它是对的它工作得很好,但我不知道它是否以一种愚蠢的方式工作

2第二个疑问与阅读Spring文档有关:我发现它使用的AOP服务可以调用DAO


那么…是不是我的架构太差了?我有一个接口,它展示了我的DAO和使用Hibernate实现DAO的具体类,我调用它的方法在DB上执行CRUD操作。是的,在DAO的CRUD操作方法中使用@Transactional注释时,不需要显式处理会话的打开和关闭。春天为你做这件事。您只需在其中调用当前会话上的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操作代码。希望这有帮助。

关于1。是的,在DAO的CRUD操作方法中使用@Transactional注释时,不需要显式处理会话的打开和关闭。春天为你做这件事。您只需在其中调用当前会话上的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标签上有667分,已经被提升了5次,并且指向了相关的spring文档,那么您为什么还要问另一个类似的问题?为什么你会相信这个问题的答案?顺便说一句:你应该看看Spring Data JPA@JBNizet,我只知道有不同的方法来做同样的事情,与个人无关,我检查了你的答案:-如果你不相信你之前的问题的答案,这是由我有很高声誉的人给出的,弹簧标签上有667分,该标签已被上调
5次,哪一次指向了相关的Spring文档,为什么还要问另一个类似的问题?为什么你会相信这个问题的答案?顺便说一句:你应该看看Spring数据JPA@JBNizet,我只知道有不同的方法来做同样的事情,或者没有,不是针对个人的,我已经检查了你的答案:-Tnx太多了…是的,我有相同的体系结构:PersonDAO接口,我在其中声明了CRUD方法和PersonDAOImpl具体类,它们实现了这个接口及其方法:-现在我将尝试使用getCurrentSession方法。最后一个问题。在我的具体课程中,我必须在哪里开始我的课程?Tnx Andreay您不需要打开任何会话。您需要将SessionFactory注入DAO并执行SessionFactory.getCurrentSession以获取会话。安息吧,春天为你做的一切。不工作…我在这里打开了一个关于它的详细帖子,如果你愿意,你能帮我吗?Tnx太多了…是的,我有相同的架构:PersonDAO接口,在其中我声明了CRUD方法和PersonDAOImpl具体类,它们实现了这个接口及其方法:-现在我将尝试使用getCurrentSession方法。最后一个问题。在我的具体课程中,我必须在哪里开始我的课程?Tnx Andreay您不需要打开任何会话。您需要将SessionFactory注入DAO并执行SessionFactory.getCurrentSession以获取会话。安息吧,春天为你做的一切。不工作…我在这里打开了一个关于它的详细帖子,如果你愿意,你能帮我吗?