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