2311 字
约 7 分钟
1
JdbcTemplate 入门

JdbcTemplate 入门

1. 一句话简介

JdbcTemplate 是 Spring 对传统 JDBC 的最薄一层封装,位于 spring-boot-starter-jdbc 之中。它解决了原生 JDBC 反复写"获取连接、拼 SQL、创建 Statement/ResultSet、逐行取字段、关闭资源、转换异常"的样板代码问题,把连接获取、异常转换、资源释放都交给框架统一处理,开发者只需专注于写 SQL。

本模块 demo-orm-jdbctemplate 展示了它的核心能力:通过 jdbcTemplate.update(...) 执行增删改(返回影响行数),通过 jdbcTemplate.queryForObject(sql, args, new BeanPropertyRowMapper<>(clazz)) 查询单条、jdbcTemplate.query(...) 查询列表,并用 BeanPropertyRowMapper 自动把下划线列名(如 phone_number)映射成驼峰属性(phoneNumber)。模块还基于自定义注解(@Table@Column@Pk@Ignore)+ 反射手写了一个通用 BaseDao,动态拼接 SQL 实现通用 CRUD——这正是 MyBatis-Plus、JPA 这类 ORM 框架的底层原理,用最小的代码量看清"从 SQL 到对象"的完整链路。

核心 API 很简单:update() 管增删改、queryForObject() 管查单条、query()/queryForList() 管查列表,配合参数占位符 ? 天然避免 SQL 注入。

2. 什么时候使用

全流程使用约定:新增实体只须继承 BaseDao<T, P> 并加几个注解即可复用 CRUD,如 UserDao extends BaseDao<User, Long> 仅写了 5 个委托方法就获得了 5 个通用能力,业务类(Dao)几乎不再手写 SQL(本模块用 Hutool 拼 SQL 是为了演示原理,实际常用写法恰是手写的 SQL 字符串)。

  • 适用场景
    • 简单/标准 CRUD 的小型项目:表结构简单、查询不复杂,不需要引入重型 ORM,用 JdbcTemplate 够用且零额外心智负担。
    • 追求极致 SQL 可控性和透明度的团队:SQL 全部手写在代码里或与逻辑紧邻,没有框架的"隐式"行为(无懒加载、无脏检查、无一层层代理),出问题可以直接拿到执行的 SQL 排查,本模块也通过 debug 日志打印了实际 SQL 和参数。
    • 对性能敏感、想绕开 ORM 开销的场景:JdbcTemplate 直连 SQL + 连接池复用连接,没有 ORM 的会话缓存、对象图构建、反射开销,能拿到 JDBC 层面的原始性能。
    • 学习 Spring/JDBC/ORM 底层原理:用它理解事务、RowMapper、连接池如何工作,再去看 JPA/MyBatis 会容易很多,且它能直接嵌入任何用 Spring 的既有系统。
    • 与存储过程、复杂原生 SQL、多表 join、批量写配合:手写 SQL 最自由,动态拼接条件时只需自己用占位符 ? 传参即可,本模块的 findByExample 正是用非 null 字段动态拼 WHERE ... = ? 的高手写法。
  • 不适用/需谨慎
    • 复杂领域模型、有大量关联(一对多/多对多)映射:JdbcTemplate 不提供关系映射,需手写 join 并手动在 Service 层组装对象图;JPA/MyBatis 在这方面更省力。
    • 动态 SQL 多、查询条件随意组合的系统:如后台管理列表的多条件筛选、统计报表。手拼 WHERE 1=1? 很繁琐且易错,MyBatis 的 <if> 动态 SQL 更合适。
    • 希望大幅减少代码量的团队:JdbcTemplate 的 SQL、结果映射、分页都要自己写。MyBatis-Plus/JPA 的方法名派生查询(如 findByName)可省去大量样板。本模块虽用 BaseDao 简化了增删改,但复杂查询仍需手写。
    • 对 SQL 注入不够警惕的团队:JdbcTemplate 本身安全(占位符),但手拼 SQL 时若忘了用 ? 而直接拼接字符串,风险和被写的动态 SQL 一样高,需要编码纪律约束。
    • 需要跨数据库兼容/方言隔离的大型系统:JdbcTemplate 的 SQL 是手写的,换库时需手动改 SQL;JPA 通过方言(Dialect)自动适配,分页等特性更省心。

3. 常见业务场景

  • 标准 RESTful 用户/资源管理:对单张表做增删改查,如"创建用户、按 ID 查用户、更新邮箱和手机号、删除用户、按条件查列表"。本模块 UserController@PostMapping/@PutMapping/@DeleteMapping/@GetMapping 一一对应这 5 个操动作,SQL 只有 INSERT/DELETE/UPDATE/SELECT,JdbcTemplate 的 update/query 恰好全覆盖,是最典型的落地场景。
  • 按对象属性做条件查询(Example 查询):查询条件不固定,"有值就过滤、无值则忽略",如 ?status=1 查启用用户、或空条件查全部。本模块 BaseDao.findByExample 通过 ignoreNull 过滤掉 null 字段、动态拼出的 WHERE 1=1 and status = ? 正是这类场景的模板,直接把一个 User 对象当查询条件容器,代码极简。
  • 账号体系与密码加盐处理:在写入前在 Service 层做业务加工再落库。本模块 UserServiceImpl.save 先用 IdUtil.simpleUUID() 生成随机盐、用 SecureUtil.md5(前缀 + 明文 + salt) 加密,再把密文和盐写库。JdbcTemplate 不越权做任何数据加工,把"加密这种 SQL 管不到的活"干净地留给 Service 层,职责边界清晰。
  • 批量初始化与脚本持久化:在 application.yml 里配 initialization-mode: always + classpath:db/schema.sqldata.sql,应用启动时自动建表、灌测试数据,配合 HikariCP 连接池参数(maximum-pool-sizeconnection-test-query: SELECT 1 FROM DUAL 等)。这适合演示、测试环境,JdbcTemplate + Spring 自动配置让"配数据源 + 跑脚本"几乎零代码。
  • 日志与可观测性增强的调试场景:把执行的 SQL 和参数以 debug 级别打出来(本模块 log.debug("【执行SQL】SQL:{}", sql)),在线下联调、排查慢查询/误删时非常见价值。JdbcTemplate 简单的"一行 SQL 抵一个方法"让这类定位成本远低于 ORM 的隐式操作。

4. 同类技术对比

维度 JdbcTemplate Spring Data JPA (Hibernate) MyBatis / MyBatis-Plus MyBatis-Plus 单独看
抽象层级 最低,直接手写 SQL 最高,注解/方法名派生驱动、近乎零 SQL 中等,XML/注解映射自定义 SQL 高,内置通用 CRUD、ActiveRecord 风格
学习成本 低,会 SQL + JDBC 即可 中,需懂 JPA 规范与 Hibernate 缓存/懒加载 中,需懂 Mapper 映射与动态 SQL 低(对已会 MyBatis 者),对新手中等
SQL 可控性/灵活性 极高,全部手写 低,复杂查询需 @Query 或原生 SQL 高,动态 SQL 是一等公民 高,通用 CRUD + 逻辑删除/乐观锁内置
代码量 多,SQL 与映射均自理 少,继承 Repository 即可 中等,需写 Mapper 接口与 XML 少,继承 IService 即得全套 CRUD
复杂关联/多表映射 弱,需手写 join 与组装 强,@OneToMany/@ManyToMany 自动级联 中,可手写 resultMap 中,需配注解或 XML
性能(常规读写) 高,直连 SQL 无缓存开销 中低,一级缓存/懒加载收益仅在特定场景 中,映射开销小 同 MyBatis
通用 CRUD 内置能力 无,靠自封基类(如本模块 BaseDao 有,Repository 方法名派生 无,需自己写 XML 有,IService + Wrapper 条件构造器
动态 SQL 支持 弱,手拼 ?WHERE 1=1 弱,靠 @Query/Specification 强,<where>/<if>/<foreach> 强,LambdaQueryWrapper
分页 手写 LIMIT 自带 Pageable 需插件 内置分页插件
事务/连接池集成 Spring 自动 Spring Data 自动 Spring 自动 Spring 自动
适用规模 / 定位 小型项目、性能敏感、讲透明度 领域模型驱动、复杂对象模型、跨库 CRUD + 复杂查询并存的企业系统 标准化 CRUD + 快速开发

选型建议

  • 想要 SQL 绝对可控、追求性能、或项目简单只想少引入概念 → 选 JdbcTemplate。它在"一次 SQL 一念之间"的场景(单表 CRUD、存储过程、批量写、与老系统混用)效率最高,也是入门 JDBC 的最优起点。
  • 领域模型复杂、对象间关联多、强调"以对象为中心"的建模与敏捷迭代 → 选 Spring Data JPA。一组一组的 @OneToMany、方法名派生查询能显著减少代码,但代价是更高的抽象层与更深的隐式行为,适合用它换取研发效率的团队。
  • 业务以复杂查询、动态 SQL、多条件筛选、报表为主,且需要精细控制 SQL → 选 MyBatisMyBatis-Plus。企业级后台系统最常落在这条路线,MyBatis-Plus 还额外白送了逻辑删除、乐观锁、分页、代码生成器等加班神器。
  • 综合建议:团队能力与业务形态决定选型——小型/研究型/性能敏感项目用 JdbcTemplate,复杂对象域用 JPA,企业 CRUD + 复杂查询用 MyBatis-Plus。把几个都跑通(本仓库有对应的 demo-orm-mybatisdemo-orm-jpademo-orm-mybatis-plus 模块)再定,是最稳的做法。
JdbcTemplate 入门
http://clxhxhhr.top/posts/489/
作者
clxstart
发布于
2026-09-07
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。