一.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);
}
}
-
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);
}
}
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语法漏洞进行登录
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("登录失败");
}
}
}
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("登录失败");
}
}
}
上面实例证明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"));
}
}
}
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);
}
}