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);
}


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