YMNNALFT:一个轻量级的使用JdbcTemplate的SQL数据映射器

工程 | Josh Long | 2021年2月1日 | ...

欢迎来到您可能不需要另一个库来做这件事 (YMNNALFT) 的另一个部分!自从2016年以来,我在我的Spring Tips 视频中花费了大量时间阐明(或者至少尝试阐明!)Spring 生态系统中一些更大的机遇。然而,今天,我怀着不同的精神来到这里,希望关注那些功能强大、有时隐藏的宝石,这些宝石可以为您节省额外的第三方依赖项及其隐含的复杂性。

我认为我15年前第一次使用Spring时,用的是JdbcTemplate,它消除了直接使用JDBC的繁琐和冗长的工作。您可能知道,JDBC代表“Just Don't Break, Compiler!”(别让编译器崩溃!),其设计意图是通过提供一个API来测试JVM的每个方法65535字节字节码的限制,该API始终需要比这更多的代码行才能完成一些基本的事情。

顺便提一句,我被告知JDBC实际上是Java数据库连接API。继续…

当时我无法在项目中使用Spring作为一个框架,但我可以将其作为一个库引入。我最初引入它是为了访问JdbcTemplate,以及整体上各种*Template对象的理念。

模板对象是控制反转原则的一个很好的例子。您可以让模板对象完成90%的工作,并为其提供一个回调,在模板需要您输入某些内容时调用。模板反转了应用程序流程;它们完成繁琐的工作,只有在您需要执行您想做的事情时才涉及您。它们有点像迷你框架

JdbcTemplate是Java生态系统中最著名的模板之一,这是有充分理由的。JDBC是Java生态系统中用于处理SQL数据库的低级API。它功能强大,并且已经流行了几十年。但最终,它非常低级。您不会自己编写很多这样的代码。

当时的替代方案是易碎的技术,如Hibernate、Apache OJB、各种略微不兼容的JDO实现、iBatis,或者——天哪!——EJB 1.x或2.x持久实体Bean。大多数这些对于我试图完成的工作来说都过于庞大。我喜欢iBatis(并且继续喜欢它的后继者MyBatis),但我发现我只需JdbcTemplate就能完成很多工作。

JdbcTemplate是用于处理SQL数据库的丰富的类安排和各种抽象的一部分。如今,Spring开发人员甚至可以使用JDBC的非阻塞、反应式替代方案:R2DBC。大多数数据访问逻辑现在都使用JDBC(即使是间接的),因此让我们来看一个例子。

代码如下

package bootiful.data;

import lombok.SneakyThrows;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.util.FileCopyUtils;

import javax.sql.DataSource;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.List;

@SpringBootApplication
public class BootifulApplication {

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

	@Bean
	DataSource dataSource() {
		return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
	}

	@SneakyThrows
	private String loadSql() {
		Resource resource = new ClassPathResource("/initialization.sql");
		try (Reader r = new InputStreamReader(resource.getInputStream())) {
			return FileCopyUtils.copyToString(r);
		}
	}

	@Bean
	ApplicationListener<ApplicationReadyEvent> ready(DataSource dataSource) {
		return event -> {
			String sql = loadSql();
			String[] names = new String[] { "Spencer", "Violetta", "Madhura", "Yuxin", "Stéphane", "Dr. Syer" };
			JdbcTemplate template = new JdbcTemplate(dataSource);
			template.execute(sql);
			for (var name : names) {
				template.update("insert into CUSTOMER(name) values(?)", name);
			}
			List<Customer> results = template.query("select * from CUSTOMER",
					(resultSet, i) -> new Customer(resultSet.getInt("id"), resultSet.getString("name")));
			results.forEach(System.out::println);
		};
	}

}

如果您不介意卷起袖子编写一些SQL(您为什么要介意呢?SQL很棒!),那么您会很乐意使用JdbcTemplate和JDBC模块中的各种命令类。如果不是,Spring会继续以您今天的方式满足您的需求,并为以JDBC为中心的数据访问技术(如JOOQ、Hibernate、JPA、MyBatis、Spring Data JPA、Spring Data JDBC以及许多其他选项)提供丰富的集成。

您喜欢这种一目了然的方法吗?您学到什么了吗?一如既往,我很乐意听到您的意见,所以请在Twitter (@starbuxman) 上发表您的看法! 我将很快推出另一期YMNNALFT,所以请不要错过。

获取Spring通讯

通过Spring通讯保持联系

订阅

领先一步

VMware提供培训和认证,以加快您的进度。

了解更多

获取支持

Tanzu Spring在一个简单的订阅中提供对OpenJDK™、Spring和Apache Tomcat®的支持和二进制文件。

了解更多

即将举行的活动

查看Spring社区中所有即将举行的活动。

查看全部