首先,我们先来了解一下什么是JDBC,JDBC全称为Java Database Connectivity,是一种使用Java代码连接数据库的技术。
一般分为六步:
1.类加载驱动
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
2.数据库连接
String userName = "scott";
String password = "root";
//Oracle数据库URL语法:jdbc:oracle:thin:@db_ip:db_port:db_name
String url="jdbc:oracle:thin:@192.168.3.xxx:1521:xx";
Connection connection = DriverManager.getConnection(url, userName, password);
3.创建statment实例(3者对比见下代码)
4.执行sql语句
5.处理结果
6.关闭资源
if(resultSet!=null) {
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement!=null) {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
下面来看看俩段代码 ,对比一下
import java.sql.*;
public class Login {
public static void main(String[] args) {
try {
//1、加载JDBC驱动程序
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//2、获取数据库连接
String url = "jdbc:oracle:thin:@192.168.30.212:1522:lanqiao";
connection = DriverManager.getConnection(url, "scott", "root");
//3、创建Statement实例
statement = connection.createStatement();
String userName="王_五";
String password="' or '1'='1";
String sql = "select * from user_info where user_name='"
+userName+"'and password='"+password+"'";
//4、执行SQL语句
resultSet = statement.executeQuery(sql);
//5、处理结果
if(resultSet.next()) {//尽管密码错误了,依然可以登录成功
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
//6、关闭JDBC对象,释放资源
try {
if(resultSet!=null) {
resultSet.close();//释放ResultSet类型对象
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(statement!=null) {
statement.close();//释放Statement类型对象
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(connection!=null) {
connection.close();//释放Connection类型对象
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
在看下面一段
import java.sql.*;
public class Login {
public static void main(String[] args) {
try {
//1、加载JDBC驱动程序
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
//2、获取数据库连接
String url = "jdbc:oracle:thin:@192.168.30.212:1522:hongqiao";
connection = DriverManager.getConnection(url, "scott", "root");
//3、创建Statement实例
String sql = "select * from user_info where user_name=? and password=?";
preparedStatement = connection.prepareStatement(sql);
String userName="王_五";
String password="' or '1'='1";
preparedStatement.setObject(1, userName);//为问号占位符赋值
preparedStatement.setObject(2, password);//为问号占位符赋值
//4、执行SQL语句
resultSet = preparedStatement.executeQuery();
//5、处理结果
if(resultSet.next()) {//密码错误,但由于使用了PreparedStatement语句,所以成功规避了SQL注入
System.out.println("登录成功");
}else {
System.out.println("登录失败");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {//6、关闭JDBC对象,释放资源
try {
if(resultSet!=null) {
resultSet.close();//释放ResultSet类型对象
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(preparedStatement!=null) {
preparedStatement.close();//释放PreparedStatement类型对象
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if(connection!=null) {
connection.close();//释放Connection类型对象
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
原因非常简单:用户将特殊“密码”输入后,使得原有SQL语句发生了质的变化:select * from user_info where user_name='王_五' and password='' or '1'='1' SQL注入指通过将恶意SQL语句插入到特定SQL语句内,使特定SQL语句发生变化,最终达到欺骗数据库服务器使之执行恶意的SQL命令的一种方法,以此采用后者可以保证安全性,但执行效率相比有点低下,所以需要根据不同的需要执行不同的代码,同时,在输入密码时我们也可以采用加密,这里附送一段简单的MD5加密代码
package com.test.csdn;
import java.math.BigInteger;
import java.security.MessageDigest;
public class Md5Unit {
private static final String KEY_Md5 = "MD5";
public static final String PASS_Enc = "$%^&*()#$%^&*()^&*(";
public static String encrypt(byte[] date) throws Exception{
MessageDigest md5 = MessageDigest.getInstance(KEY_Md5);
md5.update(date);
BigInteger bigint = new BigInteger(md5.digest());
//将包含 BigInteger 的二进制补码表示形式的 byte 数组转换为 BigInteger
return bigint.toString(16).toUpperCase();
}
public static void main(String[] args) {
String input = "";
try {
String data = Md5Unit.encrypt((input).getBytes());
System.out.println(data);
} catch (Exception e) {
e.printStackTrace();
}
}
}