JDBC学习笔记(3)--PreparedStatement执行sql语句 + mysql注入+callablestatement执行存储过程

一.PreparedStatement执行sql语句

1.首先连接数据库Dao.java
package com.huan.dao;

import org.junit.Test;

import java.sql.*;

/**
 * Created by pc on 17-5-1.
 */
public class Dao {
    static String user ="root";
    static String password = "root";
    static String url = "jdbc:mysql://localhost:3306/eurasia_echarts?characterEncoding=UTF-8";

    @Test
    public static Connection getDao() throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(url, user, password);
        if (null != conn) {
            System.out.println("连接成功");
        }
        return conn;
    }

    public static void close(Statement state, Connection conn){
        if(null != state){
            try {
                state.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(null != conn){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void close(ResultSet rs, Statement state, Connection conn ){
        if(null != rs){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(null != state){
            try {
                state.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(null != conn){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

2.PreparedStatement执行DML语句
  • 执行插入语句
  • 执行更新语句
  • 执行删除语句

插入演示

package com.huan.PreparedStatement;

import com.huan.dao.Dao;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;

/**
 * Created by pc on 17-5-1.
 */
public class Demo_preparedStatement {
    @Test
    public void test() throws Exception {
        Connection conn = null;
        PreparedStatement pstmt= null;
        conn = Dao.getDao();
        //预编译的sql语句
        String sql = " insert into mahuan (name,age) values(?,?); ";//一个问号表示一个参数占位值
        //执行预编译sql语句
        pstmt = conn.prepareStatement(sql);
        //设置参数
        pstmt.setString(1,"马欢");
        pstmt.setInt(2,22);
/*
更新数据
         String sql = " update mahuan set name =? where id =?; ";
        执行预编译sql语句
        pstmt = conn.prepareStatement(sql);
        设置参数
        pstmt.setString(1,"王五");
        pstmt.setInt(2,4);
删除数据
        String sql = " delete from mahuan where  id =?; ";
        执行预编译sql语句
        pstmt = conn.prepareStatement(sql);
        设置参数
        pstmt.setInt(1,4);
*/
        int count = pstmt.executeUpdate();
        System.out.println(count);
        Dao.close(pstmt,conn);

    }
}

《JDBC学习笔记(3)--PreparedStatement执行sql语句 + mysql注入+callablestatement执行存储过程》
《JDBC学习笔记(3)--PreparedStatement执行sql语句 + mysql注入+callablestatement执行存储过程》

  • 3.PreparedStatement执行DQL语句

  • 执行查询语句
package com.huan.PreparedStatement;

import com.huan.dao.Dao;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
 * Created by pc on 17-5-1.
 */
public class Demo_Select {
    @Test
    public void selectTest() throws Exception {
        Connection conn = null;
        PreparedStatement pstmt = null;
        conn = Dao.getDao();
        String sql = " select * from mahuan; ";
        pstmt = conn.prepareStatement(sql);

         ResultSet rs = pstmt.executeQuery();
         while(rs.next()){
             System.out.println("用列名称取值:编号:"+rs.getInt("id") +" 姓名:"+rs.getString("name")+" 年龄:"+rs.getString("age"));
         }

         Dao.close(rs, pstmt,conn);
    }
}

《JDBC学习笔记(3)--PreparedStatement执行sql语句 + mysql注入+callablestatement执行存储过程》

PreparedStatement和Statement区别

1.PreparedStatement比Statement效率高
2.语法不一样
3.PreparedStatement数据更安全

二.mysql注入

模拟登录:创建表users:

  • 正常登录:

    String name =”mahuan”;
    String password = “123456”;

  • 当用户名(被破解)

    String name =”mahuan’ or 1=1– ‘”;
    String password = “456”;

上面这两条登录都可以登录,但是第二条语句明显错误,这是利用mysql语法漏洞进行登录

《JDBC学习笔记(3)--PreparedStatement执行sql语句 + mysql注入+callablestatement执行存储过程》

mysql注入成功(Statement)
package com.huan.statemennt;

import com.huan.dao.Dao;
import org.junit.Test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 * Created by pc on 17-5-1.
 */
public class login {
    String name ="mahuan' or 1=1-- '";
    String password = "456";
    @Test
    public void login_Statement() throws Exception {

        Connection conn = null;
        Statement stmt = null;
        conn = Dao.getDao();
        stmt = conn.createStatement();

        String sql=" select * from users where name='"+name+"' and password='"+password+"'; ";

        ResultSet rs = stmt.executeQuery(sql);
        if (rs.next()){
            System.out.println("登录成功");
        }else {
            System.out.println("登录失败");
        }
    }
}

《JDBC学习笔记(3)--PreparedStatement执行sql语句 + mysql注入+callablestatement执行存储过程》 image.png

mysql注入失败(PreparedStatement)
package com.huan.statemennt;

import com.huan.dao.Dao;
import org.junit.Test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

/**
 * Created by pc on 17-5-1.
 */
public class login {
    String name ="mahuan' or 1=1-- '";
    String password = "456";
    @Test
    public void login_Statement() throws Exception {

        Connection conn = null;
        PreparedStatement stmt = null;
        conn = Dao.getDao();
        
        String sql=" select * from users where name=? and password=?; ";
        stmt = conn.prepareStatement(sql);
        stmt.setString(1,name);
        stmt.setString(2,password);
        ResultSet rs = stmt.executeQuery();
        if (rs.next()){
            System.out.println("登录成功");
        }else {
            System.out.println("登录失败");
        }
    }
}

《JDBC学习笔记(3)--PreparedStatement执行sql语句 + mysql注入+callablestatement执行存储过程》

上面实例证明PreparedStatement比Statement更安全

三.callablestatement执行存储过程(是PreparedStatement的子接口)

1输出所有参数:

  • 创建存储过程

如何创建:Mysql学习笔记(6)-存储过程

delimiter $
create procedure pro_findid(in sid int)
begin
    select * from mahuan where id =sid;
end $
  • 通过程序调用存储过程,所有调用存储过程都用executeQuery
package com.huan.statemennt;

import com.huan.dao.Dao;
import org.junit.Test;

import java.sql.*;

/**
 * Created by pc on 17-5-1.
 */
public class login {
    String name ="mahuan' or 1=1-- '";
    String password = "456";
    @Test
    public void login_Statement() throws Exception {

        Connection conn = null;
        CallableStatement cstmt = null;
        conn = Dao.getDao();

        String sql = " call pro_findid(?); ";
        cstmt = conn.prepareCall(sql);
        cstmt.setInt(1,5);

        ResultSet rs =cstmt.executeQuery();//所有调用存储过程都用executeQuery
        while(rs.next()){
            System.out.println("用列名称取值:编号:"+rs.getInt("id") +" 姓名:"+rs.getString("name")+" 年龄:"+rs.getString("age"));
        }
    }
}

《JDBC学习笔记(3)--PreparedStatement执行sql语句 + mysql注入+callablestatement执行存储过程》

2.带有输出参数的存储过程

  • 创建存储过程

delimiter $
create procedure pro_findidname(in sid int,out sname varchar(20))
begin
    select name into sname from mahuan where id =sid;
end $
  • 执行带有输入输出参数的存储过程
package com.huan.statemennt;

import com.huan.dao.Dao;
import org.junit.Test;

import java.sql.*;

/**
 * Created by pc on 17-5-1.
 */
public class login {
    String name ="mahuan' or 1=1-- '";
    String password = "456";
    @Test
    public void login_Statement() throws Exception {

        Connection conn = null;
        CallableStatement cstmt = null;
        conn = Dao.getDao();

        String sql = " call pro_findidname(?,?); ";
        cstmt = conn.prepareCall(sql);
        cstmt.setInt(1,5);
        cstmt.registerOutParameter(2, java.sql.Types.VARCHAR);
        cstmt.executeQuery();
        String  result = cstmt.getString(2);
        System.out.println(result);
       Dao.close(cstmt,conn);
    }
}

《JDBC学习笔记(3)--PreparedStatement执行sql语句 + mysql注入+callablestatement执行存储过程》

文章文集:JavaEE–学习笔记

    原文作者:Mr_欢先生
    原文地址: https://www.jianshu.com/p/509629fb081e
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞