数据库连接池:说白了就是在一个池子中(容器)中放了很多的数据库连接,当用户需要的时候就从中取出来一个用,用完了就放回连接池中。
优点:极大的提高了数据库的效率。
对于自定义的数据库连接池我们使用一个LinkedList做数据库连接池.这个集合的特点是增删快,查询慢。
自定义一个数据库连接池的步骤:
1.自定义一个类实现DataSource接口。
2.定义一个List<Connection> list=new LinkedList<Connection>();存放数据库连接。
3.初始化数据库连接池。就是在静态代码块static块中添加数据库的连接若干到list中(连接池)。
4.写一个方法returnPool(Connection con)还回到数据库连接池。如果数据库连接池中没有数据连接可用,就添加若干个带数据库连接池list中。
5.在getConnection()方法中动态代理重新改造Connection的close方法,因为我们不能够用完了就关闭,而是应该用完了还回数据库连接池中。这样可以循环使用。
案例:
自定义自己的数据库连接池MyPool
package com.itheima.mypools; 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.SQLException; import java.sql.SQLFeatureNotSupportedException; import java.util.LinkedList; import java.util.List; import java.util.logging.Logger; import javax.sql.DataSource; public class MyPool implements DataSource{ //1.需要一个容器存放连接 private static List<Connection> list=new LinkedList<Connection>(); //初始化加载类的时候就在连接池中添加了5个连接 static{ try { //2.加载驱动 Class.forName("com.mysql.jdbc.Driver"); for(int i=0;i<5;i++){ //3.获取连接 Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/day11", "root", "169500"); list.add(con); } }catch (Exception e) { e.printStackTrace(); throw new RuntimeException(); } } @Override public Connection getConnection() throws SQLException { //如果连接池的数据没有了就添加3个连接到连接池中 if(list.size()==0){ for(int i=0;i<3;i++){ Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/day11", "root", "169500"); list.add(con); } } //获取连接,就是把连接池中的连接remove不是get... final Connection con = list.remove(0); //需要重写连接的close()方法,我们使用动态代理 Connection proxy=(Connection) Proxy.newProxyInstance(con.getClass().getClassLoader(), con.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args)//proxy代理类对象 method被代理类的方法,args被代理类方法的参数 throws Throwable { if("close".equals(method.getName())){ //要改造的方法就还回连接池 returnPool(con); return null; }else{ //不想改造的方法就使用被代理者对象的方法 return method.invoke(con, args); } } }); System.out.println("获取了一个连接,连接池中还有:"+list.size()+"个连接"); return proxy; } public void returnPool(Connection con){ try { if(con!=null&&!con.isClosed()){ list.add(con); } } catch (SQLException e) { e.printStackTrace(); } System.out.println("还回了一个连接,池里还剩余"+list.size()+"个连接"); } @Override public PrintWriter getLogWriter() throws SQLException { // TODO Auto-generated method stub return null; } @Override public void setLogWriter(PrintWriter out) throws SQLException { // TODO Auto-generated method stub } @Override public void setLoginTimeout(int seconds) throws SQLException { // TODO Auto-generated method stub } @Override public int getLoginTimeout() throws SQLException { // TODO Auto-generated method stub return 0; } @Override public Logger getParentLogger() throws SQLFeatureNotSupportedException { // TODO Auto-generated method stub return null; } @Override public <T> T unwrap(Class<T> iface) throws SQLException { // TODO Auto-generated method stub return null; } @Override public boolean isWrapperFor(Class<?> iface) throws SQLException { // TODO Auto-generated method stub return false; } @Override public Connection getConnection(String username, String password) throws SQLException { // TODO Auto-generated method stub return null; } }
使用这个自己定义的数据库连接池:
package com.itheima.mypools; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import cn.itheima.utils.JDBCUtils; public class JDBCDemo1 { public static void main(String[] args) { Connection con=null; PreparedStatement ps=null; ResultSet rs=null; try { //使用数据库连接池 MyPool pool=new MyPool(); //获取连接 con=pool.getConnection(); ps=con.prepareStatement("select * from account"); rs=ps.executeQuery(); while(rs.next()){ String name=rs.getString("name"); System.out.println(name); } } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(); }finally{ //这里的close已经被更该过了 if(rs!=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); }finally{ rs=null; } } if(ps!=null){ try { ps.close(); } catch (SQLException e) { e.printStackTrace(); }finally{ ps=null; } } if(con!=null){ try { con.close(); } catch (SQLException e) { e.printStackTrace(); }finally{ con=null; } } } } }
运行结果:
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-12-17 04:28:58