Spring Data JDBC示例与使用自定义 ID 插入记录

什么是春季数据 JDBC

弹簧数据 JDBC 项目属于弹簧数据系列,并为基于 JDBC 的数据访问层提供抽象。它提供了易于使用的对象关系映射 (ORM) 框架来处理数据库。这意味着,春季数据JDBC支持使用实体对象和存储库。但是,它减少了JPA支持的弹簧数据JPA引入的许多复杂性。

为了使数据访问层尽可能简单,它省略了一些JPA功能,如延迟加载,实体缓存等。因此,它可以毫不费力地用于我们打算对实体执行纯 JDBC 操作的地方。

与任何其他春季项目一样,可以通过添加自己的初学者依赖项,在春季启动中启用春季数据JDBC。

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

或者,如果您正在使用Spring应用程序,则可以像下面一样添加其依赖项。只需确保您使用的是最新版本。

<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-jdbc</artifactId>
    <version>{version}</version>
</dependency>
 

由于它不是休眠支持的JPA实现,因此春季数据JDBC中没有实体。但是,我们可以将任何普通旧 Java 对象 (POJO) 指定为实体,并将其用于存储库。在下一节中,我们将了解如何执行此操作。

春季数据 JDBC 示例

本节介绍春季数据 JDBC 的示例。我们将创建一个 Java POJO 以将其映射到表,并编写一个简单的 CRUD 存储库接口。

创建数据库表

与休眠和 JPA 组合不同,弹簧数据 JDBC 不会自动生成数据库表。因此,我们需要手动创建它们或使用数据.sql文件或 liquibase 来生成数据库架构。

接下来是为我们的示例创建 Student 表的命令。

create table student
(
    student_id bigint auto_increment,
    first_name varchar(20) null,
    last_name  varchar(20) null,
    year       int         null,
    constraint student_id
        unique (student_id)
);

alter table student
    add primary key (student_id);
 

使用POJO 作为实体

如上所述,春季数据JDBC可以将任何POJO映射到数据库表,如果,

  • POJO 的名称与表的名称相同。否则,它将使用@Table批注来引用实际的表名。
  • POJO 有一个主键,该主键注释为@Id
  • POJO 中的所有持久化字段都具有与数据库表列相同的命名。否则,我们可以使用@Column注释来提供列名。

对于我们创建的表,我们将创建一个学生 java bean 并在主键上使用@Id

package com.amitph.spring.tutorials.springdatajdbc.repo;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;

@Data
@Table("student")
public class Student {
    @Id
    private Long studentId;
    private String firstName;
    private String lastName;
    private Integer year;
}
 

由于POJO的名称和数据库表是相同的,我们可以省略@Table注释,这是为了演示目的而添加的。我们使用龙目岛@Data注释来生成默认的获取器和设置器。但是,访问方法和参数化构造函数对于映射到数据库表的 POJO 不是必需的

写入存储库接口

弹簧数据 JDBC 框架支持存储库,就像弹簧数据 JPA 一样。但是,我们很快就会讨论一些差异。此外,它还支持查询方法@Query批注

我们将为学生创建一个存储库界面,这是Crud存储库的子界面。

package com.amitph.spring.tutorials.springdatajdbc.repo;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface StudentRepository extends CrudRepository<Student, Long> {
    List<Student> findByLastName(String lastName);
}
 

Spring Data 动态提供查询方法的实现。此外,如果我们想要分页或排序结果,我们可以使用PagingAndSortingRepository

使用弹簧数据 JDBC 命名查询

为了生成自定义查询,我们可以派生存储库查询方法。但是,如果我们愿意,我们也可以编写本机查询。

需要注意的一点是,与 JPA 不同,春季数据 JDBC 不支持 JPQL 查询。因此,我们需要编写带有@Query注释的数据库本机SQL语句。

接下来是将命名查询与春季数据 JDBC 结合使用的示例。

@Query("select * from student where last_name = :lName")
List<Student> findByLastName(@Param("lName") String lastName);

如示例所示,我们可以使用@Param注释将参数传递给查询。

@Id春季数据 JDBC 中的生成

@Id字段表示实体的主键,它是强制性的。当表的主列自动递增时,序列中的下一个值将用于插入新记录。

因此,当我们将POJO实例传递给方法时,如果repository.save()

  • @ID字段为空 – POJO 作为新记录插入到表中,具有下一个自动递增值。
  • @Id POJO 中的字段不为空 – 该操作被视为 UPDATE,如果在现有记录中找不到给定的主键,则会引发异常。

因此,默认情况下,我们不能使用自定义或预定义的主键插入记录。但是,我们接下来将看到一个解决方法。

使用自定义 ID 插入记录

为了在Spring数据JDBC中插入具有自定义或预定义ID的新记录,我们可以实现持久化接口,这迫使您实现isNew()方法。根据此方法返回的布尔值,该记录将被视为新记录或更新记录。

package com.amitph.spring.tutorials.springdatajdbc.repo;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.domain.Persistable;
import org.springframework.data.relational.core.mapping.Table;

@Data
@Table("student")
public class Student implements Persistable<Long> {
    @Id
    private Long studentId;
    private String firstName;
    private String lastName;
    private Integer year;

    @Transient
    @JsonIgnore
    private Boolean isInsert;

    @Override
    @JsonIgnore
    public Long getId() {
        return studentId;
    }

    @Override
    @JsonIgnore
    public boolean isNew() {
        return isInsert;
    }
}

请注意,我们已将新的布尔标志标记为@Transient。因此,此字段将不会保留在数据库表中。

现在,我们可以插入具有自定义ID的新记录

Student student = new Student();
student.setFirstName("fName");
student.setFirstName("lName");
student.setFirstName("2023");
        
student.setStudentId(123L);
student.setIsInsert(true);
repository.save(student);

请注意,我们将瞬态字段设置为 true。因此,该记录将被视为新记录,并且将入,前提是 Id 值尚不存在。

同样,我们可以通过提供自定义 Id 来更新现有记录

student.setStudentId(123L);
student.setIsInsert(false);
repository.save(student);

总结

本教程详细介绍了春季数据JDBC,这是一个基于JDBC的对象关系映射(ORM)框架。该框架旨在通过减少JPA提供的大多数复杂功能来提供易于使用的轻量级数据访问层。

我们了解到,我们可以使用任何Java POJO映射到数据库表,并使用存储库和查询方法来让Spring Data生成低级查询。此外,我们还介绍了实际示例来理解这些概念。

有关弹簧和弹簧靴的更多信息,请访问弹簧教程。有关所用示例的完整源代码,请访问我们的 Github 存储库

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值