栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

使用Spring 3进行基于注释的事务管理和对象映射的最小Hibernate 4 XML配置?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Spring 3进行基于注释的事务管理和对象映射的最小Hibernate 4 XML配置?

我发现将Hibernate与Spring的XML配置结合使用非常直观,但是如果您以前从未将其添加到项目中,那么正确地工作可能会很痛苦。对于Hibernate4,我首选使用Spring的XML配置。

因此,您已经建立了一个Spring项目并使所有工作正常进行。您现在要添加休眠。

我一直喜欢在一个单独的XML文件中配置Hibernate,该文件的名称类似于

database-servlet.xml
WEB-
INF目录中的内容,但是名称实际上并不重要,只要它在类路径中即可。

我的新人

database-servlet.xml
看起来像这样:

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:jdbc="http://www.springframework.org/schema/jdbc"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd    http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd    http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd"></beans>

您会注意到我导入了

tx
jdbc
名称空间。这是因为我们将在此配置文件中大量使用它们。

您要做的第一件事是启用基于注释的事务管理(

@Transactional
)。人们在Spring中使用Hibernate的主要原因是因为Spring将为您管理所有事务。将以下行添加到您的配置文件:

<tx:annotation-driven />

我们需要创建一个数据源。数据源基本上是Hibernate用来持久化对象的数据库。通常,一个事务管理器将具有一个数据源。如果您希望Hibernate与多个数据源对话,那么您将有多个事务管理器。

数据源的类型将取决于您要完成的工作。您可以指定一个现有数据库,也可以创建一个预包装在Spring中的新的内存中HSQL / Derby /H2数据库。就个人而言,当我将项目部署进行物理测试时,Hibernate会连接到现有数据库,但是我使用内存数据库进行单元/集成测试。

我将首先展示如何创建内存数据库。

<jdbc:embedded-database id="dataSource" type="HSQL">    <jdbc:script location="classpath:/setup.sql" />    .    .    .    <!-- As many scripts can run as you like --></jdbc:embedded-database>

上面的配置将创建一个嵌入式(内存中的)HSQL数据库作为bean,运行脚本

setup.sql
,然后使
dataSource
bean对应用程序上下文可用。您不必指定数据库,
type
因为HSQL是默认数据库,但是我总是想清楚一点。setup.sql可以位于类路径内的任何位置(通常为WEB-
INF目录)。您可以根据需要指定任意数量的SQL脚本。您还可以设置是否在创建或销毁数据库时运行它们。

该数据库将与您的应用程序一起生存和消失。 请勿在生产项目上使用嵌入式数据库 ,一次停电,所有数据都将丢失。

要将数据源连接到现有数据库,配置略有不同。

<bean id="dataSource"     >    <property name="driverClassName" value="" />    <property name="url" value="" />    <property name="username" value="" />    <property name="password" value="" /></bean>

这个bean的类可以是任何实现的(我认为),

javax.sql.DataSource
因此您可以编写自己的。该示例类由Spring提供,但没有自己的线程池。一个流行的替代方法是Apache
Commons
org.apache.commons.dbcp.BasicDataSource
,但还有许多其他选择。我将在下面解释每个属性:

  • driverClassName :JDBC驱动程序的路径。这是 特定数据库的 JAR,应该在您的类路径中可用。确保您拥有最新版本。如果您使用的是Oracle数据库,则需要一个OracleDriver。如果您有MySQL数据库,则需要一个MySQLDriver。看看您是否可以在这里找到所需的驱动程序,但是快速的Google应该会为您提供正确的驱动程序。

  • url :数据库的URL。通常,这将是

    jdbc:oracle:thin:pathtoyourdatabase
    jdbc:mysql://path/to/your/database
    。如果您四处搜索所用数据库的默认位置,则应该能够找出应该使用的数据库的默认位置。如果您收到
    HibernateException
    该消息
    org.hibernate.HibernateException: Connection cannot be null when 'hibernate.dialect' not set
    并遵循本指南,则有90%的可能性是URL错误,5%的可能性是数据库没有启动以及5%的可能性是用户名/密码错误。

  • username :向数据库进行身份验证时使用的用户名。

  • password :与数据库进行身份验证时使用的密码。

接下来,是设置

SessionFactory
。Hibernate就是用来创建和管理事务,并实际上与数据库进行对话的。它具有许多配置选项,我将在下面尝试解释。

<bean id="sessionFactory"    >    <property name="dataSource" ref="dataSource" />    <property name="packagesToScan" value="au.com.project />    <property name="hibernateProperties">        <props> <prop key="hibernate.use_sql_comments">true</prop> <prop key="hibernate.hbm2ddl.auto">validate</prop>        </props>    </property></bean>
  • dataSource :您的数据源bean。如果您更改了数据源的ID,请在此处进行设置。

  • packagesToScan :扫描以查找您的JPA注释对象的软件包。这些是会话工厂需要管理的对象,通常是POJO并带有注释

    @Entity
    。有关如何在Hibernate中设置对象关系的更多信息,请参见此处。

  • annotatedClasses (未显示):您还可以提供一个类列表,供Hibernate扫描,如果它们不在同一包中,则进行扫描。您应该使用其中之一

    packagesToScan
    annotatedClasses
    但不能同时使用。声明看起来像这样:



    foo.bar.package.model.Person
    foo.bar.package.model.Thing

  • hibernateProperties :这里有无数的文献记载。您将使用的主要方法如下:

    • hibernate.hbm2ddl.auto :最热门的Hibernate问题之一详细介绍了此属性。看到它以获得更多信息。我通常使用validate,并使用SQL脚本(用于内存)或预先创建数据库(现有数据库)来设置数据库。
    • hibernate.show_sql :布尔型标志,如果为true,则Hibernate将打印其生成的所有SQL
      stdout
      。您还可以配置
      log4j.logger.org.hibernate.type=TRACE
      log4j.logger.org.hibernate.SQL=DEBUG
      日志记录器,以通过在日志管理器中进行设置来显示绑定到查询的值(我使用log4j)。
    • hibernate.format_sql :布尔值标志,将使Hibernate将您的SQL漂亮地打印到stdout。
    • hibernate.dialect (出于充分的原因未显示):许多旧的教程向您展示了如何设置将用于与数据库通信的Hibernate方言。Hibernate 可以 根据正在使用的JDBC驱动程序自动检测要使用的方言。由于大约有3种不同的Oracle方言和5种不同的MySQL方言,因此我将这个决定留给Hibernate。有关Hibernate支持的方言的完整列表,请参见此处。

您需要声明的最后两个bean是:

<bean     id="PersistenceExceptionTranslator" /><bean id="transactionManager"     >    <property name="sessionFactory" ref="sessionFactory" /></bean>

PersistenceExceptionTranslator
特定于数据库的内容转换为
HibernateException
SQLExceptions
可由应用程序上下文理解的Spring异常。

TransactionManager
bean是什么控制的交易以及滚背影。

注意:您应该将

SessionFactory
bean 自动装配到DAO中。

完成此操作后。您所要做的就是将新内容添加

database-servlet.xml
到web.xml文件中。

<context-param><param-name>contextConfigLocation</param-name>    <param-value>        /WEB-INF/database-servlet.xml        .        .        .    </param-value></context-param>

这应该是使Hibernate实际工作所需的全部。您仍然需要向对象添加注释,并向

@Transactional
服务层添加与DAO交互的方法。

方便提示:如果您使用的是Ivy或maven之类的依赖项管理器,并且拉入了所有Spring&Hibernate
javadocs,则可以通过将鼠标悬停在属性上来实际上在STS XML编辑器中查看它们。

所有这些在实践中如何运作

在服务类中,当使用注释方法,

@Transactional
然后从其他地方调用该方法时,会发生一些事情。
TransactionManager
在调用方法之前,Hibernate使用AOP切入点插入代码。在这里,
TransactionManager
它将执行以下操作(不按特定顺序):

  • 尝试确定哪些持久性对象(它知道)在内存中。

  • 检查中

    SessionFactory
    是否存在现有的交易会话,
    SessionFactory
    如果不存在,则使用来创建一个新的交易会话,具体取决于注释中的参数。

从这一点开始,事务管理器记录您对发现的任何持久对象所做的所有更改,以及在当前会话中运行的所有查询。这样做的目的是,如果引发异常,则回滚自调用该方法以来发生的所有事情都是很简单的事情。

SessionFactory
bean是负责建立,维护,关闭和冲洗所有的数据库会话的
TransactionManager
请求它来创建。这就是为什么我们将
SessionFactory
DAO自动连接到DAO并通过它运行所有查询的原因。

新的Hibernate用户提出的最大问题之一是“我的更改何时提交?”
当你考虑到它的

TransactionManager
工作原理时,答案才有意义
SesisonFactory
。当您退出使用注释的服务方法时,将刷新并提交数据库更改
@Transactional
。这样做的原因是,交易应该代表不间断工作的单个“单元”。如果设备出现问题,则认为设备发生故障,所有更改都应回滚。因此,
SessionFactory
当您退出最初调用的服务方法时,它将刷新并清除会话。

这并不是说在事务进行过程中也不会刷新并清除会话。例如,如果我调用一个服务方法以添加5个对象的集合并返回数据库中对象的总数,

SessionFactory
则将意识到query(
SELECTCOUNT(*)
)要求一个更新的状态是准确的,因此将刷新添加的运行count查询之前的5个对象。执行可能看起来像这样:

//Service@Override@Transactionalpublic long saveAndCount(List<Foo> listOfFoo){    for(Foo foo : listOfFoo){        //Doesn't get instantly saved to the database.        fooDAO.saveOrUpdate(foo);    }        return fooDAO.count();}

需要明确的是,DAO根本没有会话管理代码。它会有类似的东西,仅此

sessionFactory.getCurrentSession().buildCriteria(Foo.class);
而已。无需操作
Session
对象实例,也无需调用
flush()
clear()
。这就是在Spring中使用Hibernate的好处。

免责声明:我不知道这些示例是否适用于斯坦纳德·海贝娜特

我与Hibernate或Hibernate开发团队没有任何关系。我提供这些示例,以便在回答Hibernate标签上的问题时提供参考。这些示例和讨论是基于我自己的观点以及我如何使用Hibernate开发应用程序的。这些例子绝不是全面的。我将基于过去使用Hibernate的常见情况为基础。

如果您在尝试实现这些示例时遇到问题,请不要评论,并希望我解决您的问题。学习Hibernate的一部分是学习其API的内容。如果示例有误,请随时对其进行编辑。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/506181.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号