(新手)手写一个简陋的数据库连接池
- 首先,一个测试类poolDemo,这个类就是简单的从数据库里查询一条数据。代码如下。
package www.study.pool;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class poolDemo {
public static void main(String[] args) {
Connection conn=null;
PreparedStatement pst=null;
ResultSet rs=null;
String sql="select * from account where id=?";
MyPool pool=new MyPool();
try {
conn=pool.getConnection();
pst=conn.prepareStatement(sql);
pst.setString(1, "1");
rs=pst.executeQuery();
while(rs.next()){
System.out.println("查询成功!");
System.out.println(rs.getInt(3)+"元");
}
}catch(Exception e) {
e.printStackTrace();
}finally{
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
rs=null;
}
}
if(pst!=null){
try {
pst.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
pst=null;
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}finally{
conn=null;
}
}
}
}
}
- 然后是一个简陋数据库连接池MyPool类,里面使用静态代码块初始化 了5个连接,因为使用的时候会对增加,删除连接比较频繁,所以使用LinkedList链表的数据结构来存储连接。判断5个初始的连接是否用完了,用完的话就在生成5个连接出来。
- 接着使用动态代理模式,改造Connection的close()方法。当我们在测试类Pooldemo中使用conn.close()方法时,就会自动调用改造过的close()方法。代码如下。
package www.study.pool;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
import javax.sql.DataSource;
public class MyPool implements DataSource {
private static LinkedList<Connection> list=new LinkedList<Connection>();
public static final String url="jdbc:mysql:///day11";
public static final String username="root";
public static final String password="***********";
static{
for(int i=0;i<5;i++){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection(url,username,password);
list.add(conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@Override
public Connection getConnection() throws SQLException {
if(list.size()==0){
for(int i=0;i<5;i++){
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn=DriverManager.getConnection(url,username,password);
list.add(conn);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
final Connection con=list.remove();
Connection proxy=(Connection)Proxy.newProxyInstance(Connection.class.getClassLoader(), new Class[]{Connection.class}, new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if("close".equals(method.getName())){
System.out.println("close()方法只这里被调换了。。");
returnConn(con);
return null;
}else{
return method.invoke(con, args);
}
}
});
return proxy;
}
public void returnConn(Connection conn) throws SQLException{
if(!conn.isClosed()&&conn instanceof Connection&&conn!=null){
list.add(conn);
}
}
}
- 运行结果的截图:
最后想说,在下是个新手,写的不好,欢迎指正。这在学习使用的c3p0之前,学习着手写一个简陋的数据库连接池,大家有谁手写的连接池不错的,可以推荐给我学习学习。