Java学习笔记47(JDBC、SQL注入攻击原理以及解决)

JDBC:java的数据库链接java

JDBC本质是一套API,由开发公司定义的类和接口mysql

这里使用mysql驱动,是一套类库,实现了接口sql

驱动程序类库,实现接口重写方法,由驱动程序操做数据库数据库

 

JDBC操做步骤:安全

1.注册驱动url

2.得到链接spa

3.得到语句执行平台code

4.执行sql语句对象

5.处理结果blog

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','1'),('b','2');
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(); } }
相关文章
相关标签/搜索