手写连接池

4.连接池_手写连接池_动态代理

二、数据库连接池

很多很多的连接

放进一个池子里用集合来存取这些连接

手写连接池:

改造conn的close方法

1.继承

2.装饰

3.动态代理

package com.itheima.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.SQLException;
import java.util.LinkedList;
import java.util.List;
import javax.sql.DataSource;

public class MyPool implements DataSource {
    private static List<Connection> pool = new LinkedList<Connection>();
    static{
        try{
        Class.forName("com.mysql.jdbc.Driver");
        for(int i=0;i<5;i++){
        Connection conn = DriverManager.getConnection("jdbc:mysql:///day11","root","root");
        pool.add(conn);
        }
        }catch (Exception e) {
        e.printStackTrace();
        throw new RuntimeException(e);
        }
    }
    
    public Connection getConnection() throws SQLException {
        if(pool.size()==0){
            for(int i=0;i<3;i++){
                Connection conn = 
                    DriverManager.getConnection("jdbc:mysql:///day11","root","root");
                pool.add(conn);
            }
        }
        final Connection conn = pool.remove(0);
        //--利用动态代理改造close方法
        Connection proxy = 
            (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), 
                    conn.getClass().getInterfaces(), new InvocationHandler(){
            public Object invoke(Object proxy, Method method,
                        Object[] args) throws Throwable {
                if("close".equals(method.getName())){
                    //对于想要改造的close方法,我们自己写
                    retConn(conn);
                    return null;
                }else{
                    //对于不想改造的方法调用被代理者身上相同的方法
                    return method.invoke(conn, args);
                }
            }
        });
        System.out.println("获取了一个连接,池里还剩余"+pool.size()+"个连接");
        return proxy;
    }
        private void retConn(Connection conn){
        try {
            if(conn!=null && !conn.isClosed()){
                pool.add(conn);
                System.out.println("还回了一个连接,池里还剩余"+pool.size()+"个连接");
            }
        } catch (SQLException e) {
        e.printStackTrace();
        }
    }
    public Connection getConnection(String username, String password)
            throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }
    public PrintWriter getLogWriter() throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }
    public int getLoginTimeout() throws SQLException {
        // TODO Auto-generated method stub
        return 0;
    }
    public void setLogWriter(PrintWriter out) throws SQLException {
        // TODO Auto-generated method stub
    }
    public void setLoginTimeout(int seconds) throws SQLException {
        // TODO Auto-generated method stub
    }
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        // TODO Auto-generated method stub
        return false;
    }
    public <T> T unwrap(Class<T> iface) throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }
}
时间: 2024-10-07 20:17:43

手写连接池的相关文章

手写数据库连接池

  1.  相信很多人看这篇文章已经知道连接池是用来干什么的?没错,数据库连接池就是为数据库连接建立一个"缓冲池",预先在"缓冲池"中放入一定数量的连接欸,当需要建立数据库连接时,从"缓冲池"中取出一个,使用完毕后再放进去.这样的好处是,可以避免频繁的进行数据库连接占用很多的系统资源.      2.  常见的数据库连接池有:dbcp,c3p0,阿里的Druid.好了,闲话不多说,本篇文章旨在加深大家对连接池的理解.这里我选用的数据库是mysql

手写线程池 (一)

前言准备 1.jdk线程池的使用:https://www.cnblogs.com/jtfr/p/10187419.html 2.线程池核心:线程的复用. 运行的线程是线程池的核心,被添加的任务需要实现过Runnable接口,主要是保证有run方法.运行时候 对象.run() . 一.手写线程池注意要点 1.线程池需要添加任务,任务是放置在一个队列(FIFO)当中,具体只要保证FIFO,或优先级保证(Map集合)先执行.2.线程池运行,需要一个容器存放创建的线程,可数组或集合,可以自己设计思考.3

图解线程池工作机制,手写线程池?

ThreadPoolExecutor构造函数的各个参数说明 public ThreadPoolExecutor(int corePoolSize,//线程池中核心线程数 int maximumPoolSize,//允许的最大线程数 long keepAliveTime,//线程空闲下来后,存活的时间,这个参数只在> corePoolSize才有用 TimeUnit unit,//存活时间的单位值 BlockingQueue<Runnable> workQueue,//保存任务的阻塞队列

c3p0写连接池 Demo

1.导包 2.配置文件:名称必须为:c3p0-config.xml,且必须放在src根目录下 1 <c3p0-config> 2 <!-- 默认配置,有且仅可出现一次 ,如果没有指定则使用这个配置 --> 3 <default-config> 4 <!-- 连接超时时间 30秒 --> 5 <property name="checkoutTimeout">30000</property> 6 <!-- 每30

dbcp写连接池 Demo

1.导包 2.准备配置文件   .properties(注:这里的参数名driverClassName.url.username等是不能改变的) 不能任意命名的原因是[你懂得] 3.Demo 1 public static DataSource ds;//变量 2 public TestBasicDataSource() {} //私有化构造函数 3 static{ 4 try{ 5 Properties p=new Properties(); 6 p.load(TestBasicDataSou

关于利用动态代理手写数据库连接池的异常 java.lang.ClassCastException: com.sun.proxy.$Proxy0 cannot be cast to java.sql.Connection

代码如下: final Connection conn=pool.remove(0); //利用动态代理改造close方法 Connection proxy= (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object pro

手写线程池

Executors.newSingleThreadExecutor(): 只有一个线程的线程池,因此所有提交的任务是顺序执行 Executors.newCachedThreadPool(): 线程池里有很多线程需要同时执行,老的可用线程将被新的任务触发重新执行, 如果线程超过60秒内没执行,那么将被终止并从池中删除 Executors.newFixedThreadPool(): 拥有固定线程数的线程池,如果没有任务执行,那么线程会一直等待 Executors.newScheduledThread

DBCP、c3p0、Druid三大连接池区别

DBCP.c3p0.Druid三大连接池区别 一.连接池优势 如果一个项目中如果需要多个连接,如果一直获取连接,断开连接,这样比较浪费资源: 如果创建一个池,用池来管理Connection,这样就可以重复使用Connection. 有了池我们就不用自己来创建Connection,而是通过池来获取Connection对象.当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection"归还"给池. 池就可以再利用

c3p0连接池整合jdbc

需要的jar包如下 在src下面新建一个xml配置文件用来写连接池相关配置,名字必须为c3p0-config.xml,必须在src下面,如下图 c3p0-config.xml配置文件内容为 <?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <!--连接四大参数配置 --> <property name="jdbcU