查看“使用Statement的演示及其弊端”的源代码
←
使用Statement的演示及其弊端
跳到导航
跳到搜索
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看和复制此页面的源代码。
https://www.bilibili.com/video/BV1eJ411c7rf?p=12 === 操作和访问数据库 === * 数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果。其实一个数据库连接就是一个 Socket 连接。 * 在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式: ** Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。 ** PreparedStatement:SQL 语句被编译并存储在此对象中,可以使用此对象多次高效地执行该语句。 ** CallableStatement:用于执行 SQL 存储过程 [[文件:操作和访问数据库 图1.png|无|缩略图|600x600像素]] === 使用 Statement 操作数据表的弊端 === * 通过调用 Connection 对象的 createStatement() 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返回执行结果。 * Statement 接口中定义了下列方法用于执行 SQL 语句:<syntaxhighlight lang="java"> package java.sql; public interface Statement extends Wrapper, AutoCloseable { ResultSet executeQuery(String sql) throws SQLException; int executeUpdate(String sql) throws SQLException; } </syntaxhighlight> *但是使用 Statement 操作数据库存在弊端: **问题1:存在拼串操作,繁琐 **问题2:存在 SQL 注入问题 *SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令,例如:<syntaxhighlight lang="java"> public class Test6 { public static void main(String[] args) { String user = "zhangsan"; String normalSQL = getStatementSQL(user); System.out.println(normalSQL); String injectParam = "zhangsan' or '1'='1"; String injectSQL = getStatementSQL(injectParam); System.out.println(injectSQL); } public static String getStatementSQL(String user) { return "SELECT user, password FROM user_table WHERE user='" + user + "'"; } } </syntaxhighlight><syntaxhighlight lang="console"> SELECT user, password FROM user_table WHERE user='zhangsan' SELECT user, password FROM user_table WHERE user='zhangsan' or '1'='1' </syntaxhighlight> *对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement (从 Statement 扩展而来)取代 Statement 就可以了。 *存在 SQL 注入隐患的代码演示:<syntaxhighlight lang="java"> import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.sql.*; import java.util.Properties; import java.util.Scanner; public class StatementTest { @Test public void testLogin() { Scanner scanner = new Scanner(System.in); System.out.print("请输入用户名:"); String user = scanner.nextLine(); System.out.print("请输入密码:"); /* 当输入密码的字符串是: ' or '1' = '1 * SQL 也会执行并返回数据 * next() 和 nextLine() 的区别:空格也会被next()方法认为是结束输入的字符,所以这里要用 nextLine() */ String password = scanner.nextLine(); String sql = "SELECT user, password from user_table where user = '" + user + "' and password = '" + password + "'"; System.out.printf("\nsql:%s\n", sql); User userInfo = get(sql, User.class); if (userInfo != null) { System.out.println("登录成功"); } else { System.out.println("用户名不存在或密码错误"); } } } </syntaxhighlight>https://github.com/jihch/jdbc/blob/main/src/main/java/io/github/jihch/statement/crud/StatementTest.java === 解决方案 === [[文件:注入Statement解决方案图1.png|无|缩略图|600x600像素]]
返回至
使用Statement的演示及其弊端
。
导航菜单
个人工具
登录
名字空间
页面
讨论
变种
视图
阅读
查看源代码
查看历史
更多
搜索
导航
首页
Spring Boot 2 零基础入门
Spring Cloud
Spring Boot
设计模式之禅
VUE
Vuex
Maven
算法
技能树
Wireshark
IntelliJ IDEA
ElasticSearch
VirtualBox
软考
正则表达式
程序员精讲
软件设计师精讲
初级程序员 历年真题
C
SQL
Java
FFmpeg
Redis
Kafka
MySQL
Spring
Docker
JMeter
Apache
Linux
Windows
Git
ZooKeeper
设计模式
Python
MyBatis
软件
数学
PHP
IntelliJ IDEA
CS基础知识
网络
项目
未分类
MediaWiki
镜像
问题
健身
国债
英语
烹饪
常见术语
MediaWiki帮助
工具
链入页面
相关更改
特殊页面
页面信息