实现一个自己的数据库连接池----利用工厂设计模式

1.抽象接口的实现

/**
 1. @author : GONG ZHI QIANG
 2. @data : 2019-08-30 , 22:50
 3. @user : SnaChat
 4. @project: DesignPattern
 5. @description :
 */
public abstract class Pool {

    public String propertiesName = "connection.properties";

    private static Pool instance = null;

    protected int maxConnect = 100;

    protected int normalConnect = 10;

    protected String driverName = null;

    protected String username = null;

    protected String password = null;

    protected Driver driver = null;

    protected String url = null;

    /**
     * 抽象类中的构造函数私有
     */
    protected Pool() {
        initDbInfo();
        loadDrivers(driverName);
    }

    protected void initDbInfo() {

        InputStream inputStream = Pool.class.getClassLoader().getResourceAsStream(propertiesName);
        Objects.requireNonNull(inputStream, "输入流数据为空");
        Properties properties = new Properties();
        try {
            properties.load(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        this.driverName = properties.getProperty("driverName");
        this.maxConnect = Integer.parseInt(properties.getProperty("maxConnect"));
        this.normalConnect = Integer.parseInt(properties.getProperty("normalConnect"));
        this.username = properties.getProperty("username");
        this.password = properties.getProperty("password");
        this.url = properties.getProperty("url");
    }

    private void loadDrivers(String driverName) {
        String driverClassName = driverName;
        try {
            driver = (Driver) Class.forName(driverClassName).newInstance();
            DriverManager.registerDriver(driver);
            System.out.println("系统成功注册驱动程序");

        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {

        } finally {
            System.out.println("系统注册驱动异常");
        }
    }

    /**
     * @return
     * @throws InstantiationError
     * @throws IllegalAccessException
     * @throws ClassNotFoundException
     */
    public static synchronized Pool getInstance() throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        if (instance == null) {
            instance.initDbInfo();
            instance = (Pool) Class.forName("factory.Pool").newInstance();
        }
        return instance;
    }


    public abstract Connection getConnection();

    /**
     * @param time
     * @return
     */
    public abstract Connection getConnection(long time);

    /**
     * @param connection 将对象返回给连接池
     */
    public abstract void freeConnection(Connection connection);

    /**
     * @return 返回当前空闲连接数
     */
    public abstract int getNum();

    /**
     * @return 返回当前工作的连接数
     */
    public abstract int getNumActive();

    public synchronized void realse() {
        try {
            DriverManager.deregisterDriver(driver);
            System.out.println("连接驱动释放成功" + driver.getClass().getName());
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("连接释放异常");
        }
    }
}

2. 利用抽象接口创建数据库连接池

public final class DBConnectionPool extends Pool {
    /**
     * 用于连接池连接数量的核查
     */
    private int checkedOut;

    /**
     * 存放连接池的容器
     */
    private Vector<Connection> freeConnection = new Vector<Connection>();

    /**
     * 当前连接池中总共的连接数量
     */
    private static int num = 0;

    /**
     * 当前连接池中活跃的连接数量
     */
    private static int numActive = 0;

    /**
     * 连接池对象
     */
    private static DBConnectionPool pool = null;
	
	/**
     * @return 产生数据库连接池对象
     */
    public static synchronized DBConnectionPool getInstance() {
        if (pool == null) {
            pool = new DBConnectionPool();
        }
        return pool;
    }

    /**
     * 构造方法,初始化连接池
     */
    private DBConnectionPool() {
        //使用父类中的方法初始化连接信息
        initDbInfo();
        for (int i = 0; i < normalConnect; i++) {
            Connection connection = newConnection();
            if (connection != null) {
                freeConnection.addElement(connection);
                num++;
            }
        }
    }

    /**
     * @return 从连接池中返回一个对象
     */
    public synchronized Connection getConnection() {
        Connection connection = null;
        if (freeConnection.size() > 0) {
            num--;
            connection = freeConnection.firstElement();
            freeConnection.removeElementAt(0);
            try {
                if (connection.isClosed()) {
                    System.out.println("从连接池中取出的是一个无效的连接");
                    connection = getConnection();
                }
            } catch (SQLException e) {
                e.printStackTrace();
                System.out.println("删除一个无效的连接");
            }
        } else if (maxConnect == 0 || checkedOut < maxConnect) {
            //没有空的连接,当前的连接数小于最大的连接数,则创建一个新的连接
            connection = newConnection();
        }
        if (connection != null) {
            checkedOut++;
        }
        numActive++;
        return connection;
    }

    /**
     * @param time 指定超时,超时将返回 null
     * @return 返回一个Connection对象
     */
    public synchronized Connection getConnection(long time) {
        long startTime = new Date().getTime();

        Connection connection = null;

        while ((connection = getConnection()) == null) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            //超时
            if (new Date().getTime() - startTime >= time) {
                return null;
            }
        }
        return connection;
    }

    /**
     * @param connection 将对象返回给连接池
     */
    public void freeConnection(Connection connection) {
        freeConnection.add(connection);
        num++;
        numActive--;
        checkedOut--;
        notifyAll();
    }

    /**
     * @return 当前的连接池中剩余的可用连接数量
     */
    public int getNum() {
        return num;
    }

    /**
     * @return 当期使用中的连接的数量
     */
    public int getNumActive() {
        return numActive;
    }

    /**
     * @return 在没有超过连接池的最大值 <code> maxConnect< /code>的情况下,创建一个新的连接
     */
    private Connection newConnection() {
        Connection connection = null;
        try {
            if (username == null) {
                connection = DriverManager.getConnection(url);
            } else {
                connection = DriverManager.getConnection(url, username, password);
            }
            System.out.println("连接池创建一个新的连接");
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("创建连接失败");
        } finally {
        }
        return connection;
    }

    /**
     * 关闭连接池
     */
    public synchronized void realse() {
        Enumeration allConnection = freeConnection.elements();
        while (allConnection.hasMoreElements()) {
            Connection connection = null;
            connection = (Connection) allConnection.nextElement();
            try {
                connection.close();
                num--;
            } catch (SQLException e) {
                System.out.println("无法关闭连接池中的连接");
            }
            freeConnection.removeAllElements();
            numActive = 0;
        }
        super.realse();
    }
}

3.配置文件 : connection.properties

url=jdbc:mysql://localhost:3306/MUSICDB
username=root
password=数据库的密码

maxConnect=100
normalConnect =10
driverName=com.mysql.cj.jdbc.Driver

4.使用测试:


        Pool pool = DBConnectionPool.getInstance();
        Connection connection = pool.getConnection(2000);
        Objects.requireNonNull(connection , "获取连接对象为空");

        System.out.println("当前连接池中空闲的连接对象 = " + pool.getNum());
        System.out.println("正在使用的连接的数量      = " + pool.getNumActive());

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值