前言
本文来讲解statement和properstatement的相关用法
上一节的最后一个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再关闭Connection JdbcUtils.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; // 执行sql int 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); // 执行SQL int i = ps.executeUpdate(); System.out.println(i); }catch (Exception e){ e.printStackTrace(); }finally{ // 关闭资源 JdbcUtils.closeResource(ps,conn); } }
四. 总结
到目前为止相信你会使用Statement和PrepareStatement来对数据库进行增删改查的操作了,希望对你有所帮助😊