(十三)Spring之JdbcTemplate

news2024/11/16 13:54:56

文章目录

  • 环境
  • 新增、删除与修改数据
    • 新增
    • 修改
    • 删除
  • 查询一个
    • 查询一个对象
    • 查询一个值
  • 查询多个对象
  • 批量操作
    • 批量添加
    • 批量修改
    • 批量删除
  • 使用回调函数
  • 使用德鲁伊连接池

上一篇:(十二)Spring IoC注解式开发

JdbcTemplate是Spring提供的一个JDBC模板类,是对JDBC的封装,简化JDBC代码。
当然,也可以不用,可以让Spring集成其它的ORM框架,例如:MyBatis、Hibernate等。
先使用JdbcTemplate完成增删改查。

环境

数据库表:t_user
请添加图片描述
初始数据:
请添加图片描述
spring6里程碑版本的仓库
依赖:spring context依赖、junit依赖、log4j2依赖
log4j2.xml文件放到类路径下。
使用JdbcTemplate需要再引入spring-jdbc依赖,以及mysql驱动:

	<!--spring jdbc依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>6.0.0-M2</version>
    </dependency>
    <!--mysql依赖-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.30</version>
    </dependency>

准备实体类User:

public class User {
    private Integer id;
    private String loginName;
    private String loginPwd;

    public User() {
    }

    public User(Integer id, String loginName, String loginPwd) {
        this.id = id;
        this.loginName = loginName;
        this.loginPwd = loginPwd;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", loginName='" + loginName + '\'' +
                ", loginPwd='" + loginPwd + '\'' +
                '}';
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }

    public void setLoginPwd(String loginPwd) {
        this.loginPwd = loginPwd;
    }
}

编写Spring配置文件:创建spring.xml
JdbcTemplate是Spring提供好的类,这类的完整类名是:org.springframework.jdbc.core.JdbcTemplate
直接将这个类配置到Spring配置文件中,纳入Bean管理即可。

<?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">
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"></bean>
</beans>

通过源码我们可以看到,JdbcTemplate是继承jdbcAccessor,而jdbcAccessor有一个DataSource属性,这个属性是数据源,连接数据库需要Connection对象,而生成Connection对象是数据源负责的。所以我们需要给JdbcTemplate设置数据源属性。
请添加图片描述

请添加图片描述
所有的数据源都是要实现javax.sql.DataSource接口的。这个数据源可以自己写一个,也可以用写好的,比如:阿里巴巴的德鲁伊连接池,c3p0,dbcp等。我们这里自己先手写一个数据源。
创建数据源MyDataSource,实现DataSource接口,默认实现里面的方法:

public class MyDataSource implements DataSource {

    private String driver;

    private String url;

    private String username;

    private String password;

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public Connection getConnection() throws SQLException {
        Connection connection = null;
        try {
            Class.forName(driver);
            connection = DriverManager.getConnection(url,username,password);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }
}

写完数据源,我们需要把这个数据源传递给JdbcTemplate。因为JdbcTemplate中有一个DataSource属性:

<?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">
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--这里需要数据源,也可以集成其他数据源-->
        <property name="dataSource" ref="myDataSource"/>
    </bean>

    <!--配置自己的数据源-->
    <bean id="myDataSource" class="com.jdbctemplate.bean.MyDataSource">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydbtest"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
</beans>

测试JdbcTemplate是否已设置好:

    @Test
    public void testJdbc(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        System.out.println(jdbcTemplate);
        System.out.println(jdbcTemplate.getDataSource());
    }

请添加图片描述
环境准备完成

新增、删除与修改数据

在JdbcTemplate当中,insert,delete,update语句,都是调用update方法。
update方法两个参数

  • 第一个参数是传sql语句
  • 第二个参数args是可变长参数,有几个问号,传几个值

新增

测试程序:

    @Test
    public void testInsert(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        String sql = "insert into t_user(loginName,loginPwd) values(?,?)";
        int count = jdbcTemplate.update(sql, "张三", "123456");
        System.out.println(count);
    }

请添加图片描述
新增成功,数据改变:
请添加图片描述

修改

测试程序:

    @Test
    public void testUpdate(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        String sql = "update t_user set loginName = ? , loginPwd = ? where id = ?";

        int count = jdbcTemplate.update(sql, "李四", "654321",7);
        System.out.println(count);
    }

请添加图片描述
修改成功,数据改变:
请添加图片描述

删除

测试程序:

    @Test
    public void testDelete(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        String sql = "delete from t_user where id = ?";

        int count = jdbcTemplate.update(sql, 7);
        System.out.println(count);
    }

请添加图片描述
删除成功。数据改变:
请添加图片描述

查询一个

查询一个使用queryForObject方法,三个参数:

  • 第一个参数:sql语句
  • 第二个参数:映射器对象,在构造方法中指定映射的对象类型。
  • 第三个参数:可变长参数,给sql语句的占位符问号传值。

查询一个对象

测试程序:

    @Test
    public void testSelectOne(){

        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);

        String sql = "select * from t_user where id = ?";
        User user = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), 2);
        System.out.println(user);
    }

请添加图片描述

查询一个值

有时候查询是一个值,例如总记录条数:
测试程序:

    @Test
    public void testSelectOneValue(){
        // 获取JdbcTemplate对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        // 执行select
        String sql = "select count(1) from t_user";
        Integer count = jdbcTemplate.queryForObject(sql, int.class); // 这里用Integer.class也可以
        System.out.println("总记录条数:" + count);
    }

请添加图片描述

查询多个对象

查询结构返回多个对象,使用query方法,与queryForObject方法用法差不多,只是query方法的返回值是一个List集合
测试程序:

    @Test
    public void testSelectAll(){
        // 获取JdbcTemplate对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        // 执行select
        String sql = "select * from t_user";
        //查询多个是调用query方法。
        List<User> users = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
        System.out.println(users);
    }

请添加图片描述

批量操作

批量添加、批量修改、批量删除都是使用batchUpdate方法,该方法返回值是一个int集合,表示操作的数据成功与否,有两个参数:

  • 第一个参数:sql语句
  • 第二个参数:需要操作的list集合,主要给问号赋值

批量添加

测试程序:

    @Test
    public void testAddBatch(){
        // 获取JdbcTemplate对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        // 批量添加
        String sql = "insert into t_user(id,loginName,loginPwd) values(?,?,?)";
        //这里需要注意的是问号顺序
        Object[] objs1 = {null, "张三", "123"};
        Object[] objs2 = {null, "李四", "321"};
        Object[] objs3 = {null, "王五", "231"};
        List<Object[]> list = new ArrayList<>();
        list.add(objs1);
        list.add(objs2);
        list.add(objs3);

        int[] count = jdbcTemplate.batchUpdate(sql, list);
        System.out.println(Arrays.toString(count));
    }

请添加图片描述
运行成功,数据改变:
请添加图片描述

批量修改

测试程序:

    @Test
    public void testUpdateBatch(){
        // 获取JdbcTemplate对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        // 批量修改
        String sql = "update t_user set loginName = ?, loginPwd = ? where id = ?";
        //这里需要注意的是问号顺序
        Object[] objs1 = {"张三11", "546", 8};
        Object[] objs2 = {"李四22", "654", 9};
        Object[] objs3 = {"王五33", "456", 10};
        List<Object[]> list = new ArrayList<>();
        list.add(objs1);
        list.add(objs2);
        list.add(objs3);

        int[] count = jdbcTemplate.batchUpdate(sql, list);
        System.out.println(Arrays.toString(count));
    }

请添加图片描述
运行成功,数据改变:
请添加图片描述

批量删除

测试程序:

    @Test
    public void testDeleteBatch(){
        // 获取JdbcTemplate对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        // 批量删除
        String sql = "delete from t_user where id = ?";
        Object[] objs1 = {8};
        Object[] objs2 = {9};
        Object[] objs3 = {10};
        List<Object[]> list = new ArrayList<>();
        list.add(objs1);
        list.add(objs2);
        list.add(objs3);
        int[] count = jdbcTemplate.batchUpdate(sql, list);
        System.out.println(Arrays.toString(count));
    }

请添加图片描述
运行成功,数据改变:请添加图片描述

使用回调函数

如果想参与更加细节的jdbc代码可以使用回调函数
execute方法,两个参数:

  • 第一个:sql语句
  • 第二个:回调接口PreparedStatementCallback,需实现doInPreparedStatement方法

测试成功:

    @Test
    public void testCallback(){
        // 获取JdbcTemplate对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        String sql = "select * from t_user where id = ?";
        User user = jdbcTemplate.execute(sql, new PreparedStatementCallback<User>() {
            @Override
            public User doInPreparedStatement(PreparedStatement ps) throws SQLException, DataAccessException {
                User user = null;
                ps.setInt(1, 1);
                ResultSet rs = ps.executeQuery();
                if (rs.next()) {
                    user = new User();
                    user.setId(rs.getInt("id"));
                    user.setLoginName(rs.getString("loginName"));
                    user.setLoginPwd(rs.getString("loginPwd"));
                }
                return user;
            }
        });
        System.out.println(user);
    }

请添加图片描述

使用德鲁伊连接池

之前数据源是用我们自己写的。也可以使用别人写好的。例如比较牛的德鲁伊连接池。
第一步:引入德鲁伊连接池的依赖。

<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.1.8</version>
</dependency>

第二步:将德鲁伊中的数据源配置到spring配置文件中。和配置我们自己写的一样。
创建一个新的配置文件spring2.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">
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <!--这里需要数据源,也可以集成其他数据源-->
        <property name="dataSource" ref="druidDataSource"/>
    </bean>

    <!--配置德鲁伊数据源-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydbtest"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>
</beans>

测试程序:

    @Test
    public void testSelectAllForDruid(){
        // 获取JdbcTemplate对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring2.xml");
        JdbcTemplate jdbcTemplate = applicationContext.getBean("jdbcTemplate", JdbcTemplate.class);
        
        String sql = "select * from t_user";
        
        List<User> users = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
        System.out.println(users);
    }

运行可以发现使用了INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited(德鲁伊连接池)
请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/30492.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

高阶数据结构:二叉搜索树

本篇主要是在初级数据结构中介绍的二叉树的提升&#xff0c;了解二叉搜索树的特性。 文章目录 一、二叉搜索树的概念二、二叉搜索树操作 1、二叉搜索树的查找2、二叉搜索树的插入3、二叉搜索树的删除三、二叉搜索树的实现四、二叉搜索树的应用五、关于二叉树进阶面试题一、二叉…

大衣哥又有喜事了,孟文豪新作《克什克腾的眼泪》,是给他写的吗

农民歌唱家大衣哥又出新歌啦&#xff01; 就在大衣哥被谷传民起诉不久&#xff0c;互联网上面又传出新消息&#xff0c;继《火火的情怀》之后&#xff0c;大衣哥的新歌《新时代的新农民》&#xff0c;又要和大家见面了。很多人不明白&#xff0c;大衣哥不过是一个农民歌唱家&am…

Java中的反射,枚举和Lambda表达式

一. 反射 1. 反射的概述 2. 反射的使用 反射常用的类 通过反射获取Class对象 获得Class类相关的方法 使用反射创建实例对象 使用反射获取实例对象中的构造方法 通过反射获取实例对象的属性 通过反射获取实例对象的方法 3. 反射的优缺点 二. 枚举 1…

Graalvm 安装和静态编译

文章目录1、下载2、graalvm安装3、native-image工具安装3.1 安装native-image3.2 安装C编译工具4、java编译成二进制exe4.1、普通的java命令行应用4.2、Swing应用编译4.3、使用maven插件静态编译4.4、javafx应用编译1、下载 文件下载&#xff1a;https://www.graalvm.org/down…

[附源码]计算机毕业设计JAVA剧本杀门店管理系统-

[附源码]计算机毕业设计JAVA剧本杀门店管理系统- 项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM myb…

OBS-VirtualCam OBS的虚拟摄像头插件

OBS-VirtualCam 是OBS的一个虚拟摄像头插件&#xff0c;可以将OBS中的内容提供给一个虚拟摄像头&#xff0c;这样其它软件就可以使用这个内容了&#xff0c;这里试试这个插件功能。 1. 下载obs并安装 登录OBS Studio网站&#xff0c;下载windows版&#xff0c; 下载完成后并安装…

栈的基本操作

目录 一、什么是栈&#xff1f; 二、用单链表实现栈 三、用顺序表数组实现栈 一、什么是栈&#xff1f; 栈&#xff08;stack&#xff09;是一个先进后出&#xff08;FILO-First In Last Out&#xff09;的有序列表。 主要方法&#xff1a;入栈&#xff08;push&#xff09;…

SCA算法优化脉冲耦合神经网络的图像自动分割(Matlab代码实现)

&#x1f352;&#x1f352;&#x1f352;欢迎关注&#x1f308;&#x1f308;&#x1f308; &#x1f4dd;个人主页&#xff1a;我爱Matlab &#x1f44d;点赞➕评论➕收藏 养成习惯&#xff08;一键三连&#xff09;&#x1f33b;&#x1f33b;&#x1f33b; &#x1f34c;希…

【C语言】初识指针(终篇)

摸了一手秀发&#xff0c;发现还在~ 目录 1、指针运算 1.1指针加减整数 1.2指针减指针 1.3指针关系运算 2、二级指针 3、指针和数组 4、指针数组 前言&#xff1a; 大家好&#xff0c;我是拳击哥。上一期我们讲到了指针类型&#xff0c;指针的访问步长&#xff0c;野指针…

Redis数据类型总结

文章目录一、5种数据类型二、常用指令汇总三、应用汇总提示&#xff1a;以下是本篇文章正文内容&#xff0c;Redis系列学习将会持续更新 一、5种数据类型 Redis 数据存储格式&#xff1a;  ● redis 自身是一个 Map ,其中所有的数据都是采用 key : value 的形式存储。  ● 数…

如何设计用户体验测试用例

一、 什么是用户体验 UE&#xff1a; User Experience 用户体验。 用户体验是指用户在使用产品过程中的个人主观感受&#xff0c;即用户在使用一个产品之前、使用过程中、使用后的整体感受&#xff0c;包括行为、情感、喜好、生理和心里反应、成就等各个方面。 通俗的讲用户体…

希望所有计算机学生都知道这些宝藏网站

GitHub GitHub是一个面向开源及私有软件项目的托管平台&#xff0c;因为只支持Git作为唯一的版本库格式进行托管&#xff0c;故名GitHub。 作为开源代码库以及版本控制系统&#xff0c;Github拥有超过900万开发者用户。随着越来越多的应用程序转移到了云上&#xff0c;Github已…

数据结构与算法(五) 动态规划

这篇文章来讲动态规划&#xff08;Dynamic Programming&#xff09;&#xff0c;这是一个在面试中很经常出现的题型 1、本质 之前说过&#xff0c;解决算法问题的主流思路就是穷举搜索&#xff0c;即遍历整个搜索空间&#xff0c;找到给定问题的解 只是在某些场景下&#xff…

Python学习 - 异常处理

Python学习 - 语法入门&#xff1a;https://blog.csdn.net/wanzijy/article/details/125287855 Python学习 - 数据类型&#xff1a;https://blog.csdn.net/wanzijy/article/details/125341568 Python学习 - 流程控制&#xff1a;https://blog.csdn.net/wanzijy/article/details…

3dmax网渲云渲染哪个平台费用低?一张图要多少钱多长时间?怎么收费

话说现在的设计师应该没有不知道云渲染的吧&#xff1f;毕竟比起本地渲&#xff0c;云渲染不占本地资源&#xff0c;一次能渲很多张&#xff0c;方便又快捷&#xff0c;有谁不喜欢呢&#xff01;那么这么多的云渲染平台用哪个呢&#xff1f;今天我们就以主流的4个平台为例&…

(STM32)从零开始的RT-Thread之旅--SPI驱动ST7735(4)使用LVGL

上一篇&#xff1a; (STM32)从零开始的RT-Thread之旅--SPI驱动ST7735(3)使用DMA 经过前几章的搭建&#xff0c;底层显示已经没有问题了&#xff0c;现在需要添加上层的库&#xff0c;我选择了比较火的开源GUI库--LVGL。而RT-Thread Studio支持直接添加LVGL代码库的。 在RT-T…

人工智能-4计算机视觉和图像处理01

深度学习简介 机器学习是实现人工智能的一种途径&#xff0c;深度学习是机器学习的一个子集 深度学习相比于机器学习&#xff0c;少了‘手动特征提取’部分&#xff0c;交给网络来处理 深度学习流程&#xff1a;数据输入–训练模型&#xff08;在数据中学习&#xff09;–输出预…

IP请求工具

无缝的 IP 分配和管理 手动将不同子网中的 IP 分配给不同的 IT 管理员&#xff0c;同时遵守配置的不同访问级别可能是一项繁琐的任务。为了简化IP请求和分配的过程&#xff0c;OpUtils为您提供了一个内置的IP请求工具。使用此工具&#xff0c;您的网络管理员不必再等待其 IP 请…

数据库笔记

文章目录01 数据库概述1.1 四个基本概念1.2 数据管理技术的三个阶段1.2.1 人工管理阶段1.2.2 文件系统阶段1.2.3 数据库阶段1.3 数据独立性1.4 数据库的三级模式结构1.4.1 三级模式结构1.4.2 数据库的二级映像与数据独立性02 关系数据库2.1 关系数据结构及形式化定义2.1.1 关系…

论文管理系统(增删查改功能的实现)

目录 一、后端 1.1实体类 1.2paperMapper类 1.3 PaperMapper类 1.4Service层 1.5 Controller层 二、前端 源代码 我们已经实现列表数据了,接下来我们将实现增删查改功能,新增和修改还能够回显 一、后端 1.1实体类 实体类还是我们上一版的列表功能的实现的paper实…