领先一步
VMware提供培训和认证,以加快您的进度。
了解更多欢迎来到您可能不需要另一个库来做这件事 (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(即使是间接的),因此让我们来看一个例子。
在Spring Initializr上使用JDBC - org.springframework.boot
: spring-boot-starter-jdbc
在Spring Initializr上使用H2 - com.h2database
: h2
代码如下
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,所以请不要错过。