2024.4.11 Thursday
接上文【WEEK7】 【DAY3】JDBC—数据库驱动【中文版】
目录
10.2.statement对象
10.2.1.定义
10.2.1.1.Jdbc中的statement队形用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。
10.2.1.2.Statement对象的executeUpdate方法,用于向数据库发送增、删、改的SQL语句,executeUpdate执行结束后,将会返回一个整数(显示这些增删改语句导致了数据库中几行数据发生了变化)
10.2.2.CRUD操作-create
使用executeUpdate(String sql)方法完成数据添加操作,示例操作:
Statement st = conn.createStatement();
String sql = "insert into user(...) values(...)";
int num = st.executeUpdate(sql);
if(num > 0){
System.out.println("插入成功");
}
10.2.3.CRUD操作-delete
使用executeUpdate(String sql)方法完成数据删除操作,示例操作:
Statement st = conn.createStatement();
String sql = "delete from user where id = 1";
int num = st.executeUpdate(sql);
if(num > 0){
System.out.println("删除成功");
}
10.2.4.CRUD操作-update
使用executeUpdate(String sql)方法完成数据修改操作,示例操作:
Statement st = conn.createStatement();
String sql = "update user set name = '' where name = ''";
int num = st.executeUpdate(sql);
if(num >0){
System.out.println("修改成功");
}
10.2.5.CRUD操作-read
使用executeQuery(String sql)方法完成数据查询操作,示例操作:
Statement st = conn.createStatement();
String sql = "select * from user where id = 1";
ResultSet rs = st.executeQuery(sql);
while(rs.next()){
//根据获取列的数据类型,分别调用re的相应方法映射到java对象中
}
10.2.6.代码实现
10.2.6.1.提取工具类
10.2.6.2.编写增删改的方法:executeUpdate
10.2.6.2.1.增
package lesson.two;
import lesson.two.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestInsert {
public static void main(String[] args){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection(); //获取数据库连接
st = conn.createStatement(); //获得SQL的执行对象
String sql = "INSERT INTO users(`id`,`NAME`,`PASSWORD`,`email`,`birthday`)"+
"VALUES('4','abbk','123456','12345678@qq.com','2020-01-01')";
int i = st.executeUpdate(sql);
if(i > 0){
System.out.println("插入成功");
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
-
运行结果
-
插入数据时报错:权限不够的修改(在navicat中修改)
10.2.6.2.2.删
package lesson.two;
import lesson.two.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestDelete {
public static void main(String[] args){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection(); //获取数据库连接
st = conn.createStatement(); //获得SQL的执行对象
String sql = "DELETE FROM users WHERE id = 4"; //唯一一行有实质性改变的(和TestInsert相比)
int i = st.executeUpdate(sql);
if(i > 0){
System.out.println("删除成功");
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
- 运行结果
10.2.6.2.3.修改
package lesson.two;
import lesson.two.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestUpdate {
public static void main(String[] args){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection(); //获取数据库连接
st = conn.createStatement(); //获得SQL的执行对象
String sql = "UPDATE users SET `NAME` = 'abbk' WHERE id = 1"; //唯一一行有实质性改变的(和TestInsert相比)
int i = st.executeUpdate(sql);
if(i > 0){
System.out.println("修改成功");
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
-
运行结果
-
修改多个参数也只需要修改相应的SQL语句
String sql = "UPDATE users SET `NAME` = 'abbk',`email` = 'abbk.mu' WHERE id = 1"; //修改多个参数
10.2.6.3.查询executeQuery
package lesson.two;
import lesson.two.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestSelect {
public static void main(String[] args){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
st = conn.createStatement();
//SQL
String sql = "SELECT * FROM users WHERE id = 1";
//查询完毕返回的结果集保存在rs中
rs = st.executeQuery(sql);
//打印
while (rs.next()) {
System.out.println(rs.getString("NAME"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
- 结果
10.2.7.SQL注入问题
10.2.7.1.SQL存在漏洞,会被攻击,本质是SQL语句被拼接
10.2.7.2.代码(正常情况下)
package lesson.two;
import lesson.two.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SQL_injection {
public static void main(String[] args){
login("abbk","123456");
}
//登录业务
public static void login(String username, String password){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
st = conn.createStatement();
//SQL
// SELECT * FROM users WHERE `NAME` = 'abbk' AND `PASSWORD` = '123456'要将这句话改成传入参数的形式
// 双引号包围的'只是为了传入的数据被单引号左右包围,以符合SQL语句的语法要求。其余+变量名+的部分语法同java
String sql = "SELECT * FROM users WHERE `NAME` ='" +username+ "' AND `PASSWORD` = '" + password + "'";
//查询完毕返回的结果集保存在rs中
rs = st.executeQuery(sql);
//打印
while (rs.next()) {
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("email"));
System.out.println(rs.getString("password"));
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}
- 输出
10.2.7.3.SQL注入的定义
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。
10.2.7.4.被攻击时只需要修改login的传入参数
(SQL_injection.java文件)
login("'or '1=1 ","'or '1=1 "); //sql 注入
// 本句的目的是让最终的SQL语句变成SELECT * FROM users WHERE `NAME` = ''(为空)or '1=1'(恒成立) AND `PASSWORD` = '(为空)or '1=1'(恒成立)
// 的形式,以便在未知用户名和密码的情况下盗取用户信息
-
输出
-
完整代码:
package lesson.two;
import lesson.two.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class SQL_injection {
public static void main(String[] args){
// login("abbk","123456"); //正常情况下
login("'or '1=1 ","'or '1=1 "); //sql 注入
// 本句的目的是让最终的SQL语句变成SELECT * FROM users WHERE `NAME` = ''(为空)or '1=1'(恒成立) AND `PASSWORD` = '(为空)or '1=1'(恒成立)
// 的形式,以便在未知用户名和密码的情况下盗取用户信息
}
//登录业务
public static void login(String username, String password){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
st = conn.createStatement();
//SQL
// SELECT * FROM users WHERE `NAME` = 'abbk' AND `PASSWORD` = '123456'要将这句话改成传入参数的形式
// 双引号包围的'只是为了传入的数据被单引号左右包围,以符合SQL语句的语法要求。其余+变量名+的部分语法同java
String sql = "SELECT * FROM users WHERE `NAME` ='" +username+ "' AND `PASSWORD` = '" + password + "'";
//查询完毕返回的结果集保存在rs中
rs = st.executeQuery(sql);
//打印
while (rs.next()) {
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("email"));
System.out.println(rs.getString("password"));
System.out.println("===========================");
}
} catch (SQLException e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.release(conn,st,rs);
}
}
}