• 在 Spring Boot 中使用 Jdbi3 简介


    如果您是 Java 开发人员并且曾经做过任何应用程序开发,那么您很可能会遇到需要为您的应用程序添加持久层的情况。多年来,这意味着包含重型 ORM,例如 Hibernate/JPA 或一些类似的库,以及随之而来的所有怪癖和挑战。一年前,我的一位同事指导我采用Jdbi一种新的(对我而言)处理数据的方法,从那时起我就没有回头。

    Jdbi 舒适地位于 ORM 库和低级JDBC驱动程序之间,作为一个直观、简洁和轻量级的库,可以与您的持久层进行交互。Jdbi 不提供任何实体管理、中介服务或魔术来管理您的数据。此外,它不提供自动查询组合(如来自QueryDSLspring-data-jpa)、类似于 Hibernate 的 DDL 生成,甚至不提供 Java 应用程序服务器标志性的容器管理事务。

    此时,您可能会问自己,“我为什么要牺牲所有这些花哨而有用的功能”?虽然这个问题有很多答案,但有几件事真正吸引了我对 Jdbi 的兴趣,下面重点介绍:

    • Jdbi 有声明式和流畅的 API。两者都非常易于使用,允许您编写干净简洁的代码,并且对引擎盖下实际发生的事情几乎没有想象空间
    • 关闭!我对使用 Hibernate 的最大抱怨之一是连接边界通常被应用程序服务器隐藏。Jdbi 通过使用闭包显式定义连接生命周期的能力完全解决了这个问题
    • 在方便的地方轻松将行和列自动映射到 Bean,但在需要时可以轻松定义自定义行为
    • 使用本机连接、选择和复杂查询,而不是依赖应用程序逻辑(即 Hibernate 使用子选择进行连接)。由于您的数据模型不表示为代码,因此在返回查询结果时您不会受到它的影响。可以轻松构建新的数据视图并将其映射到自定义 bean 中,几乎不费吹灰之力
    • 最后,由于没有中间层来管理您的数据,因此它比许多 ORM 的性能要高得多!

    使用 Jdbi 和 Spring Boot 构建一个简单的应用程序

    下面的小教程将概述一些简单的步骤,让您开始在自己的 spring 项目中使用 Jdbi。这两种工具的功能都非常丰富。本教程将概述如何在 Spring Boot 应用程序中使用 Jdbi3 进行设置,但不会深入探讨每个功能更强大的功能。请继续关注未来的帖子以获取更多信息。

    将 Jdbi 依赖项添加到您的项目

    在开始之前,您需要将几个 Jdbi 依赖项添加到您的pom.xml. 在本教程中,我们将使用我最喜欢的数据库:Postgres。如果您在为此示例创建数据库时需要帮助,可以参考 Postgres 的官方文档

    1. org.springframework.boot
    2. spring-boot-starter-data-jdbc
    3. org.jdbi
    4. jdbi3-core
    5. 3.6.0
    6. org.jdbi
    7. jdbi3-sqlobject
    8. 3.6.0
    9. org.jdbi
    10. jdbi3-postgres
    11. 3.6.0

    添加库是一种轻量级的方式,可以在不向项目添加不必要的依赖spring-boot-starter-data-jdbc项的情况下获得所有方便的 spring-boot 自动配置。DataSource由于Jdbi只是一个包装器,JDBC我们不会添加任何不会使用的东西。

    设置数据源永久链接

    在我们开始使用我们的应用程序之前,我们需要告诉 Spring 数据库的连接信息。实现这一点的最简单方法是在我们的src/main/resources/application.yml. 一般来说,我会硬编码我需要在本地开发的值,application.yml然后提供prod配置文件,或者利用 springs externalized configuration model

    1. spring:
    2. datasource:
    3. # I previously created a "Role" for my postgres database for this tutorial
    4. username: jdbi-example-spring-boot
    5. # When developing locally , I tend not to use passwords for ease of use
    6. password: ""
    7. url: jdbc:postgresql://localhost/jdbi-example-spring-boot
    8. driver-class-name: org.postgresql.Driver

    配置 Jdbi Bean

    我们要让 Jdbi 对应用程序可用,创建一个可以自动装配到任何需要它的服务的 bean。为此,我们可以创建一个新的配置类并注册必要的 bean。

    1. @Configuration
    2. public class JdbiConfiguration {
    3. @Bean
    4. public Jdbi jdbi(DataSource datasource){
    5. return Jdbi.create(dataSource)
    6. .installPlugin(new PostgresPlugin())
    7. .installPlugin(new SqlObjectPlugin());
    8. }
    9. }

    由于spring-boot-starter-data-jdbc不需要自己配置DataSource,而是允许springDataSource直接将之前定义的bean注入到 jdbi()Bean定义方法中。最后,我们创建Jdbibean 并确保初始化正确的插件,以便Jdbi了解 Postgresjsonb使用的特定数据类型和操作(即 Postgres 数据)。

    创建 POJO固定链接

    我们将要创建一个简单的 POJO 来表示我们的数据。需要注意的是,这根本不需要与我们的数据模型对应,但可以包含对我们的需求有用的任何内容,而无需更改数据模型。Jdbi 不会像在 Hibernate 中那样自动生成任何数据模型。请注意,@Data注释来自lombok,这是一个适用于任何 Java 开发人员的方便库!

    1. @Data
    2. public class User {
    3. private Long id;
    4. private String firstName;
    5. private String lastName;
    6. private String phoneNumber
    7. }

    定义一个声明式DAO

    我是 Jdbi 定义持久性交互的声明性方法的忠实粉丝。这种方法使用带有注释组合的接口,然后 Jdbi 可以使用这些接口为您生成 DAO 的实现。通过使用声明性方法,您可以清楚地了解 jdbi 执行代码时究竟发生了什么。

    1. public interface UserDao {
    2. @Transaction
    3. @SqlUpdate("CREATE TABLE IF NOT EXISTS users(id BIGINT NOT NULL PRIMARY KEY, first_name VARCHAR(48), last_name VARCHAR(48), phone_number VARCHAR(48))")
    4. void createUserTable();
    5. @Transaction
    6. @SqlUpdate("INSERT INTO users(id,first_name,last_name,phone_number) VALUES(:id,:firstName,:lastName,:phoneNumber)")
    7. void createUser(@BindBean User user);
    8. @SqlQuery("SELECT * FROM users")
    9. @RegisterBeanMapper(User.class)
    10. List getUsers();
    11. @SqlQuery("SELECT * FROM users WHERE id = :id")
    12. @RegisterBeanMapper(User.class)
    13. User getUser(@Bind("id") Long id);
    14. }

    这里发生了很多事情,但是从注释中很容易准确地理解每种方法试图实现的目标。@Transaction注释告诉 Jdbi 将特定的方法调用包装在事务中。您可以将其他参数传递给此注释以修改事务生命周期,但是对于我们的目的,默认值很好。这两个注解在外观@SqlQUery@SqlUpdate非常相似,都将SQL字符串作为参数,但是它们决定了非常不同的行为。@SqlUpdate用于定义以某种方式更改数据的操作。这可以通过SETINSERT,DELETEALTER 操作。这@SqlQuery另一方面,注解不能以任何方式修改数据,而只能用于检索数据。

    使用 Jdbi,您可以在执行时提供参数化SQL字符串和绑定方法参数SQL。上面演示了两种方法(但是 Jdbi 提供了更多的绑定方法)@Bind@BindBean. 注释将@Bind方法参数映射到 中的特定参数SQL,而@BindBean注释将使用gettersbean 的 将其所有属性绑定到SQL.

    最后,Jdbi 提供了将行(甚至连接行)映射到所需 bean 或原始类型的简单方法。上面的示例使用@RegisterBeanMapper(User.class)注释告诉 Jdbi 使用存在的设置器将返回的行转换为User对象。需要注意的是,这并不User像 Hibernate 那样 Proxy 类,而你返回的对象是一个真正的 POJO。如果您需要更多地控制 bean 的映射方式,Jdbi 提供了许多额外的策略来进行行、列和集合级别的映射。

    设置控制器

    1. @RestController
    2. public class UserController {
    3. private Jdbi jdbi;
    4. public UserController(Jdbi jdbi){
    5. this.jdbi = jdbi;
    6. jdbi.useExtension(UserDao.class,UserDao::createUserTable);
    7. }
    8. @PostMapping("/users")
    9. public User createUser(@RequestBody User user){
    10. user.setId(System.currentTimeMillis());
    11. jdbi.useExtension(UserDao.class, dao -> dao.createUser(user));
    12. return user;
    13. }
    14. @GetMapping("/users")
    15. public List getUsers(){
    16. return jdbi.withExtension(UserDao.class, UserDao::getUsers);
    17. }
    18. @GetMapping("/users/{id}")
    19. public User getUsers(@PathVariable Long id){
    20. return jdbi.withExtension(UserDao.class, dao -> dao.getUser(id));
    21. }
    22. }

    Jdbi在控制器中,我们使用闭包进行交互。在我看来,这是与数据库交互的好方法:它明确定义了连接边界,将持久性逻辑与服务层分开,并保证在闭包之外没有副作用。它清晰、简洁和干净的代码将使您的生活更轻松。

    我们在这里使用了两种特定的方法:withExtensionuseExtension. 这些方法将Dao接口用作“扩展”的参数,然后是闭包的 lambda 函数或方法引用。闭包传递了一个参数,即dao从我们的接口创建的实例。withExtension提供了一种返回值的方法,同时useExtension允许我们简单地对数据库运行一些东西。Jdbi当然提供了其他检索和更新数据的方法,完整的分类请参考官方文档。

    创建您的 Spring Boot 应用程序

    1. @SpringBootApplication
    2. public class JdbiExampleApplication {
    3. public static void main(String[] args) {
    4. SpringApplication.run(JdbiExampleApplication.class, args);
    5. }
    6. }

    测试你的 API

    现在您已经设置好了 Spring 应用程序,您可以对其进行测试了!您可以发出一些简单的 curl 请求,以确保您的 REST-API 已准备就绪。

    创建一个新用户

    1. curl -XPOST -H 'Content-Type: application/json' 'http://localhost:8080/users' -d '{"firstName":"Joe","lastName":"Shmo","phoneNumber":"714-832-2211"}'
    2. {
    3. "id":1589208108922,
    4. "firstName":"Maria",
    5. "lastName":"Magee",
    6. "phoneNumber":"676332415"
    7. }

    检索所有用户

    1. curl 'http://localhost:8080/users'
    2. [
    3. {
    4. "id":1589208108922,
    5. "firstName":"Maria",
    6. "lastName":"Magee",
    7. "phoneNumber":"676332415"
    8. }
    9. ]

    检索单个用户永久链接

    1. curl 'http://localhost:8080/users/1589208108922'
    2. {
    3. "id":1589208108922,
    4. "firstName":"Maria",
    5. "lastName":"Magee",
    6. "phoneNumber":"676332415"
    7. }

    关闭永久链接

    至此,您应该了解如何设置一个简单的 spring-boot 应用程序并Jdbi为持久层供电!如果您有兴趣了解更多有关Jdbi提供的惊人功能的信息,可以查看官方文档。如果您想继续学习,可以在GitHub上找到本教程的所有源代码。

  • 相关阅读:
    22年11月-外包-第四轮面试题
    【LeetCode热题100】接雨水+无重复字符的最长子串+找到字符串中所有字母异位词
    油猴插件(Tampermonkey)的使用教程
    混合精子群优化和万有引力搜索算法 (HSSOGSA)(Matlab完整代码实现)
    Java面试附答案:掌握关键技能,突破面试难题!
    mysql操作
    2023.11.13 信息学日志
    fps透视基础-3分钟快速定位矩阵基址-附3D坐标转屏幕坐标算法
    盘点ERP开发的那点事-业务流和数据流
    C# 第七章『I/O数据流』◆第4节:数据流—FileStream 类
  • 原文地址:https://blog.csdn.net/allway2/article/details/126908712