Java学习笔记47(JDBC、SQL注入攻击原理以及解决)
JDBC:java的数据库连接
JDBC本质是一套API,由开发公司定义的类和接口
这里使用mysql驱动,是一套类库,实现了接口
驱动程序类库,实现接口重写方法,由驱动程序操作数据库
JDBC操作步骤:
1.注册驱动
2.获得连接
3.获得语句执行平台
4.执行sql语句
5.处理结果
6.释放资源
1.导入jar包,可以在网上下载到,这里使用的是:mysql-connector-java-5.1.37-bin.jar
注册驱动:
package demo; import java.sql.DriverManager;
import java.sql.SQLException; import com.mysql.jdbc.Driver; public class JDBCDemo {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//注册驱动
//DriverManager.registerDriver(new Driver());
//不推荐上边这种方法,建议用反射技术,将驱动类加入内存
Class.forName("com.mysql.jdbc.Driver");
}
}
2.获得连接:
package demo; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; public class JDBCDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
//获得数据库连接
String url = "jdbc:mysql://localhost:3306/mybase";
String username = "root";
String password = "xuyiqing";
Connection con = DriverManager.getConnection(url,username,password);
System.out.println(con);
}
}
3.获取语句执行平台
通过数据库连接对象,获取到sql语句的执行者对象
package demo; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement; public class JDBCDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mybase";
String username = "root";
String password = "xuyiqing";
Connection con = DriverManager.getConnection(url,username,password);
//获取语句执行平台
Statement stat = con.createStatement();
System.out.println(stat);
}
}
4.执行sql语句:
准备数据:
CREATE TABLE sort(
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(100),
sprice DOUBLE,
sdesc VARCHAR(5000)
);
INSERT INTO sort(sname,sprice,sdesc) VALUES('家电',2000,'促销'),
('家具',8900,'价格上涨'),
('玩具',300,'赚钱'),
('生鲜',500.99,'促销'),
('服装',24000,'促销'),
('洗涤',50,'促销'); SELECT * FROM sort;
执行sql语句:
1.增删改
package demo; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement; public class JDBCDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mybase";
String username = "root";
String password = "xuyiqing";
Connection con = DriverManager.getConnection(url,username,password);
Statement stat = con.createStatement();
//执行sql语句
//这种方法注意:只能使用insert,delete,update语句
int row = stat.executeUpdate("INSERT INTO sort(sname,sprice,sdesc) VALUES('汽车',2000,'促销');");
System.out.println(row);
//释放资源
stat.close();
con.close();
}
}
2.查询
package demo; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement; public class JDBCDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mybase";
String username = "root";
String password = "xuyiqing";
Connection con = DriverManager.getConnection(url,username,password);
Statement stat = con.createStatement();
//查询sql语句
String sql= "SELECT * FROM sort";
//这个方法用于执行sql中的select查询
ResultSet rs = stat.executeQuery(sql);
//处理结果集
while(rs.next()){
//获取每列数据
System.out.println(rs.getInt("sid")+" "+rs.getString("sname")+
" "+rs.getDouble("sprice")+" "+rs.getString("sdesc"));
}
rs.close();
stat.close();
con.close();
}
}
输出:

SQL注入攻击简单案例:
CREATE TABLE users(
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100),
PASSWORD VARCHAR(100)
); INSERT INTO users (username,PASSWORD) VALUES ('a',''),('b','');
package demo; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner; /*
* Java程序实现用户登录,用户名和密码,数据库检查
* 演示被别人注入攻击
*/
public class JDBCDemo {
public static void main(String[] args)throws Exception {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mybase";
String username = "root";
String password = "xuyiqing";
Connection con = DriverManager.getConnection(url, username, password);
Statement stat = con.createStatement(); Scanner sc = new Scanner(System.in);
String user = sc.nextLine();
String pass = sc.nextLine(); //执行SQL语句,数据表,查询用户名和密码,如果存在,登录成功,不存在登录失败
String sql = "SELECT * FROM users WHERE username='"+user+"' AND PASSWORD='"+pass+"'";
System.out.println(sql);
ResultSet rs = stat.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getString("username")+" "+rs.getString("password"));
} rs.close();
stat.close();
con.close();
}
}
正常情况,必须输入a,1或者b,2才可以登录成功

这里如果这样输入:
1=1恒成立,or两边只要有一边成立就会成功,这里就实现了最简单的sql注入攻击
解决:
使用PrepareStatement接口
package demo; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner; /*
* Java程序实现用户登录,用户名和密码,数据库检查
* 防止注入攻击
* Statement接口实现类,作用执行SQL语句,返回结果集
* 有一个子接口PreparedStatement (SQL预编译存储,多次高效的执行SQL)
* PreparedStatement的实现类数据库的驱动中,如何获取接口的实现类
*
* 是Connection数据库连接对象的方法
* PreparedStatement prepareStatement(String sql) */
public class JDBCDemo {
public static void main(String[] args)throws Exception {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mybase";
String username = "root";
String password = "xuyiqing";
Connection con = DriverManager.getConnection(url, username, password);
Scanner sc = new Scanner(System.in);
String user = sc.nextLine();
String pass = sc.nextLine(); //执行SQL语句,数据表,查询用户名和密码,如果存在,登录成功,不存在登录失败
String sql = "SELECT * FROM users WHERE username=? AND PASSWORD=?";
//调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类
//方法中参数,SQL语句中的参数全部采用问号占位符
PreparedStatement pst = con.prepareStatement(sql);
System.out.println(pst);
//调用pst对象set方法,设置问号占位符上的参数
pst.setObject(1, user);
pst.setObject(2, pass); //调用方法,执行SQL,获取结果集
ResultSet rs = pst.executeQuery();
while(rs.next()){
System.out.println(rs.getString("username")+" "+rs.getString("password"));
} rs.close();
pst.close();
con.close();
}
}
发现这个接口更安全,所以建议使用这个接口实现增删改查
使用PrepareStatement接口,实现数据表的更新操作
package demo; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement; /*
* 使用PrepareStatement接口,实现数据表的更新操作
*/
public class JDBCDemo {
public static void main(String[] args) throws Exception{
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mybase";
String username="root";
String password="xuyiqing";
Connection con = DriverManager.getConnection(url, username, password); //拼写修改的SQL语句,参数采用?占位
String sql = "UPDATE sort SET sname=?,sprice=? WHERE sid=?";
//调用数据库连接对象con的方法prepareStatement获取SQL语句的预编译对象
PreparedStatement pst = con.prepareStatement(sql);
//调用pst的方法setXXX设置?占位
pst.setObject(1, "车");
pst.setObject(2, 49988);
pst.setObject(3, 7);
//调用pst方法执行SQL语句
pst.executeUpdate(); pst.close();
con.close();
}
}
PrepareStatement接口实现数据表的查询操作
package demo; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet; /*
* PrepareStatement接口实现数据表的查询操作
*/
public class JDBCDemo {
public static void main(String[] args) throws Exception{
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/mybase";
String username="root";
String password="xuyiqing";
Connection con = DriverManager.getConnection(url, username, password); String sql = "SELECT * FROM sort"; PreparedStatement pst = con.prepareStatement(sql); //调用pst对象的方法,执行查询语句,Select
ResultSet rs=pst.executeQuery();
while(rs.next()){
System.out.println(rs.getString("sid")+" "+rs.getString("sname")+" "+rs.getString("sprice")+" "+rs.getString("sdesc"));
}
rs.close();
pst.close();
con.close();
}
}
Java学习笔记47(JDBC、SQL注入攻击原理以及解决)的更多相关文章
- java学习笔记38(sql注入攻击及解决方法)
上一篇我们写了jdbc工具类:JDBCUtils ,在这里我们使用该工具类来连接数据库, 在之前我们使用 Statement接口下的executeQuery(sql)方法来执行搜索语句,但是这个接口并 ...
- Java应用开发中的SQL注入攻击
1. 什么是SQL注入攻击? SQL注入攻击是黑客对数据库进行攻击的常用手段之一.随着B/S模式应用开发的发展,使用这种模式编写应用程序的程序员越来越多.但是由于程序员的水平及经验参差不齐,相当一部分 ...
- 10.1(java学习笔记)JDBC基本操作(连接,执行SQL语句,获取结果集)
一.JDBC JDBC的全称是java database connection java数据库连接. 在java中需要对数据库进行一系列的操作,这时就需要使用JDBC. sun公司制定了关于数据库操作 ...
- java学习笔记39(sql事物)
在之前的学习中,我们学习了使用PreparedStatement类,使用这个类消除了sql注入的隐患,可是,还有些一些其他的隐患,这里以银行转账业务为例, 假设 一个银行,张三在里面存了1000元, ...
- 【荐】PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项
我们都知道,只要合理正确使用PDO,可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_connect? 为何PDO能防注入? 使用PDO防注入的时候应该特 ...
- PDO防 SQL注入攻击 原理分析 以及 使用PDO的注意事项
我们都知道,只要合理正确使用PDO(PDO一是PHP数据对象(PHP Data Object)的缩写),可以基本上防止SQL注入的产生,本文主要回答以下几个问题: 为什么要使用PDO而不是mysql_ ...
- java学习笔记37(sql工具类:JDBCUtils)
在之前的内容中,我们发现,当我们执行一条语句时,每新建一个方法,就要重新连接一次数据库,代码重复率很高,那么能不能把这些重复代码封装成一个类呢,我们学习方法时,就学习到方法就是为了提高代码的利用率,所 ...
- 10.3(Java学习笔记)JDBC时间操作
一.时间分类 数据库 java类 Date ---- java.sql.Date 表示日期 yyyy-MM--dd (年月日) Time ----java.sql.Time 表示 ...
- 10.2(java学习笔记)JDBC事务简述
一.事务 事务是指作为一系列操作组成的一个整体,该整体只有两种状态,要么全部执行,要么全部不执行. 当组成这个事务的所有语句都执行成功则该事务执行,只要有一条语句执行失败则该事务不执行. 假设这里有一 ...
随机推荐
- mac下安装cnpm淘宝镜像
cnpm:官网 (事先已经安装了node,有npm)查看官网,提示安装需运行命令:npm install -g cnpm --registry=https://registry.npm.taobao. ...
- SQL Server中多表连接时驱动顺序对性能的影响
本文出处:http://www.cnblogs.com/wy123/p/7106861.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...
- Xpath延伸以及总结
- Linux下,如何查看磁盘是否包含数据
可以使用lquerypv -h来查看磁盘是否包含数据,或磁盘头是否被dd过.这在安装RAC的过程中,是非常实用的一个命令.如果不包括数据的话,那么如下所示: [ZFFR4CB2101:root]/]& ...
- Pushlet实现后台信息推送(一)
Pushlet是使用较多的后台向前台推送信息的工具.前台订阅某个感兴趣的事件joinListen,触发后台的Pushlet的servlet,为该请求会话建立session,默认这个sessionID是 ...
- EasyUI DataGrid设置列宽为百分比导致表头和内容错位的解决方法
在DataGrid中设置列宽为百分比一般是没有问题的 columns: [[{ title: '内容', field: '__EMPTY', width: '40%' }, { title: '隐患级 ...
- centOS7搭建nexus私服
1.保证JDK,MAVEN已安装,firewalld服务安装 PS:yum install firewalld 2.官网下载:https://www.sonatype.com/download-oss ...
- 3T - A1 = ?
有如下方程:A i = (A i-1 + A i+1)/2 - C i (i = 1, 2, 3, .... n). 若给出A 0, A n+1, 和 C 1, C 2, .....C n. 请编程计 ...
- Python:每日一题004
题目: 输入某年某月某日,判断这一天是这一年的第几天? 程序分析: 以3月5日为例,应该先把前两个月的加起来,然后再加上5天即本年的第几天,特殊情况,闰年且输入月份大于2时需考虑多加一天 个人的思路及 ...
- PowerDesigner 缺省值 引号 问题
在使用PowerDesigner做为MySQL数据库建模的时候,总是有这样的问题,例如我需要一个字段 createTime 类型是 Timestamp,要求这个字段默认值为系统当前时间,于是我给这个字 ...