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删除数据
前言
本文来讲解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再关闭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来对数据库进行增删改查的操作了,希望对你有所帮助😊