当前位置: 首页 > ds >正文

JDBC对数据的增删改查操作:从Statement到PrepareStatement

目录

一 . Statement简介

二. 通过Statement添加数据

1. 创建表

2. 通过Statement添加数据

a. 获取连接

b. 获取Statement对象

c. 定义SQL语句

d. 执行SQL语句

e. 关闭资源

3. 通过Statement修改数据

 4. 通过Statement删除数据

三. PreparedStatement的使用(重点)

1. 介绍

2. PreparedStatement的预编译

3. 通过PreparedStatement添加数据

4. 通过PreparedStatement修改数据

5. 通过PreparedStatement删除数据


前言

本文来讲解statementproperstatement的相关用法
上一节的最后一个JDBC工具类是非常重要的,要先把它实现了,因为后面会直接调用外面自己写的JDBC工具类
如果还不清楚这个的,就先看上一篇文章
传送门:JDBC连接

个人主页:艺杯羹

一 . Statement简介

作用:用于执行静态SQL语句
Statement接口特点:
用于执行静态 SQL 语句并返回它所生成结果的对象。 由 createStatement 创建,用于发送简单的 SQL 语句(不支持动态绑定
可以使用Statement来实现对数据库的增删改查操作,也就是数据操纵语言DML

注意:
由于Statement对象是一个执行静态SQL语句的对象,所以该对象存在SQL注入风险
后面会专门讲解SQL注入风险是什么。SQL注入会导致数据风险

JDBC中三种Statement对象

  • Statement:用于执行静态 SQL 语句
  • PreparedStatement:用于执行预编译SQL语句
  • CallableStatement:用于执行数据库存储过程

一般用Statement和PreparedStatement(更常用)

二. 通过Statement添加数据

1. 创建表

这里先创建一个表,之后就会使用这个数据库表

create table students (-- 学生 id,自增主键studentid int(11) not null auto_increment,-- 学生姓名,最大长度 30 字符studentname varchar(30) default null,-- 学生年龄studentage int(11) default null,-- 将 studentid 设为主键primary key (studentid)
) engine=InnoDB default charset=utf8mb4;

2. 通过Statement添加数据

因为将要用到Connection(用于连接) 和 Statement(用于执行SQL语句),这两个类都会抛出异常
所以会用到try --- catch来捕获,finally来关闭
因为我们上一节已经实现了JDBC工具类,接下来的操作很多都会用到JDBC工具类

a. 获取连接

connection = JdbcUtils.getConnection();

b. 获取Statement对象

statement = connection.createStatement();

c. 定义SQL语句

-- 如果写字符的话,在SQL中是要加单引号的
-- 所以字符串的写法为:'"zifuchaun1"'
-- 外面是单引号,里面再加双引号表示是字符串
String sql = "insert into students values(default,'"+studentname+"',"+studentage+")";

d. 执行SQL语句

-- 如果sql有结果集返回,那么返回值为true
-- 如果没有结果集返回,则返回false
boolean execute = statement.execute(sql);

e. 关闭资源

-- 使用JDBC工具类来关闭statement和connection
-- 要先关闭statement 后关闭connection
JdbcUtils.closeResource(statement,connection);

 完整代码

public class StatementTest {// 添加用户public void insertStudent(String studentname,int studentage){Connection connection = null;Statement statement = null;try{// 获取Connection对象connection = JdbcUtils.getConnection();// 获取Statement对象statement = connection.createStatement();// 定义需要执行的SQL语句String sql = "insert into users values(default,'"+studentname+"',"+studentage+")";// 执行SQL,返回boolean值,如果sql有结果集返回// 那么返回值为true,如果没有结果集返回,则返回false。boolean execute = statement.execute(sql);System.out.println(execute);}catch(Exception e){e.printStackTrace();}finally{// 关闭资源JdbcUtils.closeResource(statement,connection);}}
}

无数据

执行 

StatementTest ts = new StatementTest();
ts.insertStudent("LuoYi", 18);

3. 通过Statement修改数据

 public void updateStudent(int id,String name,int age){Connection connection = null;Statement statement = null;try{// 获取连接对象connection = JdbcUtils.getConnection();// 获取Statement对象statement = connection.createStatement();// 定义sql语句String sql ="update students set studentname = '"+name+"', studentage = "+age+" where studentid = "+id+"";// 执行sql语句int i = statement.executeUpdate(sql);System.out.println(i);}catch(Exception e){e.printStackTrace();}finally{// 关闭资源// 先关闭statement再关闭ConnectionJdbcUtils.closeResource(statement,connection);}}

执行

StatementTest ts = new StatementTest();
// 将id为1的人,修改名字和年龄
ts.updateStudent(1, "WangSiYa", 16);

回数据库看数据

 4. 通过Statement删除数据

// 通过id来删除元素
public void deleteStudentById(int id){Connection connection =null;Statement statement = null;try{// 获取数据库连接connection = JdbcUtils.getConnection();// 获取Statement对象statement = connection.createStatement();// 定义执行删除语句String sql = "delete from students where studentid="+id;// 执行sqlint i = statement.executeUpdate(sql);System.out.println(i);}catch(Exception e){e.printStackTrace();}finally{// 关闭资源JdbcUtils.closeResource(statement,connection);}}

执行

StatementTest ts = new StatementTest();
ts.deleteStudentById(1);

回DataDrip看结果

三. PreparedStatement的使用(重点)

1. 介绍

Statement 和 PreparedStatement 的用法都是用于执行SQL语句
PreparedStatement具有预编译SQL语句能力因此比 Statement 对象的效率更高
还实现了动态的参数绑定防止了SQL注入
所以后续一般是使用PrepareStatement来执行SQL

PreparedStatement对象的特点总结如下:

PreparedStatement
继承 Statement 接口
效率高
支持动态绑定参数
具备 SQL 预编译能力
可防止 SQL 注入

2. PreparedStatement的预编译

我们一般来执行SQL的时候,一般都是会多次执行某一个语句,所以只会修改里面个别的值
预编译,就会将执行过的SQL操作进行类似备份的操作,那么下次只要修改值就可以,这样效率自然就比没有预编译的Statement要高了
所谓预编译语句就是将这类语句中的值用占位符替代,可以视为将 sql 语句模板化或者说参数化预编译语句的优势在于:一次编译、多次运行省去了解析优化等过程;此外预编译语句能防止 sql 注入
接下来看看,是怎么实现的

3. 通过PreparedStatement添加数据

?:占位符
?是PreparedStatement对象中的绑定参数的占位符。问号的位置是从1开始计数

public class PreparedStatementTest {public void insertStudent(String ame,int age){Connection connection = null;PreparedStatement ps = null;try{// 获取数据库连接connection = JdbcUtils.getConnection();// 定义Sql。?是PreparedStatement对象中的绑定参数的占位符。问号的位置是从1开始计数的String sql = "insert into students values(default,?,?)";// 创建PreparedStatement对象ps = connection.prepareStatement(sql);// 完成参数的绑定ps.setString(1, name);ps.setInt(2, age);// 返回更新的行数int i = ps.executeUpdate();System.out.println(i);}catch(Exception e){e.printStackTrace();}finally{// 关闭资源JdbcUtils.closeResource(ps,connection);}}
}

4. 通过PreparedStatement修改数据

// 根据用户ID修改用户姓名与年龄public void updateUsersById(int id,String name,int age){Connection connection = null;PreparedStatement ps = null;try{// 获取数据库连接对象connection = JdbcUtils.getConnection();// 创建PreparedStatement对象ps = connection.prepareStatement("update students set studentname = ?,studentage=? where studentid = ?");// 参数绑定ps.setString(1,studentname);ps.setInt(2,studentage);ps.setInt(3,studentid);// 执行SQL语句// 返回行数int i = ps.executeUpdate();System.out.println(i);}catch(Exception e){e.printStackTrace();}finally{// 关闭资源JdbcUtils.closeResource(ps,connection);}}

5. 通过PreparedStatement删除数据

// 根据用户ID删除指定用户public void deleteUsersById(int id){Connection conn = null;PreparedStatement ps = null;try{// 获取数据库连接对象conn = JdbcUtils.getConnection();//创建PreparedStatement对象ps = conn.prepareStatement("delete from students where studentid = ? ");// 绑定参数ps.setInt(1,id);// 执行SQLint i = ps.executeUpdate();System.out.println(i);}catch (Exception e){e.printStackTrace();}finally{// 关闭资源JdbcUtils.closeResource(ps,conn);}}

四. 总结

到目前为止相信你会使用Statement和PrepareStatement来对数据库进行增删改查的操作了,希望对你有所帮助😊

http://www.xdnf.cn/news/1074.html

相关文章:

  • Qt开发:软件崩溃时,如何生成dump文件
  • IDEA中如何统一项目名称/复制的项目如何修改根目录名称
  • 利用 SSH 实现 WordPress 网站的全面安全管理
  • 【Web API系列】Web Shared Storage API 深度解析:WindowSharedStorage 接口实战指南
  • 云平台一键部署【DiffSynth-Studio】支持wan2.1视频生成及视频lora训练
  • Rook 部署 Ceph 集群及 Kubernetes 存储对接实战
  • k8s的yaml文件里的volume跟volumeMount的区别
  • 【Qt】控件的理解 和 基础控件 QWidget 属性详解(通俗易懂+附源码+思维导图框架)
  • 鸿蒙生态:鸿蒙生态校园行心得
  • 一文详解Pytorch环境搭建:Mac电脑pip安装Pytorch开发环境
  • docker 国内源和常用命令
  • 大模型面经 | 春招、秋招算法面试常考八股文附答案(四)
  • 乐迪电玩发卡查分与控制面板模块逻辑解析
  • MAC系统下完全卸载Android Studio
  • 组网技术-BGP技术,IS-IS协议,VRRP技术
  • 操作系统之shell实现(下)
  • 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。此 RPC 请求中提供了过多的参数。最多应为 2100。
  • 常用第三方库:dio网络库使用与封装
  • PHP 爬虫如何获取 1688 商品详情(代码示例)
  • 【前端记事】关于electron的入门使用
  • 【C++】vector<bool>特化
  • 外商在国内宣传 活动|发布会|参展 邀请媒体
  • 软件测试之接口测试常见面试
  • 什么是负载均衡?NGINX是如何实现负载均衡的?
  • UML 通信图对象协作:共享汽车系统交互脉络
  • 为什么在TCP层(即传输层)没有解决半包、粘包的问题
  • 技术速递|Agent 模式:对所有用户开放,并支持 MCP
  • 【SF顺丰】顺丰开放平台API对接(注册、API测试篇)
  • V5验证官网滑块验证码WSS协议逆向算法分析
  • vue vite开发时保留console.log打包完后依然想保留某个文件夹下的console.log方便以后的观察