Java數據庫之防SQL注入和自定義線程池

一、防止SQL注入
SELECT * FROM student WHERE NAME = 'michong' ANDpasswd = '111' OR '1'='1';
如上面的SQL語句,當密碼不正確的時候也可以爆出數據庫,所以必須防止通過SQL注入爆出數據庫

操作如下:
1、在SQL語句中使用佔位符?:
String sql = "select * from student where name = ? and passwd = ?";

2、使用PreparedStatement來代替Statement
try {
Connection conn = JDBCUtils.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "michong");
ps.setString(2, "123");
ResultSet rs = ps.executeQuery();
if(rs.next()){
System.out.println("Login Success");
}else{
System.out.println("Login Failed");
}
使用PreparedStatement實現防止SQL注入
1)setString方法實現將值傳入到SQL語句中,第一個參數是參數在SQL中的位置,第二個參數是參數的值。
2)直接執行executeQuery不需要將SQL放入到參數中,因爲上面已經執行過了。




二、自定義連接池:





代碼實現:
MyDataSource.java
//1、創建一個容器,存儲Connection對象
public static LinkedList<Connection> pool = new LinkedList<Connection>();
//2、生成五個連接
static{
for(int i = 0 ; i < 5; i++){
try {
Connection conn = JDBCUtils.getConnection();
MyConnection mconn = new MyConnection(conn, pool);
pool.add(mconn);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

static{
for(int i = 0 ; i < 5; i++){
try {
Connection conn = JDBCUtils.getConnection();
MyConnection mconn = new MyConnection(conn, pool);
pool.add(mconn);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

//3、重寫getConnection方法
@Override
public Connection getConnection() throws SQLException {
Connection conn = null;
//當連接池中沒有連接對象時,重新創建五個連接
if(pool.size() == 0){
for(int i = 0 ; i < 5; i++){
conn = JDBCUtils.getConnection();
MyConnection mconn = new MyConnection(conn, pool);
pool.add(mconn);
}
}
conn = pool.remove(0);
return conn;
}

@Override
public Connection getConnection() throws SQLException {
Connection conn = null;
//當連接池中沒有連接對象時,重新創建五個連接
if(pool.size() == 0){
for(int i = 0 ; i < 5; i++){
conn = JDBCUtils.getConnection();
MyConnection mconn = new MyConnection(conn, pool);
pool.add(mconn);
}
}
conn = pool.remove(0);
return conn;
}


MyConnection.java
private Connection conn;
private List<Connection> pool;
//構造方法中傳入Connection對象和List<Connection>連接池對象
public MyConnection(Connection conn,List<Connection> pool) {
super();
this.conn = conn;
this.pool = pool;
}
//重寫PreparedStatement方法,防止在執行SQL語句的時候出現空值
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
// TODO Auto-generated method stub
PreparedStatement prepareStatement = conn.prepareStatement(sql);
return prepareStatement;
}
//重寫close()方法,回收連接資源,將連接對象重新放入到連接池中
@Override
public void close() throws SQLException {
// TODO Auto-generated method stub
pool.add(conn);
}



實現類:
MyDataSource dataSource = new MyDataSource();
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
conn = dataSource.getConnection();//通過連接池獲取連接對象
String sql = "select * from student where name = ? and passwd = ?";
pstmt = conn.prepareStatement(sql);//防止SQL注入
pstmt.setString(1, "michong");
pstmt.setString(2, "123");
rs = pstmt.executeQuery();
if(rs.next()){
System.out.println("Login Success");
}else{
System.out.println("Login Failed");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//回收資源
JDBCUtils.closeAll(conn, pstmt, rs);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章