在 Spring Boot Web 应用程序中使用 JdbcTemplate
在本教程中,我将介绍如何在 Spring Boot Web 应用程序中使用 Spring JdbcTemplate。本教程将展示如何创建 JdbcTemplate 所需的配置。以及如何使用它进行数据插入和检索。
引言
这将是我 2018 年的最后一个教程。在本教程中,我将讨论一些有趣的内容。数据访问是我最喜欢的主题之一。我曾经讨厌与数据库打交道,因为我在这方面不是很好。随着经验的积累,我对数据库的厌恶感越来越少。多年来,我曾使用过 ADO.NET、Entity Framework、Hibernate、SSRS 报告以及其他一些与数据库相关的工作。我学到的是,即使我讨厌它,也无法逃避。最好还是面对它并学习它。
我过去没有机会使用的 Spring 技术之一是 JdbcTemplate
。它是 Spring 处理 JDBC 的方式。在当今世界,我们有 Entity Framework 和 Hibernate 来进行 ORM,那么 JDBC 还有什么意义呢?有两个主要原因:
- 使用 JDBC,您可以直接处理查询本身并以任何您想要的方式对其进行优化。使用 ORM,您将无法获得这种奢侈。
- 另一个原因是支持遗留代码。有时,您会继承过去遗留下来的东西。并且需要进行升级,而您是被任命负责这项工作的人。所以很多代码都是用 JDBC 完成的,也许使用 Spring JDBC 可以有所帮助?谁知道呢。
对我来说,JDBC 只是一种非常简单直接的将数据导入和导出数据库的方式。我知道它可能比 ORM 稍快一些。有时,ORM 框架会让编码变得异常尴尬。然而,JDBC 也有其尴尬之处,一旦我获取了数据,我就必须将其映射到一个实体对象。
本教程将讨论如何设置用于 JdbcTemplate
的 Spring DAO,以及插入和检索数据的基本知识。
设置数据库
为了使这个示例应用程序正常工作,我们需要设置一个 MySQL 数据库,一个数据库用户和一个表。我准备了两个 SQL 脚本:
- 一个脚本用于创建数据库用户和数据库
- 另一个脚本用于在新建的数据库中创建表
要创建数据库和用户,请使用以下脚本:
-- user.sql
CREATE DATABASE cardb;
CREATE USER 'cardbuser'@'localhost' IDENTIFIED BY '123test321';
GRANT ALL PRIVILEGES ON cardb.* TO 'cardbuser'@'localhost';
FLUSH PRIVILEGES;
要为示例应用程序创建表,请使用以下脚本:
-- tables.sql
use cardb;
DROP TABLE IF EXISTS carinfo;
CREATE TABLE carinfo (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
yearofmanufacture INT NOT NULL,
model VARCHAR(64) NOT NULL,
make VARCHAR(64) NOT NULL,
suggestedretailprice FLOAT NOT NULL,
fullprice FLOAT NOT NULL,
rebateamount FLOAT NOT NULL,
createdate DATETIME NOT NULL,
updatedate DATETIME NOT NULL
);
现在,让我们看一下 pom.xml 文件。
Maven POM 文件
Maven POM XML 非常简单,看起来是这样的:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework</groupId>
<artifactId>hanbo-boot-rest</artifactId>
<version>1.0.1</version>
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
为了总结此 POM 文件中的内容,项目继承自 spring-boot-starter-parent
。所需的依赖项是:
spring-boot-starter-web
:此依赖项用于创建基于 Web 的应用程序。它同时支持 MVC 和 RESTFul 应用程序。spring-boot-starter-jdbc
:此依赖项用于使用 Spring DAO JDBC 功能。mysql-connector-java
:此依赖项用于提供特定于 MySQL 数据库的 JDBC 驱动程序。
使用 Maven 进行构建时,它会创建一个 jar 文件,该文件可以通过简单的 Java 命令运行。我将在最后向您展示如何操作。
主入口
正如我在 第一个 Spring Boot 教程 中所描述的,基于 Spring Boot 的 Web 应用程序不需要应用程序容器来托管它。因此,它被打包成一个 jar 文件,可以作为常规 Java 程序运行。这就是为什么这个示例应用程序有一个主入口。主入口的代码如下所示:
package org.hanbo.boot.rest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class App
{
public static void main(String[] args)
{
SpringApplication.run(App.class, args);
}
}
该类使用 @SpringBootApplication
注解标记为 Spring Boot 应用程序。主入口方法会将该类传递给 SpringApplication.run()
。Spring Boot 的应用程序运行器将创建 IoC 容器,并扫描所有包和子包以查找可以添加到 IoC 容器中的任何类。因为我们添加了 Web Starter 依赖项,所以应用程序将作为 Web 应用程序启动。Spring Boot 会自动处理配置。
REST API 控制器
接下来,我将向您展示用于演示 JdbcTemplate
用法的 REST API 的控制器类。这是完整的源代码:
package org.hanbo.boot.rest.controllers;
import java.util.ArrayList;
import java.util.List;
import org.hanbo.boot.rest.models.CarModel;
import org.hanbo.boot.rest.models.GenericResponse;
import org.hanbo.boot.rest.repository.CarRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SampleController
{
@Autowired
private CarRepository carRepo;
@RequestMapping(value="/public/addCar", method = RequestMethod.POST)
public ResponseEntity<GenericResponse> addCar(
@RequestBody
CarModel carToAdd)
{
GenericResponse retMsg = new GenericResponse();
if (carToAdd != null)
{
try
{
carRepo.addCar(carToAdd);
retMsg.setSuccess(true);
retMsg.setStatusMsg("Operation is successful.");
}
catch (Exception ex)
{
ex.printStackTrace();
retMsg.setSuccess(false);
retMsg.setStatusMsg("Exception occurred.");
}
}
else
{
retMsg.setSuccess(false);
retMsg.setStatusMsg("No valid car model object to be added");
}
ResponseEntity<GenericResponse> retVal;
retVal = ResponseEntity.ok(retMsg);
return retVal;
}
@RequestMapping(value="/public/getCars", method = RequestMethod.GET)
public ResponseEntity<List<CarModel>> getCars(
@RequestParam("make")
String make,
@RequestParam("startYear")
int startYear,
@RequestParam("endYear")
int endYear)
{
List<CarModel> foundCars
= carRepo.findCar(make, startYear, endYear);
if (foundCars == null) {
foundCars = new ArrayList<CarModel>();
}
ResponseEntity<List<CarModel>> retVal;
retVal = ResponseEntity.ok(foundCars);
return retVal;
}
}
我特意将其设置为 REST API 控制器,因为演示我想展示的功能相对简单。该类被注解为 @RestController
,这样 Spring Boot 就会识别出该类将充当 RESTFul API 控制器。
类中有两个方法。它们都用于处理用户的 HTTP 请求。它们基本上是动作方法。第一个用于将汽车型号添加到数据库。另一个是查询符合三个不同搜索标准的汽车型号列表。这两个方法都使用相同的数据访问存储库,该存储库使用 JdbcTemplate
对象。
简单来说,要将新的汽车型号添加到数据库表中,方法如下:
@Autowired
private CarRepository carRepo;
...
carRepo.addCar(carToAdd);
要查询汽车型号,该方法使用制造商(例如 Honda
、Mazda
、Ford
、Chevrolet
等)、年份范围(开始年份和结束年份),并返回符合条件的汽车型号列表。所以代码是这样的:
@RequestMapping(value="/public/getCars", method = RequestMethod.GET)
public ResponseEntity<List<CarModel>> getCars(
@RequestParam("make")
String make,
@RequestParam("startYear")
int startYear,
@RequestParam("endYear")
int endYear)
{
...
List<CarModel> foundCars
= carRepo.findCar(make, startYear, endYear);
...
}
为了设计这样的数据访问存储库,必须进行配置。需要哪些配置?例如:
- 数据库连接字符串
- 用于连接数据库的用户和密码
- 事务管理器
- 数据库 JDBC 驱动程序类
这将在下一节中介绍。
JDBC 连接配置
为了使用 JdbcTemplate
,必须首先进行配置。这是执行此操作的类:
package org.hanbo.boot.rest.config;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
@Configuration
public class JdbcConfiguration
{
@Bean
public DataSource dataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://:3306/cardb");
dataSource.setUsername("cardbuser");
dataSource.setPassword("123test321");
return dataSource;
}
@Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate()
{
NamedParameterJdbcTemplate retBean
= new NamedParameterJdbcTemplate(dataSource());
return retBean;
}
@Bean
public DataSourceTransactionManager txnManager()
{
DataSourceTransactionManager txnManager
= new DataSourceTransactionManager(dataSource());
return txnManager;
}
}
让我们逐个部分地检查这个类。首先是使用 @Configuration
注解该类。这会告诉 Spring Boot 将该类视为配置,并在启动时对其进行引导。
@Configuration public class JdbcConfiguration { ... }
接下来,我需要一个数据源。这是一个 Java 对象,按照惯例,它被称为 dataSource
。dataSouce()
方法也用于配置 MySQL 连接:
@Bean
public DataSource dataSource()
{
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://:3306/cardb");
dataSource.setUsername("cardbuser");
dataSource.setPassword("123test321");
return dataSource;
}
此 dataSource()
方法返回一个 DriverManagerDatSource
类的对象。方法的其余部分将使用诸如 MySQL JDBC 驱动程序、连接字符串、用户名和密码之类的配置来设置数据源对象。代码是不言自明的。
现在,是时候揭开本教程的核心对象——创建 JdbcTemplate
对象了。我真正喜欢使用的是带有命名参数的查询。为了做到这一点,我必须使用一种特殊的 JdbcTemplate
对象,即 NamedParameterJdbcTemplate
类。所以,这是它的样子:
@Bean
public NamedParameterJdbcTemplate namedParameterJdbcTemplate()
{
NamedParameterJdbcTemplate retBean
= new NamedParameterJdbcTemplate(dataSource());
return retBean;
}
此方法所做的就是创建一个 NamedParameterJdbcTemplate
对象。它需要一个数据源对象。
您需要的最后一件事是事务管理器。Spring 事务管理器可用于向存储库方法添加事务注解,以便 CRUD 操作可以被包装到 SQL 事务中。这是事务管理器对象:
@Bean
public DataSourceTransactionManager txnManager()
{
DataSourceTransactionManager txnManager
= new DataSourceTransactionManager(dataSource());
return txnManager;
}
有了这个事务管理器,就可以在存储库方法中提交和回滚事务了。这些是我们让 JdbcTemplate
对象正常工作所需的所有配置。我们最后需要的是具有 CRUD 操作的存储库类。
存储库类
repository
对象用于执行与 SQL 数据库的 CRUD 操作。为简单起见,我在 controller
类中直接使用了我的 repository
对象。实际上,最好将 DTO 对象和数据实体对象分开。并在存储库层之上设置服务层。
我的 repository
类如下所示:
package org.hanbo.boot.rest.repository;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.hanbo.boot.rest.models.CarModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
@Repository
public class CarRepository
{
@Autowired
private NamedParameterJdbcTemplate sqlDao;
private final String addCar_sql = "INSERT INTO carinfo (yearofmanufacture, model, make,
suggestedretailprice, fullprice, rebateamount, createdate, updatedate)"
+ " VALUES (:yearOfManufacture, :model, :make, :suggestedRetailPrice, :fullPrice,
:rebateAmount, :createdDate, :updatedDate)";
private final String getCars_sql = "SELECT id,"
+ " yearofmanufacture,"
+ " model,"
+ " make,"
+ " suggestedretailprice,"
+ " fullprice,"
+ " rebateamount,"
+ " createdate,"
+ " updatedate FROM carinfo WHERE make = :make AND
yearofmanufacture >= :startYear AND yearofmanufacture <= :endYear";
@Transactional
public void addCar(CarModel carToAdd)
{
if (carToAdd != null)
{
Map<String, Object> parameters = new HashMap<String, Object>();
Date dateNow = new Date();
parameters.put("yearOfManufacture", carToAdd.getYearOfManufacturing());
parameters.put("model", carToAdd.getModel());
parameters.put("make", carToAdd.getMaker());
parameters.put("suggestedRetailPrice", carToAdd.getSuggestedRetailPrice());
parameters.put("fullPrice", carToAdd.getFullPrice());
parameters.put("rebateAmount", carToAdd.getRebateAmount());
parameters.put("createdDate", dateNow);
parameters.put("updatedDate", dateNow);
int retVal = sqlDao.update(addCar_sql, parameters);
System.out.println("Rows updated: " + retVal);
throw new RuntimeException("dummy Bad");
}
else
{
System.out.println("Car to add is invalid. Null Object.");
}
}
@Transactional
public List<CarModel> findCar(String make, int startYear, int endYear)
{
List<CarModel> foundObjs = sqlDao.query(getCars_sql,
(new MapSqlParameterSource("make", make))
.addValue("startYear", startYear)
.addValue("endYear", endYear),
(rs) -> {
List<CarModel> retVal = new ArrayList<CarModel>();
if (rs != null)
{
while(rs.next())
{
CarModel cm = new CarModel();
cm.setYearOfManufacturing(rs.getInt("yearOfManufacture"));
cm.setMaker(rs.getString("make"));
cm.setModel(rs.getString("model"));
cm.setSuggestedRetailPrice(rs.getFloat("suggestedretailprice"));
cm.setFullPrice(rs.getFloat("fullprice"));
cm.setRebateAmount(rs.getFloat("rebateamount"));
retVal.add(cm);
}
}
return retVal;
});
return foundObjs;
}
}
关于这个类的第一件事是它被注解为 @Repository
。接下来,是 JdbcTemplate
对象的自动注入,它将用于数据访问 CRUD 操作。
@Autowired
private NamedParameterJdbcTemplate sqlDao;
JdbcTemplate
对象的注入来自配置类。接下来,我必须定义两个查询 string
。一个用于将数据行插入数据库表。另一个是返回 car
模型列表的查询。
private final String addCar_sql = "INSERT INTO carinfo (yearofmanufacture, model, make,
suggestedretailprice, fullprice, rebateamount, createdate, updatedate)"
+ " VALUES (:yearOfManufacture, :model, :make, :suggestedRetailPrice, :fullPrice,
:rebateAmount, :createdDate, :updatedDate)";
private final String getCars_sql = "SELECT id,"
+ " yearofmanufacture,"
+ " model,"
+ " make,"
+ " suggestedretailprice,"
+ " fullprice,"
+ " rebateamount,"
+ " createdate,"
+ " updatedate FROM carinfo WHERE make = :make AND
yearofmanufacture >= :startYear AND yearofmanufacture <= :endYear";
还记得我说的关于命名参数吗?在上面的查询中,我使用了类似这样的内容::suggestedRetailPrice
。这是一个命名参数。命名参数是以降号“:
”开头的内容,后面跟着实际的参数名称。无论如何,这是添加汽车型号的方法:
@Transactional
public void addCar(CarModel carToAdd)
{
if (carToAdd != null)
{
Map<String, Object> parameters = new HashMap<String, Object>();
Date dateNow = new Date();
parameters.put("yearOfManufacture", carToAdd.getYearOfManufacturing());
parameters.put("model", carToAdd.getModel());
parameters.put("make", carToAdd.getMaker());
parameters.put("suggestedRetailPrice", carToAdd.getSuggestedRetailPrice());
parameters.put("fullPrice", carToAdd.getFullPrice());
parameters.put("rebateAmount", carToAdd.getRebateAmount());
parameters.put("createdDate", dateNow);
parameters.put("updatedDate", dateNow);
int retVal = sqlDao.update(addCar_sql, parameters);
System.out.println("Rows updated: " + retVal);
}
else
{
System.out.println("Car to add is invalid. Null Object.");
}
}
工作原理
- 定义一个
Map
对象,其中键与命名参数匹配,值是将被添加到数据库的命名参数的值。 - 使用名为
sqlDao
的NamedParameterJdbcTemplate
对象调用update()
,传入addCar_sql
(其中包含插入car
模型 \的查询)。 - 调用 update 会返回一个整数,表示受影响的行数。
- 最后,我打印出这个整数,看看是否成功。
查找 car
列表的查询是通过另一个名为 findCar()
的存储库方法完成的,这是源代码:
@Transactional
public List<CarModel> findCar(String make, int startYear, int endYear)
{
List<CarModel> foundObjs = sqlDao.query(getCars_sql,
(new MapSqlParameterSource("make", make))
.addValue("startYear", startYear)
.addValue("endYear", endYear),
(rs) -> {
List<CarModel> retVal = new ArrayList<CarModel>();
if (rs != null)
{
while(rs.next())
{
CarModel cm = new CarModel();
cm.setYearOfManufacturing(rs.getInt("yearOfManufacture"));
cm.setMaker(rs.getString("make"));
cm.setModel(rs.getString("model"));
cm.setSuggestedRetailPrice(rs.getFloat("suggestedretailprice"));
cm.setFullPrice(rs.getFloat("fullprice"));
cm.setRebateAmount(rs.getFloat("rebateamount"));
retVal.add(cm);
}
}
return retVal;
});
return foundObjs;
}
这个方法有点复杂。工作原理如下:
该方法调用 sqlDao
的 query()
方法,传入三个参数:
- 第一个参数是
getCars_sql
,这是查询字符串。 - 第二个参数是
MapSqlParameterSource
的一个对象,它可能是一个包装的Map
对象。键与命名参数匹配,值是命名参数的值。 - 第三个是函数式编程语言中编写的一个接口的实现,它基本上是将
ResultSet
对象映射到一个实体对象列表。
方法调用完成后,将返回一个 CarModel
类型的对象列表。该方法的函数式编程部分是这样的:
(rs) -> {
List<CarModel> retVal = new ArrayList<CarModel>();
if (rs != null)
{
while(rs.next())
{
CarModel cm = new CarModel();
cm.setYearOfManufacturing(rs.getInt("yearOfManufacture"));
cm.setMaker(rs.getString("make"));
cm.setModel(rs.getString("model"));
cm.setSuggestedRetailPrice(rs.getFloat("suggestedretailprice"));
cm.setFullPrice(rs.getFloat("fullprice"));
cm.setRebateAmount(rs.getFloat("rebateamount"));
retVal.add(cm);
}
}
return retVal;
}
名为“rs
”的输入参数是 ResultSet
类型。箭头“->
”基本上表示 ResultSet
对象将由在花括号 {...}
中定义的函数进行操作。在此花括号中,首先创建一个 CarModel
列表。然后检查 ResultSet
对象是否不为 null
。它将逐行遍历结果集,并将行转换为 CarModel
对象。然后将该对象添加到列表中。最后,返回列表。这个 list
对象是 findCars()
方法将返回的列表。
以上就是如何设置示例项目以使用 JdbcTemplate
的全部内容。现在是时候测试它了。
测试应用程序
现在我们有了应用程序的所有内容,是时候进行测试并查看它是否正常工作了。并且它确实有效。在测试之前,我们需要构建它。然后,我们需要将其作为 Java 应用程序启动。
要构建项目,请“cd
”到示例项目的基础目录,然后使用以下命令:
mvn clean install
要启动应用程序,请在示例项目的基础目录中使用以下命令:
java -jar target\hanbo-boot-rest-1.0.1.jar
命令行控制台将输出大量文本。最后,它将成功并输出类似这样的内容:
...
2018-12-01 22:56:10.870 INFO 10832 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer :
Tomcat started on port(s): 8080 (http) with context path ''
2018-12-01 22:56:10.877 INFO 10832 --- [ main] org.hanbo.boot.rest.App :
Started App in 15.656 seconds (JVM running for 18.044)
现在,是时候进行测试了。我使用一个名为“Postman
”的程序,它可以向这个 RESTFul 示例应用程序发送 HTTP 请求。要尝试的第一件事是将 CarModel
对象添加到数据库。URL 如下:
https://:8080/public/addCar
此 URL 仅接受 HTTP POST 请求。请求正文将是一个 JSON string
,表示 CarModel
对象,看起来是这样的:
{
"yearOfManufacturing": 2007,
"maker": "Subaru",
"model": "Outback",
"suggestedRetailPrice": 17892.95,
"fullPrice": 18900.95,
"rebateAmount": 300.65
}
要使用“Postman
”发送请求,请执行以下操作:
- 将 URL 设置为 https://:8080/public/addCar。
- 在 URL 文本框的左侧,将 HTTP 方法选择为“
POST
”。 - 请求正文应包含 JSON
string
。 - 将内容类型设置为“
application/json
”。
这是“Postman
”的屏幕截图:
单击“Send”按钮。服务器将返回成功响应。这是屏幕截图:
现在尝试按制造商“Subaru
”、开始年份(值为:2006
)和结束年份(值为:2008
)搜索汽车。请求通过 HTTP GET
和请求参数完成。URL 如下:
https://:8080/public/getCars?make=Subaru&startYear=2006&endYear=2008
此请求的“Postman
”屏幕截图如下所示:
单击“Send”按钮,请求将成功处理,并返回表示找到的汽车列表的 JSON string
。根据您添加到数据库的汽车,列表可能包含零个、一个或多个元素。这是我添加了同一辆车两次的屏幕截图:
就是这样。如果您想测试事务回滚,可以在调用 sqlDao.update()
之后的行上,在 addCar()
中抛出一个异常。然后测试添加汽车场景。异常将被抛出,并阻止该行被添加到数据库。
摘要
这是我为 2018 年发布的最后一个教程。在 2017 年 12 月 31 日,我设定了在 2018 年撰写 10 个教程的目标,并在 2018 年 12 月 1 日之前完成了。在整整一年里,我发表了关于各种主题的教程。这是我最新的一篇努力。
在本教程中,我讨论了以下主题:
- 基于 JDBC 的数据访问的配置。
- 可以添加实体到数据库并根据简单条件检索的存储库对象。
JdbcTemplate
的使用,特别是NamedParameterJdbcTemplate
对象用于数据插入和检索。- 并通过示例应用程序的 RESTFul 接口对数据访问进行了一些简单的测试。
一如既往,发布这样的教程是一件很棒的事情。希望您喜欢它。
历史
- 2018-12-01 - 初稿