Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >芋道 Spring Boot JdbcTemplate 入门

芋道 Spring Boot JdbcTemplate 入门

作者头像
芋道源码
发布于 2019-12-13 10:23:50
发布于 2019-12-13 10:23:50
74300
代码可运行
举报
文章被收录于专栏:芋道源码1024芋道源码1024
运行总次数:0
代码可运行

摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/JdbcTemplate/ 「芋道源码」欢迎转载,保留摘要,谢谢!

  • 1. 概述
  • 2. 快速入门
  • 666. 彩蛋

1. 概述

虽然说,我们现在项目的 DAL 数据访问层,大多使用 MyBatis 或者 JPA ,但是可能极少部分情况下也会使用 JDBC 。而使用的 JDBC 一般来说,一共有 3 种方式:

  • 原生 JDBC ,或者自己项目封装的 JDBC 工具类。
  • Apache Common ,提供了 DbUtils 工具类。
  • Spring JDBC ,提供了 JdbcTemplate 工具类。

因为项目中大多采用了 Spring ,此时艿艿比较推荐使用 Spring JDBC 提供的 JdbcTemplate 。如果没有,推荐使用 Apache Common 提供的 DbUtils 。

咳咳咳,项目实战中,我选择 MyBatis ,哈哈哈。

下面,我们来快速入门 JdbcTemplate 的使用。

2. 快速入门

示例代码对应仓库:lab-14-jdbctemplate 。

本小节,我们会使用 spring-boot-starter-jdbc 自动化配置 JDBC 主要配置。同时,编写相应的 SQL 操作。

2.1 引入依赖

pom.xml 文件中,引入相关依赖。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lab-14-jdbctemplate</artifactId>

    <dependencies>
        <!-- 实现对数据库连接池的自动化配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency> <!-- 本示例,我们使用 MySQL -->
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

        <!-- 方便等会写单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

2.2 Application

创建 Application.java 类,配置 @SpringBootApplication 注解即可。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Application.java

@SpringBootApplication
public class Application {
}

2.3 配置文件

application.yml 中,添加 DataSource 配置,如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
spring:
  # datasource 数据源配置内容
  datasource:
    url: jdbc:mysql://47.112.193.81:3306/testb5f4?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.jdbc.Driver
    username: testb5f4
    password: F4df4db0ed86@11

2.4 UserDO

cn.iocoder.springboot.lab14.jdbctemplate.dataobject 包路径下,创建 UserDO.java 类,用户 DO 。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// UserDO.java

public class UserDO {

    /**
     * 用户编号
     */
    private Integer id;
    /**
     * 账号
     */
    private String username;
    /**
     * 密码(明文)
     *
     * ps:生产环境下,千万不要明文噢
     */
    private String password;
    /**
     * 创建时间
     */
    private Date createTime;

    // ... 省略 setting/getting 方法

}

对应的创建表的 SQL 如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
  `password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

2.5 UserDao

cn.iocoder.springboot.lab14.mybatis.dao 包路径下,创建 UserDao 接口。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// UserDao.java

@Repository
public class UserDao {

    /**
     * 声明 INSERT 操作的 PreparedStatementCreatorFactory 对象
     */
    private static final PreparedStatementCreatorFactory INSERT_PREPARED_STATEMENT_CREATOR_FACTORY
            = new PreparedStatementCreatorFactory("INSERT INTO users(username, password, create_time) VALUES(?, ?, ?)");

    static {
        // 设置返回主键
        INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.setReturnGeneratedKeys(true);
        INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.setGeneratedKeysColumnNames("id");
        // 设置每个占位符的类型
        INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.addParameter(new SqlParameter(Types.VARCHAR));
        INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.addParameter(new SqlParameter(Types.VARCHAR));
        INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.addParameter(new SqlParameter(Types.TIMESTAMP));
    }

    @Autowired
    private JdbcTemplate template;

    /**
     * 使用 PreparedStatementCreator 实现插入数据
     *
     * @param entity 实体
     * @return 影响行数
     */
    public int insert(UserDO entity) {
        // 创建 KeyHolder 对象,设置返回的主键 ID
        KeyHolder keyHolder = new GeneratedKeyHolder();
        // 执行插入操作
        int updateCounts = template.update(INSERT_PREPARED_STATEMENT_CREATOR_FACTORY.newPreparedStatementCreator(
                Arrays.asList(entity.getUsername(), entity.getPassword(), entity.getCreateTime())
        ), keyHolder);
        // 设置 ID 主键到 entity 实体中
        if (keyHolder.getKey() != null) {
            entity.setId(keyHolder.getKey().intValue());
        }
        // 返回影响行数
        return updateCounts;
    }

    /**
     * 使用 SimpleJdbcInsert 实现插入数据
     *
     * @param entity 实体
     * @return 影响行数
     */
    public int insert0(UserDO entity) {
        // 创建 SimpleJdbcInsert 对象
        SimpleJdbcInsert insertOp = new SimpleJdbcInsert(template);
        insertOp.setTableName("users");
        insertOp.setColumnNames(Arrays.asList("username", "password", "create_time"));
        insertOp.setGeneratedKeyName("id");
        // 拼接参数
        Map<String, Object> params = new HashMap<>();
        params.put("username", entity.getUsername());
        params.put("password", entity.getPassword());
        params.put("create_time", entity.getCreateTime());
        // 执行插入操作
        Number id = insertOp.executeAndReturnKey(params);
        // 设置 ID 主键到 entity 实体中
        entity.setId(id.intValue());
        // 返回影响行数
        return 1;
    }

    public int updateById(UserDO entity) {
        // JdbcTemplate 生成更新的动态 SQL 不是很方便,需要自己二次封装。类似 SimpleJdbcInsert 对象
        return template.update("UPDATE users SET password = ? WHERE id = ?", entity.getPassword(),
                entity.getId());
    }

    public int deleteById(Integer id) {
        return template.update("DELETE FROM users WHERE id = ?", id);
    }

    public UserDO selectById(Integer id) {
        return template.queryForObject("SELECT id, username, password, create_time FROM users WHERE id = ?",
                new BeanPropertyRowMapper<>(UserDO.class), // 结果转换成对应的对象
                id);
    }

    public UserDO selectByUsername(String username) {
        return template.queryForObject("SELECT id, username, password, create_time FROM users WHERE username = ? LIMIT 1",
                new BeanPropertyRowMapper<>(UserDO.class), // 结果转换成对应的对象
                username);
    }

    public List<UserDO> selectByIds(List<Integer> ids) {
        // 创建 NamedParameterJdbcTemplate 对象
        NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(template);
        // 拼接参数
        Map<String, Object> params = new HashMap<>();
        params.put("ids", ids);
        // 执行查询
        return namedParameterJdbcTemplate.query(
                "SELECT id, username, password, create_time FROM users WHERE id IN (:ids)", // 使用 :ids 作为占位服务
                params,
                new BeanPropertyRowMapper<>(UserDO.class) // 结果转换成对应的对象
        );
    }

}
  • 具体的每个操作,胖友看下方法名和注释。
  • 虽然说,我们可以在 Service 中使用 JdbcTemplate 进行数据库的操作,但是艿艿还是建议将每个表的操作,分装到对应的 Dao 中。一方面,代码可以更加简洁,另一方面,未来如果替换为 MyBatis 或 JPA 等 ORM 框架时,业务层无需做调整。

2.6 简单测试

创建 UserDaoTest 测试类,我们来测试一下简单的 UserDaoTest 的每个操作。代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// UserDaoTest.java

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class UserDaoTest {

    @Autowired
    private UserDao userDao;

    @Test
    public void testInsert() {
        UserDO user = new UserDO().setUsername(UUID.randomUUID().toString())
                .setPassword("nicai").setCreateTime(new Date());
        userDao.insert(user);
        System.out.println(user);
    }

    @Test
    public void testInsert0() {
        UserDO user = new UserDO().setUsername(UUID.randomUUID().toString())
                .setPassword("nicai").setCreateTime(new Date());
        userDao.insert0(user);
        System.out.println(user);
    }

    @Test
    public void testUpdateById() {
        UserDO updateUser = new UserDO().setId(1)
                .setPassword("wobucai");
        userDao.updateById(updateUser);
    }

    @Test
    public void testDeleteById() {
        userDao.deleteById(2);
    }

    @Test
    public void testSelectById() {
        UserDO user = userDao.selectById(1);
        System.out.println(user);
    }

    @Test
    public void testSelectByUsername() {
        UserDO user = userDao.selectByUsername("yunai");
        System.out.println(user);
    }

    @Test
    public void testSelectByIds() {
        List<UserDO> users = userDao.selectByIds(Arrays.asList(1, 5));
        System.out.println("users:" + users.size());
    }

}

具体的,胖友可以自己跑跑,妥妥的。

666. 彩蛋

虽然说,我们在日常开发中,基本很少在直接接触到 JDBC ,但是 JDBC 在问 们的开发中,无处不在:

  • HikariCP、Druid 在其上,提供了数据库连接池的功能。
  • Sharding Sphere 在其上,提供了分库分表、读写分离等功能。
  • Seata 在其上,提供了分布式事务的功能。
  • Hibernate、MyBatis 在其上,提供了 ORM 的功能。
  • Oracle、MySQL 在其上,提供了不同的 Driver 实现。 Elasticsearch SQL JDBC 在其上,提供了访问 ES 的 Driver 实现。

推荐阅读:

  • 性能测试 —— MySQL 基准测试》
  • 《芋道 Spring Boot 多数据源(读写分离)入门》 对应 lab-17 。
  • 《芋道 Spring Boot 分库分表入门》 对应 lab-18 。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-12-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 芋道源码 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
​精通 Spring Boot 系列文(10)
JdbcTemplate 主要为数据访问提供了模板方案,将数据库存取的工作进行简化。
程序员小猿
2021/01/19
3100
​精通 Spring Boot 系列文(10)
Spring Boot数据持久化之JdbcTemplate
在Java领域,数据持久化有几个常见的方案,有Spring自带的JdbcTemplate、有MyBatis,还有JPA,在这些方案中,最简单的就是Spring自带的JdbcTemplate了,这个东西虽然没有MyBatis那么方便,但是比起最开始的Jdbc已经强了很多了,它没有MyBatis功能那么强大,当然也意味着它的使用比较简单,事实上,JdbcTemplate算是最简单的数据持久化方案了,本文就和大伙来说说这个东西的使用。
江南一点雨
2019/08/30
9300
Spring Boot数据持久化之JdbcTemplate
芋道 Spring Boot MyBatis 入门
艿艿自己在 知识星球 中,做过一个简单的调研,看看大家使用哪个为主。结果是 MyBatis > JPA > JDBC 。这个也符合在知乎上看到的两篇文章:
芋道源码
2020/02/19
1.4K0
芋道 Spring Boot MyBatis 入门(一)之 MyBatis + XML
艿艿自己在 知识星球 中,做过一个简单的调研,看看大家使用哪个为主。结果是 MyBatis > JPA > JDBC 。这个也符合在知乎上看到的两篇文章:
芋道源码
2019/11/09
1.6K0
深入探索:Spring JdbcTemplate的数据库访问之歌
在当今的企业应用程序开发中,与数据库进行交互是至关重要的一环。Spring框架为我们提供了多种方式来简化数据库访问,其中之一就是Spring JdbcTemplate。
繁依Fanyi
2024/05/05
3780
Spring学习笔记 Spring JDBC框架
先来看看一个JDBC的例子。我们可以看到为了执行一条SQL语句,我们需要创建连接,创建语句对象,然后执行SQL,然后操纵结果集获取数据。
乐百川
2022/05/05
9580
芋道 Spring Boot MongoDB 入门
MongoDB 中的许多概念在 MySQL 中具有相近的类比。本表概述了每个系统中的一些常见概念。
芋道源码
2020/04/15
2.7K0
芋道 Spring Boot MongoDB 入门
芋道 Spring Boot MyBatis 入门(三)之 MyBatis-Plus
关于 MyBatis-Plus 的介绍,直接到 https://mybatis.plus/ 官网,艿艿就不多哔哔,嘿嘿。
芋道源码
2019/11/13
1.3K0
芋道 Spring Boot MyBatis 入门(二)之 MyBatis + 注解
大多数情况下,艿艿并不推荐使用注解的方式编写 SQL 。一方面,SQL 无法很好的排版。另一方面,会导致 Mapper 接口很长很乱。
芋道源码
2019/11/11
5490
芋道 Spring Boot 消除冗余代码 Lombok 入门
摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/Lombok/ 「芋道源码」欢迎转载,保留摘要,谢谢!
芋道源码
2020/04/01
1K0
芋道 Spring Boot MyBatis 入门(四)之 tkmybatis
摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/MyBatis/ 「芋道源码」欢迎转载,保留摘要,谢谢!
芋道源码
2019/11/23
2K0
Spring Boot - 构建数据访问层
我们将进入 Spring Boot 另一个核心技术体系的讨论,即数据访问技术体系。无论是互联网应用还是传统软件,对于任何一个系统而言,数据的存储和访问都是不可缺少的。
小小工匠
2021/08/17
8610
Spring Boot -  构建数据访问层
spring jdbctemplate[spring bean]
SpringJDBC可以理解为对于JDBC的封装使用,简化了不少重复代码并减少了SQL错误问题。一、概述在SpringJDBC模块中,所有的类可以被分到四个单独的包:1)core即核心包,它
Java架构师必看
2022/04/02
5370
Spring 全家桶之 Spring Framework 5.3(六)- JdbcTemplate
Spring JDBC Template 是Spring 操作数据库的模块, 基于 JDBC API
RiemannHypothesis
2022/08/19
3070
Spring 全家桶之 Spring Framework 5.3(六)- JdbcTemplate
芋道 Spring Boot 分库分表入门
因为市面上已经非常不错的分库分表的资料,所以艿艿就不在尴尬的瞎哔哔一些内容。推荐阅读两个资料:
芋道源码
2020/04/26
2.2K0
Spring Boot实战:数据库操作
  上篇文章中已经通过一个简单的HelloWorld程序讲解了Spring boot的基本原理和使用。本文主要讲解如何通过spring boot来访问数据库,本文会演示三种方式来访问数据库,第一种是JdbcTemplate,第二种是JPA,第三种是Mybatis。之前已经提到过,本系列会以一个博客系统作为讲解的基础,所以本文会讲解文章的存储和访问(但不包括文章的详情),因为最终的实现是通过MyBatis来完成的,所以,对于JdbcTemplate和JPA只做简单演示,MyBatis部分会完整实现对文章的增删
用户2140019
2018/05/18
1.2K0
spring boot 系列之三:spring boot 整合JdbcTemplate
由此我们发现,spring boot 只是简化了xml的配置麻烦,并没有减少我们java代码的编写量。
全栈程序员站长
2022/07/18
2720
spring boot 系列之三:spring boot 整合JdbcTemplate
从源码到实战之Spring中的JdbcTemplate及策略模式自定义JdbcTemplate实现
3.2 MyResultSetHandler 接口及实现(策略模式)
IT技术小咖
2020/11/03
2.2K0
(9)SpringBoot使用JdbcTemplate访问数据库
   摘要:本文主要讲解SpringBoot使用JdbcTemplate访问数据库。
IT云清
2022/05/07
7390
(9)SpringBoot使用JdbcTemplate访问数据库
芋道 Spring Boot JPA 入门(一)之快速入门
摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/JPA/ 「芋道源码」欢迎转载,保留摘要,谢谢!
芋道源码
2019/11/29
1.5K0
相关推荐
​精通 Spring Boot 系列文(10)
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验