Java 关于如何在Spring应用程序中实现Hibernate DAO的一些疑问
我在Spring世界是个新手,我正在尝试开发一个集成Spring和Hibernate的DAO。我已经创建了一个工作项目,但我对它有一些架构上的疑问 我已经基于以下独立的Hibernate教程创建了我的Spring+Hibernate项目standalone,因为它不使用Spring或其他框架,它是一个简单的Java+Hibernate项目: 在我的项目中,我有一个接口,我在其中定义了我需要的所有CRUD方法和该接口的具体实现,这是我的具体类的代码: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
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以获取会话。安息吧,春天为你做的一切。不工作…我在这里打开了一个关于它的详细帖子,如果你愿意,你能帮我吗?