当前位置:网站首页 > R语言数据分析 > 正文

spring教程下载(spring教程 csdn)



原文:Pro Spring 5

协议:CC BY-NC-SA 4.0

到目前为止,您已经看到了构建一个完全由 Spring 管理的应用是多么容易。您对 bean 配置和面向方面编程(AOP)有很深的理解。然而,这个难题缺少了一部分:如何获得驱动应用的数据?

除了简单的一次性命令行实用程序,几乎每个应用都需要将数据保存到某种数据存储中。最常见和最方便的数据存储是关系数据库。

以下是 2017 年七大关系型企业数据库:

  • 甲骨文数据库
  • 搜寻配置不当的
  • IBM DB2
  • SAP Sybase ASE
  • 一种数据库系统
  • MariaDB 企业
  • 关系型数据库

如果你不在一家能负担前四种许可证的大公司工作,你可能会使用前面列表中的后三种之一。使用最多的开源关系数据库可能是 MySQL ( )和 PostgreSQL ( )。MySQL 通常更广泛地用于 web 应用开发,尤其是在 Linux 平台上。 1 另一方面,PostgreSQL 对 Oracle 开发者更友好,因为它的过程语言 PLpgSQL 非常接近 Oracle 的 PL/SQL 语言。

即使您选择了最快和最可靠的数据库,您也不能因为使用设计和实现不佳的数据访问层而失去它的速度和灵活性。应用倾向于非常频繁地使用数据访问层;因此,数据访问代码中任何不必要的瓶颈都会影响整个应用,不管它设计得有多好。

在本章中,我们将向您展示如何使用 Spring 来简化使用 JDBC 的数据访问代码的实现。我们首先看一下在没有 Spring 的情况下通常需要编写的大量重复代码,然后将其与使用 Spring 的数据访问类实现的类进行比较。结果确实令人惊讶,因为 Spring 允许您使用人工调整的 SQL 查询的全部功能,同时最小化您需要实现的支持代码的数量。具体来说,我们讨论以下内容:

  • 比较传统的 JDBC 代码和 Spring JDBC 支持:我们探索 Spring 如何简化旧式的 JDBC 代码,同时保持相同的功能。您还将看到 Spring 如何访问低级 JDBC API,以及这个低级 API 如何映射到方便的类,如。
  • 连接到数据库:尽管我们没有深入到数据库连接管理的每一个细节,但我们确实向您展示了简单的和之间的根本区别。自然,我们会讨论 Spring 如何管理数据源,以及您可以在应用中使用哪些数据源。
  • 检索数据并将数据映射到 Java 对象:我们向您展示如何检索数据,然后如何有效地将所选数据映射到 Java 对象。您还了解了 Spring JDBC 是对象关系映射(ORM)工具的一个可行的替代品。
  • 插入、更新和删除数据:最后,我们讨论如何通过使用 Spring 执行这些类型的查询来实现插入、更新和删除操作。

Java 版本 8 的发布带来了 lambda 表达式支持,以及许多其他特性。Lambda 表达式是匿名内部类用法的绝佳替代品,也是使用 Spring 的 JDBC 支持的理想选择。lambda 表达式的使用需要使用 Java 8。这本书是在 Java 8 的预发行版本和第一个通用版本期间写的,所以我们知道不是每个人都会使用 Java 8。鉴于此,本章代码示例和源代码下载展示了这两种风格。Lambda 表达式适用于 Spring API 中使用模板或回调的大多数地方,而不仅仅局限于 JDBC。本章不涉及 lambda 表达式本身,因为它们是 Java 语言的一个特性,你应该熟悉 lambda 的概念和语法。更多信息请参考 的 Lambda 表达式教程。

在继续讨论之前,我们先介绍一个简单的数据模型,该模型在本章以及后面几章讨论其他数据访问技术时用于示例(我们将相应地扩展该模型,以满足每个主题的需要)。

这个模型是一个简单的音乐数据库,有两个表。第一个是表,存储一个歌手的信息,另一个表是,存储那个歌手发行的专辑。每个歌手可以有零张或多张专辑;换句话说,和之间是一对多的关系。歌手的信息包括他们的名和姓以及出生日期。图 6-1 显示了数据库的实体关系(ER)图。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 6-1。

Simple data model for the example code

正如您所看到的,两个表都有一个 ID 列,在插入过程中,数据库会自动分配这个 ID 列。对于表,有一个到表的外键关系,它通过列与表的主键(即 ID 列)相链接。

在本章中,我们使用开源数据库 MySQL 在一些例子中展示与真实数据库的交互。这将要求您有一个 MySQL 实例可供使用。我们不讨论如何安装 MySQL。您可以使用自己选择的另一个数据库,但是可能需要修改模式和函数定义。我们还将介绍嵌入式数据库的使用,它不需要 MySQL 数据库。

万一你想使用 MySQL,在官方网站上你可以找到非常好的安装和配置 MySQL 的教程。下载完 MySQL 2 并安装后,就可以使用账号访问了。通常,当您开发一个应用时,您需要一个新的模式和用户。对于本章中的代码示例,模式名为,访问它的用户名为。接下来描述了创建它们所执行的 SQL 代码,您可以在项目的目录下的文件中找到它们。包括对 MySQL 社区服务器版本 5.17.18 中的一个错误的修复,这是本书撰写时的当前版本。

 
  

下面的代码片段描述了创建前面提到的两个表所需的 SQL 代码。这个代码在的项目的目录下。

 
  

如果您使用像 IntelliJ IDEA 这样的智能编辑器,您可以使用数据库视图来检查您的模式和表。在图 6-2 中,你可以看到 IntelliJ IDEA 中描述的模式的内容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 6-2。

Contents of the MUSICDB schema

因为我们需要数据来测试 JDBC 的使用,所以还提供了一个名为的文件,其中包含一组用于填充这两个表的语句。

 
  

在本章的后面几节中,您将看到通过 JDBC 从数据库中检索数据并将结果集直接映射到 Java 对象(即 POJOs)的例子。这些映射到表中记录的类也称为。对于表,将创建一个类,该类将被实例化以创建映射到歌手记录的 Java 对象。

 
  

以类似的方式,还创建了一个类。

 
  

让我们从一个简单的接口开始,它封装了歌手信息的所有数据访问服务。代码如下:

 
  

在前面的接口中,我们分别定义了两个 finder 方法以及 insert、update 和 delete 方法。它们对应于 CRUD 术语(创建、读取、更新、删除)。

最后,为了便于测试,让我们修改一下配置文件,将所有类的日志级别改为。在级别,Spring JDBC 模块将把所有底层 SQL 语句输出到数据库,这样你就知道到底发生了什么;这对于排除 SQL 语句语法错误特别有用。下面的配置示例描述了打开了级别的文件(位于下,带有章节 6 项目的源代码文件)的内容。

 
  

JDBC 为 Java 应用访问存储在数据库中的数据提供了一种标准方法。JDBC 基础设施的核心是特定于每个数据库的驱动程序;正是这个驱动程序允许 Java 代码访问数据库。

一旦驱动程序被加载,它就向一个类注册自己。该类管理驱动程序列表,并提供建立数据库连接的静态方法。的方法返回一个驱动实现的接口。这个接口允许您对数据库运行 SQL 语句。

JDBC 框架相当复杂,而且久经考验;然而,随着这种复杂性而来的是开发上的困难。第一层复杂性在于确保您的代码管理到数据库的连接。连接是一种稀缺资源,建立起来非常昂贵。通常,数据库会为每个连接创建一个线程或一个子进程。此外,并发连接数通常是有限的,过多的打开连接数会降低数据库的速度。

我们将向您展示 Spring 如何帮助管理这种复杂性,但是在我们继续之前,我们需要向您展示如何在纯 JDBC 中选择、删除和更新数据。

本章涵盖的所有项目都需要特殊的数据库库作为依赖项:、、等等。只需查看每个项目的配置文件和中使用的版本和库。

让我们创建一个简单形式的接口实现,用于通过纯 JDBC 与数据库交互。记住我们已经知道的关于数据库连接的知识,我们将采取谨慎且昂贵的(就性能而言)方法为每个语句创建一个连接。这大大降低了 Java 的性能,并给数据库增加了额外的压力,因为必须为每个查询建立一个连接。但是,如果我们保持连接打开,我们可以使数据库服务器停止运行。下面的代码片段以 MySQL 为例,展示了管理 JDBC 连接所需的代码:

 
  

这段代码还远未完成,但它让您了解了管理 JDBC 连接所需的步骤。这段代码甚至没有处理连接池,连接池是一种更有效地管理数据库连接的常用技术。我们现在不讨论连接池(连接池将在本章后面的“数据库连接和数据源”一节中讨论);相反,下面的代码片段显示了使用普通 JDBC 实现接口的、和方法:

 
  

要测试类,可以使用下面的类:

 
  

正如您所注意到的,我们现在将使用一个记录器来打印控制台中的消息。运行前面的程序会产生以下结果(假设您有一个本地安装的名为的 MySQL 数据库,它的用户名和密码设置为,并且样本数据已经加载):

 
  

如输出所示,第一行显示了初始数据。第二行显示添加了新记录。最后一行显示新创建的歌手(艾德·希兰)被删除。

正如您在前面的代码示例中所看到的,许多代码需要移动到一个助手类中,或者更糟的是,在每个 DAO 类中复制。从应用员的角度来看,这是 JDBC 的主要缺点;您没有时间在每个 DAO 类中编写重复的代码。相反,您希望专注于编写代码,实际完成您需要 DAO 类做的事情:选择、更新和删除数据。您需要编写的助手代码越多,需要处理的检查异常就越多,您可能会在代码中引入更多的错误。

这就是 DAO 框架和 Spring 的用武之地。框架消除了实际上不执行任何定制逻辑的代码,并允许您忘记所有需要执行的内务处理。此外,Spring 广泛的 JDBC 支持会让您的生活轻松许多。

我们在本章第一部分讨论的代码不是很复杂,但是很繁琐,因为要写的内容太多,所以编码错误的可能性很高。是时候看看 Spring 是如何让事情变得更简单、更优雅了。

概述和使用的包

JDBC Spring 支架分为五个包,详见表 6-1;每一个都处理 JDBC 访问的不同方面。

表 6-1。

Spring JDBC Packages

| 包裹 | 描述 | | --- | --- | | `org.springframework.jdbc.core` | 这包含了 Spring JDBC 课程的基础。它包括核心 JDBC 类`JdbcTemplate`,该类简化了用 JDBC 编程数据库操作。几个子包提供了对具有更特定目的的 JDBC 数据访问的支持(例如,一个支持命名参数的`JdbcTemplate`类)以及相关的支持类。 | | `org.springframework.jdbc.datasource` | 它包含助手类和`DataSource`实现,您可以使用它们在 JEE 容器之外运行 JDBC 代码。几个子包提供了对嵌入式数据库、数据库初始化和各种数据源查找机制的支持。 | | `org.springframework.jdbc.object` | 这包含帮助将从数据库返回的数据转换成对象或对象列表的类。这些对象和列表是普通的 Java 对象,因此与数据库断开连接。 | | `org.springframework.jdbc.support` | 这个包中最重要的类是`SQLException`翻译支持。这允许 Spring 识别数据库使用的错误代码,并将它们映射到更高级别的异常。 | | `org.springframework.` `jdbc.config` | 这包含了在 Spring 的`ApplicationContext`中支持 JDBC 配置的类。例如,它包含一个用于`jdbc`名称空间的处理程序类(例如,``标签)。 |

让我们从最底层的功能开始讨论 Spring JDBC 支持。在运行 SQL 查询之前,需要做的第一件事是建立到数据库的连接。

通过提供一个实现的 bean,您可以使用 Spring 来管理数据库连接。一个和一个的区别在于一个提供和管理

(在包下)是一个最简单的实现。通过查看类名,您可以猜测它只是简单地调用来获得连接。事实上不支持数据库连接池,这使得这个类除了测试之外不适合做任何事情。的配置相当简单,如以下代码片段所示;您只需要提供驱动程序类名、连接 URL、用户名和密码()。

 
  

您很可能认识清单中的属性。它们表示您通常传递给 JDBC 以获得一个接口的值。数据库连接信息通常存储在属性文件中,以便在不同的部署环境中进行维护和替换。下面的代码片段显示了一个示例,Spring 的属性占位符将从该示例中加载连接信息:

 
  

通过在 mix 中添加名称空间,同样的配置也可以写成这样():

 
  

这里需要做一个改变。这些属性被加载到一个名为的 bean 中,因此您需要在属性文件中更改属性名的名称,以便能够使用前缀来访问它们。下面是文件内容:

 
  

因为这本书更关注 Java 类,所以这里也有一个配置类:

 
  

要测试这些类中的任何一个,可以使用下面的测试类:

 
  

同样,我们使用了一个测试类,因为重用一些代码更实际,还可以教您使用 JUnit 为您编写的任何代码快速编写测试。第一个方法用于测试 XML 配置,第二个方法用于测试配置类。从任何配置获得 bean 后,模拟查询用于测试到 MySQL 数据库的连接。

在现实世界的应用中,您可以使用 Apache Commons3或由 JEE 应用服务器(例如 JBoss、WebSphere、WebLogic 或 GlassFish)实现的,这可能会进一步提高应用的性能。你可以在普通的 JDBC 代码中使用一个,并获得同样的统筹福利;然而,在大多数情况下,您仍然会错过一个配置的中心位置。另一方面,Spring 允许您声明一个 bean,并在定义文件中设置连接属性。请参见以下配置示例;文件名为:

 
  

这个特殊的 Spring 管理的在中实现。最重要的一点是, bean 实现了,您可以立即在您的数据访问类中使用它。

配置 bean 的另一种方法是使用 JNDI。如果您正在开发的应用将在 JEE 容器中运行,我们可以利用容器管理的连接池。要使用基于 JNDI 的数据源,您需要更改 bean 声明,如下例所示():

 
  

在前面的例子中,我们使用 Spring 的通过 JNDI 查找获得数据源。从 2.5 版本开始,Spring 提供了名称空间,这进一步简化了配置。在这里,您可以看到使用名称空间()的相同 JNDI 数据源配置:

 
  

在前面的配置片段中,我们在标签中声明了名称空间,然后在标签中声明了数据源。如果采用 JNDI 方法,一定不要忘记在应用描述符文件中添加一个资源引用()。请参见以下代码片段:

 
  

是占位符值;您需要根据您的模块如何打包来更改它。例如,如果应用是一个 web 模块,它在 web 部署描述符()中就变成了。最有可能的是,您还需要在特定于应用服务器的描述符文件中配置。但是,请注意,元素配置了引用名,并且 bean 的被设置为。

正如您所看到的,Spring 允许您以几乎任何您喜欢的方式配置,并且它对应用的其余代码隐藏了数据源的实际实现或位置。换句话说,您的道类不知道也不需要知道指向哪里。

连接管理也被委托给 bean,它自己执行管理或者使用 JEE 容器来完成所有的工作。

从 3.0 版本开始,Spring 还提供了嵌入式数据库支持,它自动启动一个嵌入式数据库,并将其作为应用的公开。下面的配置片段显示了嵌入式数据库()的配置:

 
  

在前面的清单中,我们首先在标记中声明了名称空间。之后,我们使用来声明嵌入式数据库,并给它分配一个 ID。在标记中,我们还指示 Spring 执行指定的脚本来创建数据库模式,并相应地填充测试数据。请注意,脚本的顺序很重要,包含数据定义语言(DDL)的文件应该总是首先出现,然后是包含数据操作语言(DML)的文件。对于属性,我们指定要使用的嵌入式数据库的类型。从 4.0 版本开始,Spring 支持 HSQL(默认)、H2 和 DERBY。

嵌入式数据库也可以使用 Java 类来配置。要使用的类是,它使用数据库创建和加载数据脚本作为参数来创建实现的实例。

 
  

嵌入式数据库支持对于本地开发或单元测试非常有用。在本章的其余部分,我们使用嵌入式数据库来运行示例代码,因此您的机器不需要安装数据库来运行示例。

您不仅可以通过 JDBC 命名空间利用嵌入式数据库支持,还可以初始化在其他地方运行的数据库实例,如 MySQL、Oracle 等。不要指定和,只需使用,您的脚本将针对预期的执行,就像它们针对嵌入式数据库一样。

数据访问对象(DAO)模式用于将低级数据访问 API 或操作与高级业务服务分开。数据访问对象模式需要下列组件:

  • DAO 接口:它定义了要在一个模型对象(或多个对象)上执行的标准操作。
  • DAO 实现:这个类提供了 DAO 接口的具体实现。通常,这使用 JDBC 连接或数据源来处理模型对象。
  • 模型对象也称为数据对象或实体:这是一个简单的到表记录的 POJO 映射。

让我们为示例创建一个要实现的接口,如下所示:

 
  

对于简单的实现,首先我们将向实现类添加一个属性。我们想要将属性添加到实现类而不是接口的原因应该是很明显的:接口不需要知道数据将如何被检索和更新。通过向接口添加 mutator 方法,在最好的情况下,这迫使实现声明 getter 和 setter 存根。显然,这不是一个很好的设计实践。看看这里显示的简单的类:

 
  

我们现在可以指示 Spring 通过使用实现来配置我们的 bean,并设置属性,如下面的配置类所示:

 
  

Spring 支持相当多的嵌入式数据库,但是它们必须作为依赖项添加到项目中。这里您可以看到一些特定于数据库的库被配置用于:

 
  

Spring 现在通过实例化类来创建 bean,并将属性设置为 bean。确保已经设置了 bean 上所有必需的属性是一种很好的做法。最简单的方法是实现接口,并为()方法提供一个实现。这样,我们确保所有必需的属性都已经在我们的上设置好了。关于 bean 初始化的进一步讨论,请参考第四章。

到目前为止,我们看到的代码使用 Spring 来管理数据源,并引入了接口及其 JDBC 实现。我们还在 Spring 文件中的类上设置了属性。现在,我们通过向接口和实现添加实际的 DAO 操作来扩展代码。

因为 Spring 提倡使用运行时异常而不是检查异常,所以您需要一种机制来将检查的转换成运行时 Spring JDBC 异常。因为 Spring 的 SQL 异常是运行时异常,所以它们可以比检查异常更细粒度。根据定义,这不是运行时异常的特性,但是不得不在子句中声明一长串检查过的异常是不方便的;因此,被检查的异常往往比它们的运行时等价物更粗粒度。

Spring 提供了接口的默认实现,它负责将通用 SQL 错误代码转换成 Spring JDBC 异常。在大多数情况下,这个实现已经足够了,但是您可以扩展 Spring 的默认实现,并将您的新的实现设置为在中使用,如下面的代码示例所示:

 
  

同时,我们需要将对的依赖添加到项目中。在这里你可以看到被配置用于:

 
  

这个库作为一个依赖项被添加到所有用作本章示例的 JDBC 项目中。

 
  

要使用自定义翻译器,我们需要将它传递到 DAO 类中的中。下面的代码片段代表了一段增强的方法来说明它的用法:

 
  

有了定制的 SQL 异常翻译器,Spring 将在对数据库执行 SQL 语句时检测到 SQL 异常时调用它,当错误代码为时,将进行定制的异常翻译。对于其他错误,Spring 将退回到其默认的异常翻译机制。显然,没有什么可以阻止您将创建为 Spring 管理的 bean,并在您的 DAO 类中使用 bean。不记得看过类的也不用担心;我们将更详细地讨论它。

这个类代表了 Spring 的 JDBC 支持的核心。它可以执行所有类型的 SQL 语句。在最简单的视图中,您可以对数据定义和数据操作语句进行分类。数据定义语句包括创建各种数据库对象(表、视图、存储过程等等)。数据操作语句操作数据,可分为 select 和 update 语句。select 语句通常返回一组行;每一行都有相同的一组列。update 语句修改数据库中的数据,但不返回任何结果。

类允许您向数据库发出任何类型的 SQL 语句,并返回任何类型的结果。

在这一节中,我们将通过类来浏览 Spring 中 JDBC 编程的几个常见用例。

在 DAO 类中初始化 JdbcTemplate

在讨论如何使用之前,我们先来看看如何准备在 DAO 类中使用。很直白;大多数时候,您只需要通过传入数据源对象(应该由 Spring 注入到 DAO 类中)来构造类。下面的代码片段显示了将初始化对象的代码片段:

 
  

通常的做法是在方法中初始化,这样一旦数据源被 Spring 注入,也将被初始化并准备好使用。

一旦配置好,就是线程安全的。这意味着您也可以选择在 Spring 的配置中初始化单个的实例,并将其注入到所有的 DAO beans 中。类似这样的配置如下所示:

 
  

使用 JdbcTemplate 检索单值

让我们从一个返回单个值的简单查询开始。例如,我们希望能够通过 ID 检索歌手的名字。使用 jdbcTemplate,我们可以轻松地检索值。以下代码片段显示了 JdbcSingerDao 类中 findNameById()方法的实现。对于其他方法,创建了空的实现。

 
  

在前面的清单中,我们使用的方法来检索名字的值。第一个参数是 SQL 字符串,第二个参数由以对象数组格式传递给 SQL 进行参数绑定的参数组成。最后一个参数是要返回的类型,在本例中是。除了,还可以查询其他类型,如、。让我们来看看结果。下面的代码片段显示了测试程序。同样,将使用 JUnit 测试类,因为这允许我们单独运行测试方法,并且由于测试是在执行时运行的,我们也确保了我们的构建保持稳定。

 
  

当执行测试方法时,我们期望通过调用返回字符串,并且我们使用方法测试这个假设。如果在初始化数据库时出现任何问题,该测试将会失败。

对 NamedParameterJdbcTemplate 使用命名参数

在前面的例子中,我们使用普通的占位符(字符)作为查询参数,我们需要将参数值作为一个数组传递。使用普通占位符时,顺序很重要,将参数放入数组的顺序应该与参数在查询中的顺序相同。

一些开发人员更喜欢使用命名参数来确保每个参数都完全按照预期进行绑定。在 Spring 中,类的一个扩展叫做(在包下),提供了这种支持。

的初始化与相同,所以我们只需要声明一个类型的 bean,并将其注入到类中。在下面的代码中,你可以看到新的和改进的:

 
  

您将看到使用了命名参数(以分号为前缀)而不是占位符:。下面的代码片段可以用来测试新的:

 
  

当执行测试方法时,我们期望通过调用返回字符串,并且我们使用方法测试这个假设。如果在初始化数据库时出现任何问题,该测试将会失败。

使用行映射器检索域对象

大多数情况下,您会希望查询一行或多行,然后将每一行转换成相应的域对象或实体,而不是检索单个值。Spring 的接口(在包下)提供了一种简单的方法来执行从 JDBC 结果集到 POJOs 的映射。让我们通过使用接口实现的方法来看看它是如何工作的。在下面的代码片段中,您可以看到方法的实现:

 
  

在前面的代码片段中,我们定义了一个名为的静态内部类,它实现了接口。该类需要提供实现,它将的特定记录中的值转换成您想要的域对象。使它成为一个静态内部类允许你在多个查找器方法中共享。

使用 Java 8 lambda 表达式可以完全跳过类的显式实现;因此,方法可以这样重构:

 
  

之后,方法只需要调用查询方法,并传入查询字符串和行映射器。如果查询需要参数,方法提供了一个接受查询参数的重载方法。下面的测试类包含了一个用于方法的测试方法:

 
  

如果运行方法,测试必须通过,并且必须生成以下内容:

 
  

相册没有被打印出来,因为实现并没有在返回的实例上设置它们。

让我们来看一个稍微复杂一些的例子,在这个例子中,我们需要通过一个连接从父表()和子表()中检索数据,然后相应地将数据转换回嵌套对象(中的)。

前面提到的只适用于单个域对象的行映射。对于更复杂的对象结构,我们需要使用接口。为了演示它的用法,让我们在接口中再添加一个方法。该方法应该用歌手的专辑详细信息填充歌手列表。

下面的代码片段显示了将方法添加到接口以及使用实现该方法:

 
  

代码看起来很像示例,但是这次我们声明了一个实现的内部类。然后,我们实现方法,将结果集相应地转换成一列对象。对于方法,查询使用左连接来连接两个表,这样没有专辑的歌手也将被检索。结果是两个表的笛卡尔积。最后,我们使用方法,传入查询字符串和结果集提取器。

当然,内部类实际上并不是必需的,因为使用了 lambda 表达式。这里您可以看到使用 Java 8 lambda 表达式的版本:

 
  

下面的测试类包含了一个用于方法的测试方法:

 
  

如果运行方法,测试必须通过,并且必须生成以下内容:

 
  

你可以看到歌手和他们的专辑详细信息相应地列出。数据基于数据填充脚本,您可以在中找到每个 JDBC 样本项目的数据填充脚本。到目前为止,您已经看到了如何使用来执行一些常见的查询操作。(以及类)提供了许多重载方法,支持数据更新操作,包括插入、更新、删除等等。然而,方法是不言自明的,所以我们把它作为一个练习留给你去探索。另一方面,正如您将在后面的章节中看到的,我们将使用 Spring 提供的类来执行数据更新操作。

在上一节中,您看到了和相关的数据映射器实用程序类如何在使用 JDBC 开发数据访问逻辑时极大地简化了编程模型。建立在之上,Spring 还提供了许多有用的类,这些类模拟 JDBC 数据操作,并让开发人员以更加面向对象的方式维护从到域对象的查询和转换逻辑。具体来说,本节介绍了以下类别:

  • :类允许你将查询字符串和方法打包成一个类。
  • :类允许您将任何 SQL update 语句包装到其中。它还为您提供了许多有用的函数来绑定 SQL 参数,在插入新记录后检索 RDBMS 生成的键,等等。
  • :顾名思义,这个类允许你进行批量更新操作。例如,您可以循环遍历一个 Java 对象,让将记录排队,并批量提交更新语句。您可以随时设置批处理大小和刷新操作。
  • :类允许你用参数和返回类型调用数据库中的存储函数。另一个类也存在,它帮助您调用存储过程。
  • 利用注释设置 JDBC 道

首先让我们看看如何使用注释来设置 DAO 实现类。下面的示例代码逐个方法地实现了接口,直到我们有了完整的实现。下面的代码片段显示了接口类及其提供的数据访问服务的完整列表:

 
  

在本书的开始,引入了原型注释,并且引入了作为注释的专门化的,它被设计用于 beans 处理数据库操作。 4 下面的代码片段显示了使用 JSR-250 注释将数据源属性初始声明和注入到一个带注释的 DAO 类中:

 
  

在前面的清单中,我们使用来声明名为的 Spring bean,由于该类包含数据访问代码,还指示 Spring 对 Spring 中更加应用友好的层次结构执行特定于数据库的 SQL 异常。

我们还通过使用 SL4J 日志记录来声明 log 变量,以记录程序中的消息。我们使用 JSR-250 的作为属性,让 Spring 注入名为的数据源。

在下面的代码示例中,您可以看到使用注释声明 DAO 处理 beans 时的 Java 配置类:

 
  

在这个配置中,我们声明了一个 MySQL 数据库,使用一个可池化的来访问它,并使用组件扫描来自动发现 Spring bean。在本章的开始,你被告知如何安装和设置一个 MySQL 数据库并创建模式。基础设施就绪后,我们现在可以着手实施 JDBC 行动。

Spring 为建模查询操作提供了类。基本上,我们通过使用数据源和查询字符串来构造一个类。然后我们实现方法,将每个记录映射到相应的域对象。

让我们首先创建扩展了抽象类的类(它表示选择所有歌手的查询操作)。这里显示了类:

 
  

在类中,声明了选择所有歌手的 SQL。在类构造函数中,调用方法来构造类,使用和 SQL 语句。此外,实现了方法来提供结果集到域对象的映射。

有了类,我们可以在类中实现方法。下面的代码片段描述了类的一部分:

 
  

在方法中,在注入后,构建了一个类的实例。在方法中,我们简单地调用了方法,该方法间接继承自抽象类。这就是我们需要做的。以下代码片段显示了用于测试以这种方式实现的方法的方法:

 
  

如果测试通过,运行测试方法会产生以下输出:

 
  

如果通过编辑配置文件并添加以下元素为包启用了日志记录:

 
  

然后在控制台中,您还会看到 Spring 提交的查询,如下所示:

 
  

让我们继续实现方法,它接受一个命名参数。与前面的示例一样,我们为操作创建了类,如下所示:

 
  

类类似于类。首先,SQL 语句是不同的,它带有一个名为的命名参数。在构造函数方法中,调用了方法(间接从抽象类继承而来)。让我们继续在类中实现方法。在这里您可以看到更新后的代码:

 
  

在数据源注入时,构造一个的实例。然后,在方法中,用指定的参数和值构造一个。最后,调用方法(间接从抽象类继承而来)。让我们通过执行这里所示的测试方法来测试这个方法:

 
  

如果测试通过,运行测试方法会产生以下输出:

 
  

这里值得注意的一点是,只适合将单个行映射到一个域对象。对于嵌套对象,您仍然需要将与一起使用,就像在类一节中介绍的示例方法一样。

使用 SqlUpdate 更新数据

为了更新数据,Spring 提供了类。下面的代码片段显示了为更新操作扩展了类的类:

 
  

您现在应该对前面的清单很熟悉了。用查询构造了一个类的实例,并声明了命名参数。下面的代码片段展示了在类中方法的实现:

 
  

在数据源注入时,构造一个的实例。在方法中,从传入的对象构造一个命名参数的,然后调用更新联系人记录。为了测试操作,让我们给添加一个新方法。

 
  

这里我们简单地构造一个对象,然后调用方法。运行该程序会从最后一个方法产生以下输出。如果测试通过,运行测试方法会产生以下输出:

 
  

对于插入数据,我们也可以使用类。有趣的一点是主键是如何生成的(通常是列)。该值仅在 insert 语句完成后可用;这是因为 RDBMS 在插入时为记录生成标识值。列 ID 用属性声明,并且是主键,该值将在插入操作期间由 RDBMS 分配。如果您使用 Oracle,您可能会首先从 Oracle 序列中获得一个惟一的 ID,然后使用查询结果执行 insert 语句。

在 JDBC 的旧版本中,这种方法有点棘手。例如,如果我们使用 MySQL,您需要为 Microsoft SQL Server 执行 SQL 和 select 语句。

幸运的是,从 JDBC 版本 3.0 开始,增加了一个新特性,允许以统一的方式检索 RDBMS 生成的键。下面的代码片段显示了方法的实现,该方法还检索为插入的联系人记录生成的键。它可以在大多数数据库中工作(如果不是全部的话);请确保您使用的是与 JDBC 3.0 或更新版本兼容的 JDBC 驱动程序。

我们首先为插入操作创建类,它扩展了类。

 
  

级和级差不多;我们还需要做两件事。当构造类时,我们调用方法来声明 ID 列的名称。方法然后指示底层的 JDBC 驱动程序检索生成的密钥。在下面的代码中,您可以看到类中方法的实现:

 
  

在数据源注入时,构造一个的实例。在方法中,我们也使用了方法。此外,我们将的一个实例传递给该方法,该方法将把生成的 ID 存储在其中。插入数据后,我们可以从中检索生成的密钥。看看测试方法怎么找。

 
  

如果测试通过,运行测试方法会产生以下输出:

 
  

对于批处理操作,我们使用类。新的方法会将歌手及其发行的专辑插入数据库。为了能够插入专辑唱片,我们需要创建类,如下所示:

 
  

注意,在构造函数中,我们调用了方法来设置 JDBC 插入操作的批处理大小。这里您可以看到在类中方法的实现:

 
  

每次调用方法,都会构造一个新的实例,因为类不是线程安全的。然后我们就像一样使用。主要的区别是类将对插入操作进行排队,并批量提交给数据库。每当记录的数量等于批量大小时,Spring 将对数据库执行一个批量插入操作,以获得未决的记录。另一方面,在完成时,我们调用方法来指示 Spring 刷新所有挂起的操作(也就是说,正在排队但还没有达到批处理大小的插入操作)。最后,我们遍历对象中的对象列表,并调用方法。为了便于测试,还实现了方法。由于这个实现相当大,可以通过使用 Java 8 lambda 表达式来减少它。

 
  

我们来看看测试方法怎么找。

 
  

如果测试通过,运行测试方法会产生以下输出:

 
  

Spring 还提供了一些类来使用 JDBC 简化存储过程/函数的执行。在这一节中,我们将向您展示如何使用类来执行一个简单的函数。我们展示了如何将 MySQL 用于数据库,创建一个存储函数,并通过使用类调用它。

我们假设您有一个 MySQL 数据库,其模式名为,用户名和密码都等于(与“探索 JDBC 基础设施”一节中的示例相同)。让我们创建一个名为的存储函数,它接受联系人的 ID 并返回联系人的名字。下面的代码展示了在 MySQL 中创建存储函数的脚本()。对 MySQL 数据库运行脚本。

 
  

存储函数只接受 ID,并返回带有 ID 的歌手唱片的名字。接下来我们创建一个类来表示存储函数操作,它扩展了类。您可以在下面的代码片段中看到该类的内容:

 
  

这里,该类扩展了并传入了类型,这表明了函数的返回类型。然后我们声明 SQL 来调用 MySQL 中的存储函数。之后,在构造函数中,声明参数,然后我们编译操作。该类现在可以在实现类中使用了。下面的代码片段显示了使用存储函数的更新后的类:

 
  

在数据源注入时,构造一个的实例。然后在方法中,调用它的方法,传入联系人 ID。该方法将返回一个列表,我们只需要第一个,因为结果集中应该只返回一条记录。测试这个功能非常简单。

 
  

在程序中,我们将 ID 2 传递给存储函数。这将返回,如果对 MySQL 数据库运行,这是 ID 等于 2 的记录的第一个名称。运行该程序会产生以下输出:

 
  

您可以看到名字被正确检索。这里展示的只是一个简单的示例,用来演示 Spring JDBC 模块的功能。Spring 还为您提供了其他类(例如,)来调用返回复杂数据类型的复杂存储过程。如果您需要使用 JDBC 访问存储过程,我们建议您参考 Spring 的参考手册。

近年来,数据库技术发展如此之快,出现了如此多的专用数据库,如今 RDBMS 已不是应用后端数据库的唯一选择。为了响应这种数据库技术的发展和开发人员社区的需求,Spring 创建了 Spring Data 项目( )。该项目的主要目标是在 Spring 的核心数据访问功能之上提供有用的扩展,以便与传统 RDBMSs 之外的数据库进行交互。

Spring Data 项目附带了各种扩展。这里我们想提一下 JDBC 扩展( )。顾名思义,该扩展提供了一些高级特性,便于使用 Spring 开发 JDBC 应用。下面列出了 JDBC 扩展提供的主要功能:

  • QueryDSL 支持:QueryDSL ( )是一种特定于领域的语言,它为开发类型安全查询提供了一个框架。Spring Data 的 JDBC 扩展提供了来促进使用 QueryDSL 而不是 SQL 语句开发 JDBC 应用。
  • 对 Oracle 数据库的高级支持:该扩展为 Oracle 数据库用户提供了高级特性。在数据库连接方面,它支持 Oracle 特定的会话设置,以及在使用 Oracle RAC 时的快速连接故障转移技术。此外,还提供了与 Oracle 高级排队集成的类。在数据类型方面,提供了对 Oracle 的 XML 类型、和等的原生支持。

如果您正在使用 Spring 和 Oracle 数据库开发 JDBC 应用,JDBC 扩展确实值得一看。

有了这个丰富的特性集,您可以看到在使用 JDBC 与底层 RDBMS 交互时,Spring 是如何让您的生活变得更加轻松的。然而,仍然有相当多的代码需要开发,尤其是在将结果集转换成相应的域对象时。

在 JDBC 之上,已经开发了许多开源库来帮助缩小关系数据结构和 Java 的 OO 模型之间的差距。例如,iBATIS 是一个流行的框架,它也基于 SQL 映射。iBATIS 允许您将带有存储过程或查询的对象映射到 XML 描述符文件。像 Spring 一样,iBATIS 提供了查询对象映射的声明式方法,大大节省了维护分散在各种 DAO 类中的 SQL 查询的时间。

还有许多其他的 ORM 框架关注的是对象模型,而不是查询。流行的包括 Hibernate、EclipseLink(也称为 TopLink)和 OpenJPA。它们都符合 JCP 的 JPA 规范。

近年来,这些 ORM 工具和映射框架已经变得更加成熟,以至于大多数开发人员会选择其中的一个,而不是直接使用 JDBC。然而,在出于性能目的需要对提交给数据库的查询进行绝对控制的情况下(例如,在 Oracle 中使用分层查询),Spring JDBC 确实是一个可行的选择。当使用 Spring 时,一个很大的优势是您可以混合和匹配不同的数据访问技术。例如,您可以使用 Hibernate 作为主要的 ORM,然后使用 JDBC 作为一些复杂查询逻辑或批处理操作的补充;您可以在单个业务操作中混合和匹配它们,然后将它们包装在同一个数据库事务中。Spring 将帮助您轻松处理这些情况。

因为我们已经介绍了用于 web 和简单控制台应用的 Spring Boot,所以在本书中介绍用于 JDBC 的 Spring Boot 入门库是合乎逻辑的。它帮助您删除样板配置并直接进入实现。

当作为一个依赖项被添加到一个项目中时,一组库被添加到该项目中。没有添加的是数据库驱动程序。这个决定必须由开发商做出。本节将涉及的项目是,它是项目的一个子模块。其分级依赖关系和版本在以下父文件中指定:

 
  

它们在配置文件中被声明为依赖项,只是通过使用它们的属性名。

 
  

在 IntelliJ IDEA Gradle 项目视图中,自动配置的库如图 6-3 所示。库使用来配置 bean。因此,如果没有显式配置的 bean,并且类路径中有一个嵌入式数据库驱动程序,Spring Boot 将使用内存中的数据库设置自动注册 bean。Spring Boot 还会自动注册以下 beans:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

图 6-3。

Spring Boot JDBC starter dependencies

  • 一颗豆子
  • 一颗豆子
  • 一颗豆子

以下是其他一些有趣的事情,它们可以减少环境设置的工作量:

  • Spring Boot 在下寻找嵌入式数据库初始化文件。它期望找到包含 SQL DDL 语句(例如,语句)的名为的文件和包含 DML 语句(例如,语句)的名为的文件。它使用这个文件在启动时初始化数据库。
  • 这些文件的位置和名称可以在文件中配置,该文件也位于下。允许 Spring Boot 应用使用 SQL 文件的示例配置文件如下所示:
     
  • 默认情况下,Spring Boot 在引导时初始化数据库,但这也可以通过将属性添加到文件来改变。

除了上面提到的,Spring Boot 剩下要做的就是提供一些域类或实体和一个 DAO bean。 bean 与本章中到处使用的 bean 相同,它的实现驻留在项目中,该项目在任何地方都作为依赖项添加。要使用的类如下所示:

 
  

用标注的 Spring Boot 入口点类如下面的代码示例所示。请注意这是多么简单。

 
  

本章向您展示了如何使用 Spring 来简化 JDBC 编程。您学习了如何连接到数据库并执行选择、更新、删除和插入,以及调用数据库存储函数。使用核心 Spring JDBC 类,,详细讨论。我们讨论了构建在之上的其他 Spring 类,它们帮助您对各种 JDBC 操作建模。我们还展示了如何在适当的地方使用 Java 8 中新的 lambda 表达式。此外,Spring Boot·JDBC 也被涵盖在内,因为任何有助于你更多地关注应用的业务逻辑的实现而不是配置的东西都是一个很好的工具。在接下来的几章中,我们将讨论在开发数据访问逻辑时,如何使用 Spring 和流行的 ORM 技术。

Footnotes 1

WordPress 是一个广泛使用的博客平台,它使用 MySQL 或 MariaDB 来存储数据。

2

从 下载 MySQL 社区服务器。

3

这里是官方网站: 。

4

这表明带注释的类是一个存储库,最初由领域驱动设计(Evans,2003)定义为“一种封装存储、检索和搜索行为的机制,它模拟一组对象。”

到此这篇spring教程下载(spring教程 csdn)的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • xprinter客服(xprinter客服电话)2026-05-03 13:00:04
  • spring wang(spring 网页title设置)2026-05-03 13:00:04
  • tpami和cvpr哪个更厉害(cvpr和aaai)2026-05-03 13:00:04
  • iphone15promax(iphone15promax手电筒打不开)2026-05-03 13:00:04
  • third缩写(third,缩写)2026-05-03 13:00:04
  • 超详细oracle教程(oracle的使用教程)2026-05-03 13:00:04
  • airplay投屏是什么意思(airplay投屏有弹幕吗)2026-05-03 13:00:04
  • termux启动ubuntu(termux启动自动运行脚本)2026-05-03 13:00:04
  • ettercap怎么读(caltrate怎么读)2026-05-03 13:00:04
  • swagger2作用(swagger2的使用)2026-05-03 13:00:04
  • 全屏图片