SpingData-JDBC(看这篇文章就够了,新手入门指引)

news2024/11/17 19:30:26

JdbcTemplate 的基本使用

写在前面:
在这里插入图片描述
当DDL操作时,一般是用execute方法,这也是一种规范吧,这个也可以运行DML但是通常来说我DML操作是需要返回值的,一般就是返回影响的行数。然后这篇文章主要介绍增删改查,因为表格的创建一般已经完成了。

查询

  1. query 方法
  • 描述
    在这里插入图片描述
    从描述我们可以清楚的看到,普通的query 方法执行静态sql,使用的是Statement,如果需要使用PreparedStatement,可以看到还有一个方法query(String, Object[], ResultSetExtractor),只需要将数据参数传为null即可。
  • code demo
    使用ResultSetExtractor是一个函数式接口,每一行在内部进行处理,返回最终的处理结果,这一点与下面的行处理进行对比就可以很直观的看出来。
public List<Foo> demoQuery() {
    List<Foo> result = jdbcTemplate.query("SELECT ID,BAR FROM foo", (rs) -> {
        List<Foo> res = new ArrayList<>();
        while (rs.next()) {
            Long id = rs.getLong(1);
            String bar = rs.getString("BAR");
            Foo foo = new Foo(id, bar);
            res.add(foo);
        }
        return res;
    });
    return result;
}

使用行处理器RowCallbackHandler

public List<Foo> demoQuery() {
    List<Foo> res = new ArrayList<>();
    // 需要传一个行处理器,由于是函数式接口所以可以采用lamda表达式
    jdbcTemplate.query("SELECT ID,BAR FROM foo",(rs) -> {
        // 这里可以将对象进行映射,或者做其它的一些处理
        while (rs.next()) {
            Long id = rs.getLong(1);
            String bar = rs.getString("BAR");
            Foo foo = new Foo(id, bar);
            res.add(foo);
        }
    });
    return res;
}

使用PreparedStatement

正如上面描述所说,上面的两段代码使用的是Statement,下面演示一下PreparedStatement的用法:

public List<Foo> demoQuery1() {
 List<Foo> result = jdbcTemplate.query("SELECT ID,BAR FROM foo WHERE ID IN (?,?,?)" ,new Object[]{2,3,4}, (rs) -> {
     List<Foo> res = new ArrayList<>();
     while (rs.next()) {
         Long id = rs.getLong(1);
         String bar = rs.getString("BAR");
         Foo foo = new Foo(id, bar);
         res.add(foo);
     }
     return res;
 });
 return result;
}

List query(String sql, RowMapper rowMapper) 这个方法就是有一个RowMapper 将数据映射为我们需要的数据,比如映射为一个Map

// ColumnMapRowMapper Spring JDBC 提供的一个实现
// 这里的实现完全和public Map<String, Object> queryForMap(String sql); 这个方法一样,只是这个方法把转换的Mapper 写到了里面
List<Map<String, Object>> resultMap = jdbcTemplate.query("SELECT ID,BAR FROM foo", new ColumnMapRowMapper());

在这里插入图片描述

当然也可以自定义:

// 同样使用lamada 表达式
List<Foo> foos = jdbcTemplate.query("SELECT ID,BAR FROM foo", (rs, rowIndex) -> {
    long id = rs.getLong("ID");
    String bar = rs.getString("BAR");
    Foo foo = new Foo(id, bar);
    return foo;
});

这是第一部分,相当于是对于数据的映射需要我们自己来处理,jdbcTemplate提供了一写其它方法比如queryForObject,queryForLis见(2)
2) 不用自己处理映射关系的方法,也
T queryForObject(String sql, Class requiredType)
List queryForList(String sql, Object[] args, int[] argTypes, Class elementType)
在这里插入图片描述
在这里插入图片描述
可以看到里面都是用了SingleColumnRowMapper,所以这两个方法不太好用,如果列超过了1就会抛出异常,只适合返回一个字段的场景

List<String> foos = jdbcTemplate.queryForList("SELECT BAR FROM foo", String.class);

如果需要映射为对象还是需要用(1)中的方法映射,或者直接使用下面这个方法,返回一个Map的集合:

public List<Map<String, Object>> queryForList(String sql) throws DataAccessException {
	return query(sql, getColumnMapRowMapper());
}

插入

1) 使用update 这一类方法进行插入或更新,文档描述直接写了的
在这里插入图片描述
普通的使用

public Object demoInsert() {
    String sql = "INSERT INTO FOO (ID,BAR) VALUES('100','HHH')";
    // 返回的是插入以后影响的行数
    int update = jdbcTemplate.update(sql);
    return update;
}

预编译SQL

public Object demoInsert() {
     String sql = "INSERT INTO FOO (ID,BAR) VALUES(?,?)";
     // 返回的是插入以后影响的行数
     int update = jdbcTemplate.update(sql, new Object[]{100, "hhh"});
     // 当然也是可以直接写参数的,这种直接写更常用
     int update = jdbcTemplate.update(sql, 200,"mmm");
     return update;
 }

也可以不通过参数列表的形式,而是直接传递一个PreparedStatementSetter

public Object demoInsert() {
    String sql = "INSERT INTO FOO (ID,BAR) VALUES(?,?)";
    Map<String, Object> map = new HashMap<String,Object>(){{
        put("ID", 100);
        put("BAR", "bar");
    }};
    // 返回的是插入以后影响的行数
    int update = jdbcTemplate.update(sql, (ps) -> {
        ps.setObject(1, map.get("ID"));
        ps.setObject(2, map.get("BAR"));
    });
    return update;
}

2)SimpleJdbcInsert 这是包里面提供了一个类也可以做插入的操作,某些场景下可能还是比较方便的
首先我们需要注入将这个bean注入到容器

@Bean
@Autowired
public SimpleJdbcInsert simpleJdbcInsert(JdbcTemplate jdbcTemplate) {
	return new SimpleJdbcInsert(jdbcTemplate)
		 // 这里指定了bean 同时指定了主键自增策略
		.withTableName("FOO").usingGeneratedKeyColumns("ID");
}

插入后返回主键

public Number insertData() {
        Map<String, Object> row = new HashMap<>();
        row.put("bar", "c");
        // 插入后返回主键
        Number number = simpleJdbcInsert.executeAndReturnKey(row);
        return number;
    }

executeAndReturnKey 方法需要的参数是列名和值的map映射集合。

更新

更新用的方法依然是updata这一类函数,返回的同样是受影响的函数

public Object demoUpdate() {
  String sql = "UPDATE  FOO SET BAR = ? WHERE ID = ?";
  // 返回的是插入以后影响的行数
  int update = jdbcTemplate.update(sql, "UP", 2);
  int update = jdbcTemplate.update(sql, new Object[]{2,"up"});
  return update;
}

和插入基本差不多的,也可以像下面这么写:

public Object demoUpdate() {
   String sql = "UPDATE  FOO SET BAR = ? WHERE ID = ?";
   Map<String, Object> map = new HashMap<String,Object>(){{
       put("ID", 2);
       put("BAR", "TTT");
   }};
   // 返回的是插入以后影响的行数
   int update = jdbcTemplate.update(sql, (ps) -> {
       ps.setObject(2, map.get("ID"));
       ps.setObject(1, map.get("BAR"));
   });
   return update;
}

删除

删除操作

public void demoDelete() {
    String sql = "DELETE FROM foo WHERE ID= ?";
    int update = jdbcTemplate.update(sql, 2);
    System.out.println(update);
}

批量

对于批量操作来说,主要是批量更新和批量插入操作。
1)使用

@Bean
@Autowired
public NamedParameterJdbcTemplate namedParameterJdbcTemplate(DataSource dataSource) {
	return new NamedParameterJdbcTemplate(dataSource);
}

插入注入NamedParameterJdbcTemplate 后可以批量插入

@Autowired
private NamedParameterJdbcTemplate namedParameterJdbcTemplate;
List<Foo> list = new ArrayList<>();
        list.add(Foo.builder().id(100L).bar("b-100").build());
        list.add(Foo.builder().id(101L).bar("b-101").build());
        namedParameterJdbcTemplate
                .batchUpdate("INSERT INTO FOO (ID, BAR) VALUES (:id, :bar)",
                        SqlParameterSourceUtils.createBatch(list));

2 使用JdbcTemplate

public void batchInsert() {
       List<Foo> foos = new ArrayList<Foo>(){{
           add(new Foo(100L, "10t0"));
           add(new Foo(200L, "20t0"));
           add(new Foo(300L, "30t0"));
       }};
       jdbcTemplate.batchUpdate("INSERT INTO FOO (ID,BAR) VALUES (?,?)",
               new BatchPreparedStatementSetter() {
                   @Override
                   public void setValues(PreparedStatement ps, int i) throws SQLException {
                       ps.setObject(1, foos.get(i).getId());
                       ps.setObject(2, foos.get(i).getBar());
                   }
                   @Override
                   public int getBatchSize() {
                       return 3;
                   }
               });
}

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

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

相关文章

软考A计划-系统集成项目管理工程师-项目范围管理(四)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff…

Linux服务器网卡流量过高排查

第一种方式&#xff1a;nethogs 1.安装 yum -y install nethogs #nethogs em1 -d 3 监控eth0 并每3s刷新一次 手动安装 wget https://github.com/raboof/nethogs/archive/v0.8.5.tar.gz 依赖包&#xff1a; yum install -y libpcap libpcap-devel 编译&#xff1a; mak…

④数据封装对象(Vo、Bo、Po..)+MySQL视图

1.数据封装对象 VO&#xff08;View Object&#xff09;&#xff1a;视图对象&#xff0c;用于展示层&#xff0c;它的作用是把某个指定页面&#xff08;或组件&#xff09;的所有数据封装起来。 DTO&#xff08;Data Transfer Object&#xff09;&#xff1a;数据传输对象&a…

小黑特种兵重庆行走一天,体验了当地风土人情的leetcode之旅:剑指 Offer II 014. 字符串中的变位词

小黑代码 class Solution:def checkInclusion(self, s1: str, s2: str) -> bool:# 字符串长度n_s1 len(s1)n_s2 len(s2)if n_s1 > n_s2:return False# s1的字符计数字典count_s1 [0] * 26# 窗口计数字典count_window [0] * 26# 寻找初始窗口for i in range(n_s1):co…

SpringBoot(四)SpringBoot搭建简单服务端

通过之前的几篇文章相信大家已经对SpringBoot项目开发有了一个基本的了解。本篇&#xff0c;介绍下如何使用SpringBoot搭建一个简单的服务端&#xff0c;实现一个新用户注册的场景&#xff0c;供前端和移动端去使用。本篇需要你对SpringBoot的starter&#xff0c;mysql&#xf…

Redis概述及安装、使用和管理

文章目录 一、NoSQL非关系型数据库1.NoSQL概述2.关系型数据库和非关系型数据库区别&#xff08;1&#xff09;数据存储方式不同&#xff08;2&#xff09;扩展方式不同&#xff08;3&#xff09;对事务性的支持不同 3.非关系型数据库使用场景 二、Redis概述1.简介2.优点3.Redis…

Learn Mongodb了解DB数据库 ④

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; PHP MYSQL &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f44…

SIMATIC WINCC中实现弹窗跟随鼠标功能(C语言脚本)的具体方法示例

SIMATIC WINCC中实现弹窗跟随鼠标功能(C语言脚本)的具体方法示例 具体C语言脚本可参考以下代码: #include "apdefap.h" //添加的头文件//定义的函数 void OnLButtonDown(char* lpszPictureName, char* lpszObjectName, char

七.错误处理

目录 1、错误处理 1、error一般是处理一些比较低级的错误&#xff0c;不会造成程序中断或者宕机。 2、panic一般是发生了致命的错误时才会被调用&#xff0c;例如数组越界&#xff0c;空指针等等&#xff0c; 2.1 手动调用panic 2.2 数组越界造成panic 2、recover函数 1、…

PaddleSeg中交互式分割EISeg的使用

EISeg(Efficient Interactive Segmentation)是基于飞桨开发的一个高效智能的交互式分割标注软件。它涵盖了通用、人像、遥感、医疗、视频等不同方向的高质量交互式分割模型。另外&#xff0c;将EISeg获取到的标注应用到PaddleSeg提供的其他分割模型进行训练&#xff0c;便可得到…

stm32-iic 时序驱动

数据发送 #include "IIC.h" #include "delay.h"void IIC_Init(void){GPIO_InitTypeDef GPIO_InitStruct;//使能GPIPFRCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//初始GPIGB8 GPIGB9 GPIO_InitStruct.GPIO_Pin GPIO_Pin_8 | GPIO_Pin_9; …

4.28 白噪声功率谱密度的估计

前一节有下面结论&#xff1a; 什么仿真的白噪声波形是均匀的&#xff0c;均匀的特点是相关函数在0时刻是相关的&#xff08;自己和自己相关的&#xff09;0以外时刻都互相不相关

PLC 网关设备如何进行数据采集?

引言&#xff1a; 在现代工业领域&#xff0c;PLC&#xff08;可编程逻辑控制器&#xff09;被广泛应用于自动化控制系统。为了实现高效的数据收集和分析&#xff0c;工业边缘网关扮演着重要角色。本文将探讨PLC网关设备如何进行数据采集&#xff0c;并介绍一款优秀的工业边缘网…

JVM-jvisualvm性能监控可视化工具使用与eden-s0-s1分配分析(三)

目录 第一步&#xff1a;安装jvisualvm 第二步&#xff1a;安装VisualvmGc插件 方式一&#xff1a;jvisualvm工具直接下载安装 方式二&#xff1a;去官网下载导入安装 总结 第三步&#xff1a;idea安装VisualvM Launcher插件 第四步&#xff1a;演示young中eden、s0、s1垃…

浅谈小程序开发 [2018年]

一、问题背景 随着App市场趋近于饱和&#xff0c;大部分用户已经养成了使用习惯&#xff0c;加上开发和推广新的App的成本高&#xff0c;使得开发新的App很难在市场上生存。在此背景下&#xff0c;小程序应运而生&#xff0c;2016年&#xff0c;张小龙的微信团队首次推出了微信…

vmware虚拟机无法启动修复

虚拟机场景报错&#xff1a;Entering emergency mode. Exit the shell to continue. #输入journalctl journalctl #如果出现以下描述&#xff1a; failed to mount /sysroot. Dependency failed for Initrd root File System. Dependency failed for Reload configuration fro…

信息服务上线渗透检测网络安全检查报告和解决方案4(网站风险等级评定标准、漏洞危害分级标准、漏洞安全建议)

系列文章目录 信息服务上线渗透检测网络安全检查报告和解决方案3(系统漏洞扫描、相对路径覆盖RPO漏洞、nginx漏洞修复)信息服务上线渗透检测网络安全检查报告和解决方案2(安装文件信息泄漏、管理路径泄漏、XSS漏洞、弱口令、逻辑漏洞、终极上传漏洞升级)信息服务上线渗透检测网…

CCF-CSP真题《202303-2 垦田计划》思路+python,c++满分题解

想查看其他题的真题及题解的同学可以前往查看&#xff1a;CCF-CSP真题附题解大全 试题编号&#xff1a;202303-2试题名称&#xff1a;垦田计划时间限制&#xff1a;1.0s内存限制&#xff1a;512.0MB问题描述&#xff1a; 问题描述 顿顿总共选中了 n 块区域准备开垦田地&#xf…

交换机是否会梦见机器学习?面向网络内分类

交换机是否会梦见机器学习&#xff1f;面向网络内分类 摘要 机器学习目前正在推动技术和社会革命。虽然可编程交换机已被证明对网络内计算非常有用&#xff0c;但是在可编程交换机内进行机器学习迄今为止取得了很少的成功。不利用网络设备进行机器学习会付出高昂的代价&#…

华为OD机试真题 JavaScript 实现【寻找峰值】【牛客练习题】

一、题目描述 给定一个长度为n的数组nums&#xff0c;请你找到峰值并返回其索引。数组可能包含多个峰值&#xff0c;在这种情况下&#xff0c;返回任何一个所在位置即可。 1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于&#xff1b; 2.假设 nums[-1] n…