65.9K
CodeProject 正在变化。 阅读更多。
Home

在 Spring Boot Web 应用程序中使用 JdbcTemplate

starIconstarIconstarIconstarIconstarIcon

5.00/5 (4投票s)

2018年12月3日

MIT

11分钟阅读

viewsIcon

21604

downloadIcon

223

在本教程中,我将介绍如何在 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);

要查询汽车型号,该方法使用制造商(例如 HondaMazdaFordChevrolet 等)、年份范围(开始年份和结束年份),并返回符合条件的汽车型号列表。所以代码是这样的:

@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 对象,按照惯例,它被称为 dataSourcedataSouce() 方法也用于配置 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 对象,其中键与命名参数匹配,值是将被添加到数据库的命名参数的值。
  • 使用名为 sqlDaoNamedParameterJdbcTemplate 对象调用 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;
}

这个方法有点复杂。工作原理如下:

该方法调用 sqlDaoquery() 方法,传入三个参数:

  • 第一个参数是 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 - 初稿
© . All rights reserved.