Spring Boot入门教程:第四章:使用JDBC访问关系型数据库

本章带你用Spring Boot实现访问关系型数据库。

本文目标

用Spring Boot构建一个应用,使用JdbcTemplate 去访问储存在一个关系型数据库里面的数据。

你需要

  • 15分钟左右
  • IntelliJ IDEA
  • JDK 1.8+
  • Maven 3.2+

用Spring Initializr生成项目代码

对于所有的Spring应用,你都可以使用Spring Initializr生成基本的项目代码。Initializr提供了一个快速的方式去引入所有你需要的依赖,并且为你做了很多设置。当前例子需要JDBC API和H2 Database依赖。具体设置如下图:
在这里插入图片描述
如上图所示,我们选择了Maven作为编译工具。你也可以选择Gradle来进行编译。然后我们分别把Group和Artifact设置为“com.hansy”和“relational-data-access”。

生成的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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.1.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.hansy</groupId>
	<artifactId>relational-data-access</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>relational-data-access</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jdbc</artifactId>
		</dependency>

		<dependency>
			<groupId>com.h2database</groupId>
			<artifactId>h2</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

创建一个Customer对象

我们将要实现的数据存取逻辑就是管理客户的名字和姓氏。为了在应用层表示这些数据,定义一个Customer类,代码如下:

package com.hansy.relationaldataaccess;

public class Customer {
    
    

    private long id;
    private String firstName;
    private String lastName;

    public Customer(long id, String firstName, String lastName) {
    
    
        this.id = id;
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public long getId() {
    
    
        return id;
    }

    public void setId(long id) {
    
    
        this.id = id;
    }

    public String getFirstName() {
    
    
        return firstName;
    }

    public void setFirstName(String firstName) {
    
    
        this.firstName = firstName;
    }

    public String getLastName() {
    
    
        return lastName;
    }

    public void setLastName(String lastName) {
    
    
        this.lastName = lastName;
    }

    @Override
    public String toString() {
    
    
        return "Customer{" +
                "id=" + id +
                ", firstName='" + firstName + '\'' +
                ", lastName='" + lastName + '\'' +
                '}';
    }
}

保存和检索数据

Spring提供了一个模板类JdbcTemplate,它把SQL关系数据库和JDBC的调用变得很容易。大部分的JDBC代码都在处理 “资源获取”、“连接管理”、“异常处理”和“一般错误的检查”,这些跟代码原本想要实现的效果没有直接关系的操作。但是JdbcTemplate可以把这些原本繁琐的处理都接管了。你只需要专注于手边的任务。下面的代码将展示怎么通过JDBC来保存和检索数据:

package com.hansy.relationaldataaccess;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@SpringBootApplication
public class RelationalDataAccessApplication implements CommandLineRunner {
    
    

    private static final Logger logger = LoggerFactory.getLogger(RelationalDataAccessApplication.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public static void main(String[] args) {
    
    
        SpringApplication.run(RelationalDataAccessApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
    
    

        logger.info("Creating tables");

        jdbcTemplate.execute("DROP TABLE customers IF EXISTS");
        jdbcTemplate.execute("CREATE TABLE customers (" +
                " id SERIAL, first_name VARCHAR(255), last_name VARCHAR(255))");

        // Split up the array of whole names into an array of first/last names
        List<Object[]> splitUpNames = Arrays.asList("John Woo", "Jeff Dean", "Josh Bloch", "Jsoh Long")
                .stream().map(name -> name.split(" "))
                .collect(Collectors.toList());

        // Use a Java 8 stream to print out each tuple of the list
        splitUpNames.forEach(name -> logger.info(String.format("Inserting customer record for %s %s", name[0], name[1])));

        //Use JdbcTemplate's batchUpdate operation to bulk load data
        jdbcTemplate.batchUpdate("INSERT INTO customers(first_name, last_name) VALUES (?,?)", splitUpNames);

        logger.info("Querying for customer records where first_name = 'Josh':");
        jdbcTemplate.query("SELECT id, first_name, last_name FROM customers WHERE first_name = ?", new Object[]{
    
    "Josh"}
                , (rs, rowNum) -> new Customer(rs.getLong("id"), rs.getString("first_name"), rs.getString("last_name")))
                .forEach(customer -> logger.info(customer.toString()));
    }
}

Spring Boot支持H2(一个内存式关系数据库引擎),并且会自动创建一个连接。因为我们使用spring-jdbc,Spring Boot自动创建一个JdbcTemplate。而 @Autowired JdbcTemplate 字段会自动加载JdbcTemplate,然后提供给我们使用。

上面的Application类实现了Spring Boot的CommandLineRunner接口,所以程序上下文加载之后,就会执行run()方法。

run()方法的流程:

  • 使用JdbcTemplate的execute方法来执行一些DDL语句。
  • 拿到一个字符串列表,接着使用Java 8的Stream API,把字符串列表分解成“名字/姓氏”这样成对的JAVA数组。
  • 使用JdbcTemplate的batchUpdate方法插入一些数据到新创建的customers表里面。batchUpdate方法的第一个参数是SQL语句,第二个参数(Object数组)则是SQL语句中“?”所代表的参数的实际值。(单个插入语句的可以使用JdbcTemplate的insert方法,但是多个插入语句最好使用batchUpdate方法)(使用“?”进行参数绑定可以规避SQL注入攻击
  • 使用query方法从customers表中根据条件查询数据。依然使用“?”进行参数绑定。最后一个参数是一个 Java 8的lambda表达式,把每个结果行转换为一个Customer对象。

本文使用了Java 8的lambda表达式对Spring的RowMapper进行了映射。如果你使用Java 7或者更早的版本,你可以使用一个匿名的接口实现类,方法体可以直接使用lambda表达式里面的内容。

运行应用

运行程序,你可以看到如下结果:

2020-07-18 10:58:13.663  INFO 17436 --- [           main] c.h.r.RelationalDataAccessApplication    : Creating tables
2020-07-18 10:58:13.675  INFO 17436 --- [           main] c.h.r.RelationalDataAccessApplication    : Inserting customer record for John Woo
2020-07-18 10:58:13.675  INFO 17436 --- [           main] c.h.r.RelationalDataAccessApplication    : Inserting customer record for Jeff Dean
2020-07-18 10:58:13.675  INFO 17436 --- [           main] c.h.r.RelationalDataAccessApplication    : Inserting customer record for Josh Bloch
2020-07-18 10:58:13.675  INFO 17436 --- [           main] c.h.r.RelationalDataAccessApplication    : Inserting customer record for Josh Long
2020-07-18 10:58:13.684  INFO 17436 --- [           main] c.h.r.RelationalDataAccessApplication    : Querying for customer records where first_name = 'Josh':
2020-07-18 10:58:13.692  INFO 17436 --- [           main] c.h.r.RelationalDataAccessApplication    : Customer{id=3, firstName='Josh', lastName='Bloch'}
2020-07-18 10:58:13.693  INFO 17436 --- [           main] c.h.r.RelationalDataAccessApplication    : Customer{id=4, firstName='Josh', lastName='Long'}

小结

你已经用Spring Boot开发了一个简单的JDBC客户端。

源码下载

relational-data-access

参考资料

https://spring.io/guides/gs/relational-data-access/

猜你喜欢

转载自blog.csdn.net/hanshiying007/article/details/107351718
今日推荐