本指南将引导您完成使用 Spring 访问关系数据的过程。
您将构建什么
您将构建一个应用程序,该应用程序使用 Spring 来访问存储在关系数据库中的数据。JdbcTemplate
你需要什么
- 约15分钟
- 最喜欢的文本编辑器或 IDE
- JDK 1.8或以后
- 格拉德尔 4+或梅文 3.2+
- 您也可以将代码直接导入到 IDE 中:
- 弹簧工具套件 (STS)
- 智能理念
- VSCode
如何完成本指南
像大多数春天一样入门指南,您可以从头开始并完成每个步骤,也可以绕过您已经熟悉的基本设置步骤。无论哪种方式,您最终都会得到工作代码。
要从头开始,请继续从 Spring 初始化开始.
要跳过基础知识,请执行以下操作:
- 下载并解压缩本指南的源存储库,或使用吉特:git clone https://github.com/spring-guides/gs-relational-data-access.git
- 光盘成gs-relational-data-access/initial
- 跳转到创建对象Customer.
完成后,您可以根据 中的代码检查结果。gs-relational-data-access/complete
从 Spring 初始化开始
你可以使用这个预初始化项目,然后单击生成以下载 ZIP 文件。此项目配置为适合本教程中的示例。
手动初始化项目:
如果您的 IDE 集成了 Spring Initializr,则可以从 IDE 完成此过程。
您也可以从 Github 分叉项目,然后在 IDE 或其他编辑器中打开它。
创建对象Customer
您将使用的简单数据访问逻辑管理客户的名字和姓氏。若要在应用程序级别表示此数据,请创建一个类,如以下清单 (from ) 所示:Customersrc/main/java/com/example/relationaldataaccess/Customer.java
package com.example.relationaldataaccess;public class Customer { private long id; private String firstName, lastName; public Customer(long id, String firstName, String lastName) { this.id = id; this.firstName = firstName; this.lastName = lastName; } @Override public String toString() { return String.format( "Customer[id=%d, firstName='%s', lastName='%s']", id, firstName, lastName); } // getters & setters omitted for brevity}存储和检索数据
Spring 提供了一个名为的模板类,它使使用 SQL 关系数据库和 JDBC 变得容易。大多数 JDBC 代码都陷入了资源获取、连接管理、异常处理和一般错误检查的泥潭,这与代码要实现的目标完全无关。会为您处理所有这些。您所要做的就是专注于手头的任务。下面的清单(来自)显示了一个可以通过 JDBC 存储和检索数据的类:JdbcTemplateJdbcTemplatesrc/main/java/com/example/relationaldataaccess/RelationalDataAccessApplication.java
package com.example.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;@SpringBootApplicationpublic class RelationalDataAccessApplication implements CommandLineRunner { private static final Logger log = LoggerFactory.getLogger(RelationalDataAccessApplication.class); public static void main(String args[]) { SpringApplication.run(RelationalDataAccessApplication.class, args); } @Autowired JdbcTemplate jdbcTemplate; @Override public void run(String... strings) throws Exception { log.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", "Josh 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 -> log.info(String.format("Inserting customer record for %s %s", name[0], name[1]))); // Uses JdbcTemplate's batchUpdate operation to bulk load data jdbcTemplate.batchUpdate("INSERT INTO customers(first_name, last_name) VALUES (?,?)", splitUpNames); log.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 -> log.info(customer.toString())); }}@SpringBootApplication是一个方便的注释,它添加了以下所有内容:
- @Configuration:将类标记为应用程序上下文的 Bean 定义源。
- @EnableAutoConfiguration:告诉 Spring 引导根据类路径设置、其他 bean 和各种属性设置开始添加 bean。
- @ComponentScan:告诉 Spring 在包中查找其他组件、配置和服务。在这种情况下,没有。com.example.relationaldataaccess
该方法使用 Spring Boot 的方法启动应用程序。main()SpringApplication.run()
Spring Boot 支持 H2(内存中关系数据库引擎)并自动创建连接。因为我们使用 ,Spring Boot 会自动创建一个 .该字段会自动加载它并使其可用。spring-jdbcJdbcTemplate@Autowired JdbcTemplate
此类实现了 Spring Boot 的,这意味着它将在加载应用程序上下文后执行该方法。ApplicationCommandLineRunnerrun()
首先,使用 .executeJdbcTemplate
其次,获取字符串列表,并使用 Java 8 流将它们拆分为 Java 数组中的名字/姓氏对。
然后使用 的方法在新创建的表中安装一些记录。方法调用的第一个参数是查询字符串。最后一个参数(实例数组)保存要替换到字符所在的查询中的变量。batchUpdateJdbcTemplateObject?
对于单插入语句,方法很好。但是,对于多个插入,最好使用 .insertJdbcTemplatebatchUpdate
用于参数以避免?SQL 注入攻击通过指示 JDBC 绑定变量。
最后,使用该方法在表中搜索与条件匹配的记录。再次使用参数为查询创建参数,并在进行调用时传入实际值。最后一个参数是 Java 8 lambda,用于将每个结果行转换为新对象。query?Customer
Java 8 lambdas很好地映射到单方法接口上,例如Spring的。如果您使用的是 Java 7 或更早版本,则可以插入匿名接口实现,并使方法主体与 lambda 表达式的主体相同。RowMapper
构建可执行的 JAR
您可以使用 Gradle 或 Maven 从命令行运行应用程序。您还可以构建一个包含所有必需依赖项、类和资源的可执行 JAR 文件并运行该文件。通过构建可执行 jar,可以轻松地在整个开发生命周期中跨不同环境等将服务作为应用程序进行交付、版本控制和部署。
如果使用 Gradle,则可以使用 .或者,您可以使用 JAR 文件生成 JAR 文件,然后运行该文件,如下所示:./gradlew bootRun./gradlew build
java -jar build/libs/gs-relational-data-access-0.1.0.jar如果使用 Maven,则可以使用 运行应用程序。或者,您可以使用 JAR 文件生成 JAR 文件,然后运行该文件,如下所示:./mvnw spring-boot:run./mvnw clean package
java -jar target/gs-relational-data-access-0.1.0.jar此处描述的步骤将创建一个可运行的 JAR。你也可以构建经典 WAR 文件.
应会看到以下输出:
2019-09-26 13:46:58.561 INFO 47569 --- [ main] c.e.r.RelationalDataAccessApplication : Creating tables2019-09-26 13:46:58.564 INFO 47569 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...2019-09-26 13:46:58.708 INFO 47569 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.2019-09-26 13:46:58.809 INFO 47569 --- [ main] c.e.r.RelationalDataAccessApplication : Inserting customer record for John Woo2019-09-26 13:46:58.810 INFO 47569 --- [ main] c.e.r.RelationalDataAccessApplication : Inserting customer record for Jeff Dean2019-09-26 13:46:58.810 INFO 47569 --- [ main] c.e.r.RelationalDataAccessApplication : Inserting customer record for Josh Bloch2019-09-26 13:46:58.810 INFO 47569 --- [ main] c.e.r.RelationalDataAccessApplication : Inserting customer record for Josh Long2019-09-26 13:46:58.825 INFO 47569 --- [ main] c.e.r.RelationalDataAccessApplication : Querying for customer records where first_name = 'Josh':2019-09-26 13:46:58.835 INFO 47569 --- [ main] c.e.r.RelationalDataAccessApplication : Customer[id=3, firstName='Josh', lastName='Bloch']2019-09-26 13:46:58.835 INFO 47569 --- [ main] c.e.r.RelationalDataAccessApplication : Customer[id=4, firstName='Josh', lastName='Long']总结
祝贺!您刚刚使用 Spring 开发了一个简单的 JDBC 客户端。