【JDBC系列】- 扩展提升学习

news2025/1/17 0:12:49

扩展提升学习

😄生命不息,写作不止
🔥 继续踏上学习之路,学之分享笔记
👊 总有一天我也能像各位大佬一样
🏆 博客首页   @怒放吧德德  To记录领地
🌝分享学习心得,欢迎指正,大家一起学习成长!

在这里插入图片描述

文章目录

  • 扩展提升学习
    • 简介
    • 1、获取自增长主键回显
      • (1)、操作过程
      • (2)、代码
      • (3)、代码解析
    • 2、批量插入数据优化
      • 优化前
      • 优化后
    • 3、事务
      • 事务的概念
      • 在JDBC中操作事务

简介

上一两篇文章介绍了jdbc的使用过程以及statement与prepareStatement的用法和优缺点,这次就接着来学习一下扩展提升。

1、获取自增长主键回显

在新增数据的时候,如果主键标识是自增,往往会返回本次插入的自增标识。然而JDBC是支持将自增主键返回回来。

(1)、操作过程

其使用流程与之前的并没有什么不同,都是从 注册驱动、建立连接、编写SQL语句、创建preparedStatement对象、发送SQL语句、解析结果集、释放资源 具体流程如下图所示。
在这里插入图片描述

(2)、代码

/**
 * @Author: lyd
 * @Description: 获取自增主键的id回显
 * @Date: 2023/8/12
 */
public class JDBCPSOtherPart {
    @SneakyThrows
    public static void main(String[] args) {
        // 注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 创建连接
        Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/cloud_user", "root", "12356");
        // 编写SQL语句
        String sql = "insert into tb_user(username,address) values(?,?);";
        // 创建preparedStatement
        // 这样并不会返回主键, 要想返回就需要携带另一个参数:Statement.RETURN_GENERATED_KEYS
        PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        // 占位符赋值
        preparedStatement.setObject(1, "lkj");
        preparedStatement.setObject(2, "beijing");
        // 发送sql并获取结果集
        int i = preparedStatement.executeUpdate(); // 返回的是几行受影响
        // 获取存储主键结果集对象/只有主键
        ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
        generatedKeys.next();
        System.out.println("操作成功" + i + "行受影响, 主键id为: " + generatedKeys.getLong(1));
        // 关闭资源
        generatedKeys.close();
        preparedStatement.close();
        connection.close();
    }
}

(3)、代码解析

在上面的示例中,基本的方式是相同的,也是使用executeUpdate()来插入数据,在创建预编译对象的时候,需要在放入sql语句携带另一个参数:Statement.RETURN_GENERATED_KEYS,这个参数告诉JDBC在执行插入语句后返回生成的主键。之后,就可以使用 getGeneratedKeys() 方法获取包含生成的主键值的 ResultSet 对象(这个对象只有一行一列,只是存放主键)。我们先将游标往下移一个位置,然后可以使用 getLong(1) 来获取第一列的自增主键值。

我们可以看一下这个方法,这里官方是有标注这通过Statement.RETURN_GENERATED_KEYS or Statement.NO_GENERATED_KEYS 来判断是否需要返回自增的键值,其返回是一个ResultSet对象。
在这里插入图片描述

2、批量插入数据优化

在现实开发中,肯定会需要需要插入万条以上的数据,在本次学习中,我们采用jdbc进行批量插入。在不优化的情况下,运行起来的时间是需要很久的,性能也会很拉跨。

优化前

在没有优化的时候,我们就是在预编译Statement对象中放入不同的值,并且每次去执行一下sql,这样的执行方式会导致执行时间比较长,性能也比较差,因为每次的插入就需要一次IO,IO次数越多越会导致性能的底下。

核心的代码如下

for (int i = 0; i < 10000; i++) {
    preparedStatement.setObject(1, "batch" + i);
    preparedStatement.setObject(2, "hangzhou");
    // 发送sql并获取结果集
    preparedStatement.executeUpdate();
}

我们看一下运行结果,当运行的时候就需要好久才能够结束,我们可以看到,在执行1万次插入需要执行18.64s。
在这里插入图片描述

优化后

优化前的执行方式就相当于是for循环去执行了1万次插入,在sql语句中,其实批量插入是可以追加的形式,每次数据用","隔开。

INSERT INTO table (column1, column2)
VALUES
    ('value1_1', 'value2_1'),
    ('value1_2', 'value2_2'),
    ('value1_3', 'value2_3'),
    ...;

在使用jdbc也是可以的,JDBC提供了相关方法:addBatch()进行追加和executeBatch()去执行SQL来批量插入,这样的效果就比上面的好,优化前需要执行1万次IO,而采用批量插入就只需要执行1次IO。

for (int i = 0; i < 10000; i++) {
    preparedStatement.setObject(1, "opt" + i);
    preparedStatement.setObject(2, "hunan");
    // 发送sql并获取结果集
    preparedStatement.addBatch(); // 不直接执行插入,追加到后面
}
preparedStatement.executeBatch(); // 批量操作

我们执行一下并且查看一下执行速度。

在这里插入图片描述

然而我们会发现,奇怪了,我已经使用了批量插入,但是执行的时间还是那么久,这到底是为什么呢?别慌,这是因为,在使用批量插入的时候,他是需要一定条件的,首先是我们需要在路径后面追加一个**?rewriteBatchedStatements=true** 代表允许这样的操作。并且还需要注意,在语句后面不能加”;“,否则拼接出来的sql会是错误的。

在这里插入图片描述

我们可以看到,这回执行1万条数据的时间就大大缩短了。从刚开始的18秒多降到1秒都不到。然而在此笔者需要说一下,在日常开发的时候,能尽量减少IO次数的就尽量减少,比如批量删除,也是可以用这样的形式操作。当然减少IO次数的做法是需要因地制宜的。

3、事务

事务的目的是确保数据库在执行过程中始终保持一致性和完整性,即使发生了系统故障或其他问题。

事务的概念

在数据库中,事务通常具有以下四个特性,通常被称为 ACID 特性:

  • 原子性(Atomicity): 事务被视为不可分割的最小工作单位,要么全部成功完成,要么全部失败回滚。即,事务的操作要么全部执行,要么一个都不执行。

  • 一致性(Consistency): 事务在执行前后,数据库从一个一致性状态转换到另一个一致性状态。这意味着事务执行后,数据库的完整性约束仍然得到保持。

  • 隔离性(Isolation): 事务之间是相互隔离的,一个事务的操作不应该对其他事务产生影响。即,每个事务都应该像它是系统中唯一的事务一样。

  • 持久性(Durability): 一旦事务提交成功,其所做的更改将永久保存在数据库中,即使发生系统故障也不会丢失。

事务的使用场景包括数据库中的插入、更新、删除操作,以及需要确保数据一致性的任何操作。通过使用事务,可以确保数据库在任何情况下都能保持数据的正确性和完整性,从而提高数据的可靠性。

在JDBC中操作事务

在jdbc中,我们可以简单的使用事务,首先需要关闭自动提交,在执行SQL后,手动进行提交事务,如果抛出异常就在异常处理进行回滚。

我们可以看一下, 主要的使用方式

try{
	connection.setAutoCommit(false); // 关闭自动提交事务
	// 增删修改的SQL执行
	connection.commit(); // 提交事务
} catch (Exception e) {
	connection.rollback(); // 回滚事务
} finally {
	// 关闭资源
    connection.close();
}

代码如下

/**
 * @Author: lyd
 * @Description: JDBC事务的使用
 * @Date: 2023/8/12
 */
public class JDBCTransaction {
    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            // 注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 创建连接
            connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/cloud_user", "root", "12356");
            // 关闭自动连接
            connection.setAutoCommit(false);
            // 编写SQL语句
            String sql = "insert into tb_user(username,address) values(?,?);";
            // 创建preparedStatement
            // 这样并不会返回主键, 要想返回就需要携带另一个参数:Statement.RETURN_GENERATED_KEYS
            preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            // 占位符赋值
            preparedStatement.setObject(1, "ooo");
            preparedStatement.setObject(2, "beijing");
            if (true) {
                throw new RuntimeException("异常");
            }
            // 发送sql并获取结果集
            int i = preparedStatement.executeUpdate(); // 返回的是几行受影响
            // 获取存储主键结果集对象/只有主键
            ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
            generatedKeys.next();
            System.out.println("操作成功" + i + "行受影响, 主键id为: " + generatedKeys.getLong(1));
            connection.commit(); // 提交事务
        } catch (Exception e) {
            // 事务回滚
            System.out.println("事务回滚");
            try {
                connection.rollback(); // 回滚事务
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
        } finally {
            // 关闭资源
            try {
                preparedStatement.close();
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

坚持学习,冲上顶峰!

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

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

相关文章

Golang 基本常量声明及 iota 使用

文章目录 一、局部常量声明二、全局常量声明三、多行常量定义&#xff0c;值表达式为空时自动继承前一个四、常量声明 - iota 一、局部常量声明 package mainimport "fmt"func main() {//局部常量声明//方式一&#xff1a;主动声明类型const lengthA int 10//方式二…

tomcat设置PermSize

最近tomcat老是报错,查看了日志出现PermGen 内存不够用,重启tomcat后查询使用情况 通过启动参数发现没有设置 PermGen,继续通过jmap查看 jmap -heap 21179 发现99%已使用,而且默认是30.5M,太小了,这里设置成256M 1. 创建setenv.sh文件 在/usr/local/tomcat/bin目录下创建一个…

CDN是什么?CDN的好处

近段时间开组会的时候组内的大佬多次提及CDN这个名词&#xff0c;因为以前没有接触过&#xff0c;所以上网查询后写一篇博客来巩固自己对于CDN的理解 1、什么是CDN CDN的全称是Content Delivery Network&#xff0c;即内容分发网络。其目的是通过在现有的Internet中增加一层新…

Linux命令200例:ls用于列出指定目录下的文件和子目录

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &…

Java实现对称加密(DES,AES)快速入门示例

对称加密是使用相同的密码进行加密和解密&#xff0c; 对称加密实现简单&#xff0c;安全性相比非对称加密较弱&#xff0c; 常用的对称加密算法有 DES&#xff0c;AES以及PDE等&#xff0c;关于对称加密相关概念参考&#xff1a; 对称加密、非对称加密深度解析 本篇介绍Java的…

【CSH 入门基础 5 -- csh 文件监控脚本实现】

文章目录 背景CSHLL 代码实现cshell 中 unset 的介绍bash 中监控文件的方法 背景 由于开发代码是在外网编译&#xff0c;而镜像的烧写是在内网中的EDA工具中进行的&#xff0c;所以就需要先将代码在外网编译好后&#xff0c;再通过FTP工具将镜像传输到内网中&#xff0c;然后在…

MyBatis配置文件:配置连接数据库的环境,实现数据库连接

目录 1、MyBatis配置数据库环境的连接方式 1.1连接方式一&#xff1a;MyBatis核心配置文件配置数据库连接信息 1.2连接方式二&#xff1a;在MyBatis核心配置文件中引入properties文件&#xff0c;配置数据库的环境 2、MyBatisd核心配置文件连接数据库的环境完整配置信息 3…

Win11麦克风说话别人听不见解决办法

Win11麦克风说话别人听不到声音怎么办&#xff1f;麦克风没有声音可能有三种原因造成的&#xff0c;第一种声音设置里面确认麦克风设备是否启用&#xff0c;第二种查看麦克风的访问权限&#xff0c;第三种是检查驱动是否有问题&#xff0c;下面就简单的讲一下解决方法&#xff…

【loadbalancer】还在用Ribbon?试试Spring自带的LoadBalancer吧

Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器, 用来替代Ribbon。 Spring官方提供了两种客户端都可以使用loadbalancer&#xff1a; RestTemplate&#xff1a;Spring提供的用于访问Rest服务的客户端&#xff0c;RestTemplate提供了多种便捷访问远程…

【第二阶段】it关键字

1.invoke&#xff08;&#xff09;函数 meThod1(1,2,3)等价meThod1.invoke(1,2,3) fun main() {val meThod1:(Int,Int,Int)->String{n1,n2,n3->val num"kotlin"println("num$num,n1$n1,n2$n2,,n3$n3")"num$num,n1$n1,n2$n2,,n3$n3,"}//调…

Vue响应式数据的原理

在 vue2 的响应式中&#xff0c;存在着添加属性、删除属性、以及通过下标修改数组&#xff0c;但页面不会自动更新的问题。而这些问题在 vue3 中都得以解决。 vue3 采用了 proxy 代理&#xff0c;用于拦截对象中任意属性的变化&#xff0c;包括&#xff1a;属性的读写、属性的…

前端使用ReadableStream.getReader来处理流式渲染

文章目录 前言一、纯css二、vue-typed-js插件1.安装2.注册3.使用总结 三、ReadableStream1.ReadableStream是什么&#xff1f;2.ReadableStream做什么&#xff1f;3.ReadableStream怎么用 前言 需求&#xff1a;让接口返回的文章根据请求一段一段的渲染&#xff0c;同时可以点击…

Spring MVC视图解析器

Spring MVC视图解析器 ➢ AbstractCachingViewResolver&#xff1a;➢ XmlViewResolver&#xff1a;➢ ResourceBundleViewResolver➢ UrlBasedViewResolver&#xff1a;➢ InternalResourceViewResolver&#xff1a;➢ FreeMarkerViewResolver➢ ContentNegotiatingViewResolv…

OffSec Labs Proving grounds Play——FunboxEasyEnum

文章目录 端口扫描目录扫描文件上传漏洞利用查看用户爆破密码sudo提权flag位置FunboxEasyEnum writeup walkthrough Funbox: EasyEnum ~ VulnHub Enumeration Brute-force the web server’s files and directories. Be sure to check for common file extensions. Remote…

OCR的发明人是谁?

OCR的发明背景可以追溯到早期计算机科学和图像处理的研究。随着计算机技术的不断发展&#xff0c;人们开始探索如何将印刷体文字转换为机器可读的文本。 OCR&#xff08;Optical Character Recognition&#xff0c;光学字符识别&#xff09;的发明涉及多个人的贡献&#xff0c…

布局性能优化:安卓开发者不可错过的性能优化技巧

作者&#xff1a;麦客奥德彪 当我们开发Android应用时&#xff0c;布局性能优化是一个必不可少的过程。一个高效的布局能够提高用户体验&#xff0c;使应用更加流畅、响应更加迅速&#xff0c;而低效的布局则会导致应用的运行变得缓慢&#xff0c;甚至出现卡顿、崩溃等问题&…

植被利用了多少陆地降水?

降水部分被植被利用&#xff0c;部分转化为河水流量。量化植被直接使用的水量对于解读气候变化的影响至关重要。 新提出的模型的预测与之前的结果进行了比较。资料来源&#xff1a;AGU Advances 水是地球的重要组成部分&#xff0c;因此&#xff0c;了解大尺度的水平衡及其建模…

【Rust】Rust学习 第十章泛型、trait 和生命周期

泛型是具体类型或其他属性的抽象替代。我们可以表达泛型的属性&#xff0c;比如他们的行为或如何与其他泛型相关联&#xff0c;而不需要在编写和编译代码时知道他们在这里实际上代表什么。 之后&#xff0c;我们讨论 trait&#xff0c;这是一个定义泛型行为的方法。trait 可以…

Springboot04--vue前端部分+element-ui

注意点&#xff1a; 这边v-model和value的区别&#xff1a;v-model是双向绑定的&#xff0c;value是单向绑定 li的key的问题 vue的组件化开发&#xff1a; 1. NPM&#xff08;类似maven&#xff0c;是管理前段代码的工具&#xff09; 安装完之后可以在cmd里面使用以下指令 2.…

带你认识储存以及数据库新技术演进

01经典案例 1.0 潜在问题 02存储&数据库简介 2.1 存储器层级架构 2.1 数据怎么从应用到存储介质 2.1 RAID技术 2.2 数据库 数据库分为 关系型数据库 和 非关系型数据库 2.2.2 非关系型 2.2.1 关系型 2.3 数据库 vs 经典存储-结构化数据管理 2.3.1 数据库 vs 经典存储-事务能…