前言 在现代应用程序开发中,数据访问是至关重要的一环。如何有效地与数据库进行交互直接影响到应用程序的性能和维护性。Spring 框架提供了多种工具来简化和优化数据访问,其中包括 JDBCTemplate、Spring Data JDBC 和 Spring Data JPA。本篇博客将详细介绍这三种工具的区别和适用场景,帮助开发者选择合适的解决方案。
我们用一个栗子来说明这三者的区别:从数据库中通过id查询用户名,这里使用mysql数据库演示,
下面给出了sql代码
1 2 3 4 5 6 7 8 9 10 11 12 create table if not exists user ( id int primary key, name varchar(255) not null, email varchar(255) not null, password varchar(255) not null ); insert into user (id,name, email, password)values (1,'admin1', 'abd@gmail.com', 'abc'); insert into user (id,name, email, password)values (2,'admin2', 'abAasdfd@gmail.com', 'admin'); insert into user (id,name, email, password)values (3,'admin3', 'a123bd@gmail.com', 'admi123n'); insert into user (id,name, email, password)values (5,'admin4', 'abd6245@gmail.com', 'ad1m1in'); insert into user (id,name, email, password)values (8,'admin78', 'a1345bd@gmail.com', 'ad24min');
User类,其中使用了lombok库的@Data标签,可以自动生成set,get以及构造方法。
1 2 3 4 5 6 7 8 9 import lombok.Data;@Data public class User { private int id; private String name; private String email; private String password; }
JDBCTemplate JDBCTemplate 是 Spring 框架提供的一个简化 JDBC 操作的工具类。它封装了复杂的 JDBC 操作,简化了数据库访问。
功能和特点
简化了 JDBC 连接、语句创建、执行和结果集处理
需要手动编写 SQL 查询语句
更细粒度的控制,适用于需要精确控制 SQL 语句和数据库交互的场景
无 ORM 功能,需要手动将结果集转换为对象
使用场景和示例代码(Repo层)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 import org.jdbctemplatedemo.entity.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Repository;@Repository public class UserRepoByTP { private JdbcTemplate jdbcTemplate; @Autowired public UserRepoByTP (JdbcTemplate jdbcTemplate) { this .jdbcTemplate = jdbcTemplate; } public User findById (int id) { return jdbcTemplate.queryForObject("select * from user where id = ?" , new Object []{id}, (rs, rowNum) -> { User user = new User (); user.setId(rs.getInt("id" )); user.setName(rs.getString("name" )); user.setEmail(rs.getString("email" )); user.setPassword(rs.getString("password" )); return user; } ); } }
配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.jdbc.core.JdbcTemplate;import javax.sql.DataSource;@Configuration public class DataSourceConfig { @Autowired private DataSource dataSource; @Bean public JdbcTemplate jdbcTemplate () { return new JdbcTemplate (dataSource); } }
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 import org.jdbctemplatedemo.entity.User;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import static org.junit.jupiter.api.Assertions.assertEquals;import static org.junit.jupiter.api.Assertions.assertNotNull;@SpringBootTest public class UserRepoByTPTests { @Autowired private UserRepoByTP userRepoByTP; @Test public void testFindById () { User user = userRepoByTP.findById(1 ); assertNotNull(user); assertEquals("admin1" , user.getName()); } }
Spring Data JDBC Spring Data JDBC 是 Spring Data 的一部分,旨在简化基于 JDBC 的数据库访问,提供了比 JDBCTemplate 更高层次的抽象。
功能和特点
通过 Repository 接口进行数据操作
自动处理数据库表和实体类之间的映射
较轻量级,没有 JPA 的复杂性和开销
适合性能要求高但不需要复杂功能的场景
使用场景和示例代码(Repo层)
1 2 3 4 5 6 import org.jdbctemplatedemo.entity.User;import org.springframework.data.repository.CrudRepository;public interface UserRepository extends CrudRepository <User, Integer> { }
与 JDBCTemplate 需要手动编写 SQL 不同,Spring Data JDBC 能自动生成数据访问层的实现类。
修改领域类
1 2 3 4 5 6 7 8 9 10 11 12 13 import lombok.Data;import org.springframework.data.annotation.Id;import org.springframework.data.relational.core.mapping.Table;@Data @Table public class User { @Id private int id; private String name; private String email; private String password; }
使用@Id
标签标记唯一标识,使用@Table
注解用于指定实体类与数据库表的映射关系。它通常用于在实体类上标记,指定实体类所对应的数据库表的名称和其他属性。
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import org.jdbctemplatedemo.entity.User;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import java.util.Optional;import static org.junit.jupiter.api.Assertions.assertEquals;import static org.junit.jupiter.api.Assertions.assertNotNull;@SpringBootTest public class UserRepositoryJDBCTests { @Autowired private UserRepository userRepository; @Test public void testFindById () { Optional<User> user = userRepository.findById(1 ); assertNotNull(user); assertEquals("admin1" , user.get().getName()); } }
Spring Data JPA Spring Data JPA 基于 JPA 规范,提供了强大的 ORM 功能,是 Spring Data 的重要组成部分。
功能和特点
完全支持 JPA 规范,提供了丰富的 ORM 功能
通过 Repository 接口进行 CRUD 操作
支持 JPQL、方法名解析查询等复杂查询机制
提供缓存、懒加载、事务管理等高级功能
适用于需要复杂关系映射和高级功能的应用
使用场景和示例代码(Repo层)
1 2 3 4 5 6 import org.jdbctemplatedemo.entity.User;import org.springframework.data.repository.CrudRepository;public interface UserRepository extends CrudRepository <User, Integer> { }
与JDBC的Repo写法一致
修改领域类
1 2 3 4 5 6 7 8 9 10 11 12 13 import jakarta.persistence.Entity;import jakarta.persistence.Id;import lombok.Data;@Data @Entity public class User { @Id private int id; private String name; private String email; private String password; }
这里使用的是@Entity
标签,该注解是 JPA(Java Persistence API)中的一种注解,用于标识一个类是一个 JPA 实体类。实体类是映射到数据库表的对象,它的每个实例对应数据库表中的一行数据。使用 @Entity
注解将一个普通的 Java 类标记为 JPA 实体类,使得 JPA 提供的持久化操作能够管理该类的实例。
这里的@Id
是jakarta.persistence库中的和Spring Data JDBC中不同,需要注意
测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import java.util.Optional;import static org.junit.jupiter.api.Assertions.assertEquals;import static org.junit.jupiter.api.Assertions.assertNotNull;@SpringBootTest public class UserRepoByJPA { @Autowired private UserRepository userRepository; @Test public void testFindById () { Optional<User> user = userRepository.findById(1 ); assertNotNull(user); assertEquals("admin1" , user.get().getName()); } }
比较与选择
JDBCTemplate : 适用于需要精细控制 SQL 语句和数据库交互的场景,如简单查询和更新操作。
Spring Data JDBC : 适用于需要高性能但不需要复杂 ORM 功能的场景,提供了简单易用的 Repository 接口。
Spring Data JPA : 适用于需要复杂关系映射和高级功能的应用,如需要缓存、懒加载和复杂查询的场景。
特性
JDBCTemplate
Spring Data JDBC
Spring Data JPA
SQL 控制
需要手动编写
需要少量 SQL
不需要手动编写
ORM 支持
无
有,但较简单
完整支持
缓存与懒加载
无
无
有
性能
高
较高
相对较低,但提供更多功能
适用场景
精细控制、简单查询
轻量级、高性能需求
复杂关系映射、需要高级功能