从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 新闻合订本
    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

    • Spring 介绍
    • 程序中的耦合
    • IoC 的概念和作用
    • Spring 中的依赖注入
    • 基于注解的 IoC
    • 使用基于 XML 的 IoC 完成单表的 CRUD
    • 使用基于注解的 IoC 完成单表的 CRUD
    • IoC 的纯注解配置
    • Spring 整合 Junit
    • 事务问题
    • 代理模式
    • AOP 的概念和入门
    • 基于注解的 AOP
    • Spring 的 JdbcTemplate
      • JdBCTemplate 介绍
      • 环境准备
      • 引入依赖
      • 创建实体类
      • 入门案例
      • 配置 IoC
      • 配置增删改查
      • JdbcTemplate 在 dao 中的使用
      • 源码
    • JdBCDaoSupport
    • 基于 XML 的 AOP 实现事务控制
    • 基于注解的 AOP 实现事务控制
    • Spring 的事务控制
    • 基于 XML 的声明式事务控制
    • 基于注解的声明式事务控制
    • 纯注解实现事务控制
    • Spring 编程式事务控制
    • Spring5 新特性
  • 主流框架

  • SpringMVC

  • SpringBoot

  • Java
  • Spring
2023-05-08
目录

Spring 的 JdbcTemplate

# 100.Spring 的 JdbcTemplate

JdBCTemplate 是 Spring 框架中提供的一个对象,是对原始 Jdbc API 对象的简单封装。 ‍ ‍

# JdBCTemplate 介绍

Spring 框架为我们提供了很多的操作模板类:

  • 操作关系型数据的:JdbcTemplate、HibernateTemplate
  • 操作 NoSQL 数据库的:RedisTemplate
  • 操作消息队列的:JmsTemplate

需要的依赖: spring-jdbc-5.0.2.RELEASE.jar 、 spring-tx-5.0.2.RELEASE.jar(和事务相关) ‍ 概念图:

持久层总图.jpg

# 环境准备

此时我们可以删掉之前的所有代码,和 pom.xml 文件中的依赖,从头开始搭建

# 引入依赖

‍

  <dependencies>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.0.2.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.27</version>
    </dependency>
</project>
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

# 创建实体类

package com.peterjxl.domain;

import java.io.Serializable;

public class Account implements Serializable {
  
    private Integer id;
    private String name;
    private Float money;
}
1
2
3
4
5
6
7
8
9
10

注:请自行生成 getter 和 setter

# 入门案例

我们直接新建一个 demo 类来演示:

package com.peterjxl.jdbctemplate;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;

/**
 * JdbcTemplate的最基本用法
 */
public class JdBCTemplateDemo1 {
    public static void main(String[] args) {
        // 准备数据源:spring的内置数据源
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
        ds.setUrl("jdbc:mysql:///learnSpring");
        ds.setUsername("learnSpringUser");
        ds.setPassword("learnSpringPassword");

        // 1. 创建JdbcTemplate对象
        JdbcTemplate jt = new JdbcTemplate(ds);

        //2. 执行操作
        jt.execute("insert into account(name, money) values('ddd', 1000)");
    }
}

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

‍ 可以看到能正常 insert 数据。 ‍

# 配置 IoC

新建 bean.xml,配置如下内容:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!-- 配置JdBCTemplate-->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

    <!-- 配置数据源 -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/learnSpring"/>
        <property name="username" value="learnSpringUser"/>
        <property name="password" value="learnSpringPassword"/>
    </bean>
</beans>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

新建一个 demo 类:

package com.peterjxl.jdbctemplate;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * JdbcTemplate的最基本用法
 */
public class JdBCTemplateDemo2 {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);

        jt.execute("insert into account(name, money) values('eee', 1000)");
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

‍

# 配置增删改查

新建一个 demo 类:

package com.peterjxl.jdbctemplate;

import com.peterjxl.domain.Account;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;

import java.util.List;

/**
 * JdbcTemplate的增删改查
 */
public class JdBCTemplateDemo3 {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        JdbcTemplate jt = ac.getBean("jdbcTemplate", JdbcTemplate.class);

        // 保存
        jt.update("insert into account(name, money) values(?, ?)", "fff", 1000f);

        //更新
        jt.update("update account set name=?, money=? where id=?", "test", 100f, 7);

        // 删除
        jt.update("delete from account where id=?", 8);

        // 查询所有
        List<Account> accounts = jt.query("select * from account where money > ?", new AccountRowMapper(), 1000f);
        for (Account account : accounts) {
            System.out.println(account);
        }

        // 查询一个
        List<Account> accounts1 = jt.query("select * from account where id = ?", new AccountRowMapper(), 1);


        // 查询返回一行一列(使用聚合函数,但不加group by子句)
        Long count = jt.queryForObject("select count(*) from account where money > ?", Long.class, 1000f);
    }
}

/**
 * 定义Account的封装策略
 */
class AccountRowMapper implements RowMapper<Account> {

    /**
     * 把结果集中的数据封装到Account中,然后由Spring把每个Account加到集合中
     */
    public Account mapRow(java.sql.ResultSet rs, int rowNum) throws java.sql.SQLException {
        Account account = new Account();
        account.setId(rs.getInt("id"));
        account.setName(rs.getString("name"));
        account.setMoney(rs.getFloat("money"));
        return account;
    }
}
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

query 方法有很多:

‍

我们可以根据返回类型,和参数列表,来确定我们到底用哪个方法。以查询所有为例,可以定位到这两个方法:

public <T> List<T> query(String sql, @Nullable Object[] args, RowMapper<T> rowMapper) 
public <T> List<T> query(String sql, RowMapper<T> rowMapper, @Nullable Object... args)
1
2

这两个方法都可以用,区别在于,第一个方法是任何 Java 版本都可以用,而第二个方法用了可变参数,是 Java5 之后才能用。

queryForObject 方法中,如果想返回 int 类型,可以传入 Integer.class。 ‍

# JdbcTemplate 在 dao 中的使用

在实际开发过程中,我们都是使用三层架构的。

# 新建 dao 接口

package com.peterjxl.dao;
import com.peterjxl.domain.Account;
public interface IAccountDao {
    Account findAccountById(Integer accountId);
    Account findAccountByName(String accountName);
    void updateAccount(Account account);
}
1
2
3
4
5
6
7

# 新增 dao 实现类

package com.peterjxl.dao.impl;

import com.peterjxl.dao.IAccountDao;
import com.peterjxl.domain.Account;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;


/**
 * 账户的持久层实现类
 */
public class AccountDaoImpl implements IAccountDao {

    private JdbcTemplate jdbcTemplate;

    public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }


    @Override
    public Account findAccountById(Integer accountId) {
        List<Account> accounts = jdbcTemplate.query("select * from account where id = ?", new BeanPropertyRowMapper<>(Account.class), accountId);
        return accounts.isEmpty() ? null : accounts.get(0); // 如果accounts为空,返回null,否则返回accounts.get(0)
    }

    @Override
    public Account findAccountByName(String accountName) {
        List<Account> accounts = jdbcTemplate.query("select * from account where name = ?", new BeanPropertyRowMapper<>(Account.class), accountName);
        if (accounts.isEmpty()) {
            return null;
        }
        if (accounts.size() > 1) {
            throw new RuntimeException("结果集不唯一");
        }
        return accounts.get(0);
    }

    @Override
    public void updateAccount(Account account) {
        jdbcTemplate.update("update account set name=?, money=? where id=?", account.getName(), account.getMoney(), account.getId());
    }
}

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

‍

# 配置 bean

<!-- 配置账户的持久层实现类 -->
<bean id="accountDao" class="com.peterjxl.dao.impl.AccountDaoImpl">
    <!-- 注入JdbcTemplate -->
    <property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
1
2
3
4
5

# 新增测试方法

package com.peterjxl.jdbctemplate;

import com.peterjxl.dao.IAccountDao;
import com.peterjxl.domain.Account;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 * JdbcTemplate的最基本用法
 */
public class JdBCTemplateDemo4 {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        IAccountDao accountDao = ac.getBean("accountDao", IAccountDao.class);

        Account account = accountDao.findAccountById(1);
        System.out.println(account);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

‍ 运行结果:

Account{id=1, name='aaa', money=600.0}
1

# 源码

本项目已将源码上传到 GitHub (opens new window) 和 Gitee (opens new window) 上。并且创建了分支 demo13,读者可以通过切换分支来查看本文的示例代码。 ‍

上次更新: 2025/6/3 09:31:54
基于注解的 AOP
JdBCDaoSupport

← 基于注解的 AOP JdBCDaoSupport→

最近更新
01
新闻合订本 2025-10
10-31
02
2025 年 10 月记
10-30
03
用 AI 批量优化思源笔记排版
10-15
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式