Java手写连接池

来源:互联网 发布:淘宝百丽是正品吗 编辑:程序博客网 时间:2024/06/09 13:45
  1. .连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用。也是复用连接。
  2. 连接池简易设计图
    这里写图片描述

  3. 代码

jdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/njdx?useUnicode=true&characterEncoding=utf8jdbc.username=rootjdbc.password=rootjdbc.maxActive=50jdbc.initialSize=5jdbc.stepSize = 5
/** * 连接池方法接口 * * @Author yjian * @Date 16:08 2017/10/14 **/public interface IDataBasePool {    //对外提供管道    PooledConnection getConnection();    //对内创建链接    void createConnections(int count);}
import java.io.InputStream;import java.sql.Connection;import java.sql.Driver;import java.sql.DriverManager;import java.sql.SQLException;import java.util.Properties;import java.util.Vector;/** * 连接池实现 * * @Author yjian * @Date 16:40 2017/10/14 **/public class DataBasePoolImpl implements IDataBasePool {    //源代码中的所有参数属性都是对外的配置    private static String driver = null;    private static String url = null;    private static String user = null;    private static String password = null;    //限制连接池中的管道数量参数    private static int initCount = 4;    private static int stepSize = 10;    private static int poolMaxSize = 150;    //线程安全的集合 用来放我们的连接管道    private static Vector<PooledConnection> pooledConnections = new Vector<PooledConnection>();    public DataBasePoolImpl() {        init();    }    /**     * 初始化 解析配置文件并创建连接池     *     * @Author yjian     * @Date 16:33 2017/10/14     **/    public void init() {        //获得连接池配置并读取        InputStream input = this.getClass().getClassLoader().getResourceAsStream("jdbc.properties");        Properties properties = new Properties();        try {            properties.load(input);        } catch (Exception e) {            e.printStackTrace();        }        //解析数据        driver = properties.getProperty("jdbc.driverClassName");        url = properties.getProperty("jdbc.url");        user = properties.getProperty("jdbc.username");        password = properties.getProperty("jdbc.password");        //对字节信息进行判断        if (Integer.valueOf(properties.getProperty("jdbc.initialSize")) > 0) {            initCount = Integer.valueOf(properties.getProperty("jdbc.initialSize"));        }        if (Integer.valueOf(properties.getProperty("jdbc.maxActive")) > 0) {            poolMaxSize = Integer.valueOf(properties.getProperty("jdbc.maxActive"));        }        if (Integer.valueOf(properties.getProperty("jdbc.stepSize")) > 0) {            stepSize = Integer.valueOf(properties.getProperty("jdbc.stepSize"));        }        //准备创建什么类型管道        try {            //反射            Driver dbDriver = (Driver) Class.forName(driver).newInstance();            //注册            DriverManager.registerDriver(dbDriver);        } catch (Exception e) {            e.printStackTrace();        }        //开始创建连接池        createConnections(initCount);    }    /**     * 从连接池获取有效的连接,如果没有会容错创建     *     * @Author yjian     * @Date 16:31 2017/10/14     **/    public PooledConnection getRealConnection() {        for (PooledConnection conn : pooledConnections) {            if (!conn.isBuy()) {                //获得物理连接                Connection connection = conn.getConnection();                try {                    //发送一个指令给数据库,看是否收到回应                    if (!connection.isValid(2000)) {                        connection = DriverManager.getConnection(url, user, password);                    }                } catch (SQLException e) {                    e.printStackTrace();                }                //设置当前连接被占用                conn.setBuy(true);                return conn;            }        }        return null;    }    @Override    public PooledConnection getConnection() {        //容错性校验        if (pooledConnections.size() == 0) {            System.out.println("获取数据库连接管道失败");            //手动刷新            createConnections(initCount);        }        PooledConnection pooled = getRealConnection();        while (pooled == null) {            createConnections(stepSize);            pooled = getRealConnection();            //防止被其他人抢了            try {                Thread.sleep(20);            } catch (Exception e) {                e.printStackTrace();            }        }        return pooled;    }    @Override    public void createConnections(int count) {        //判断是否超过连接池最大限制        if (pooledConnections.size() + count <= poolMaxSize) {            for (int i = 0; i < initCount; i++) {                try {                    //创建连接                    Connection connection = DriverManager.getConnection(url, user, password);                    //封装                    PooledConnection pooled = new PooledConnection(false, connection);                    //加入连接池                    pooledConnections.add(pooled);                } catch (SQLException e) {                    e.printStackTrace();                }                System.out.println("初始化" + (i + 1) + "个管道");            }        } else {            System.out.println("超过连接池最大限制");        }    }}
import java.sql.Connection;import java.sql.ResultSet;import java.sql.Statement;/** * 连接池实体 */public class PooledConnection {    //标识繁忙标识 复用的标志 线程安全    private boolean isBuy = false;    //物理连接(连接数据库的)    private Connection connection;    //数据库操作    public ResultSet queryBySql(String sql) {        Statement sm = null;        ResultSet rs = null;        try {            sm = connection.createStatement();            rs = sm.executeQuery(sql);        } catch (Exception e) {            e.printStackTrace();        }        return rs;    }    //这个功能也是自定义添加  是否链接    public void close() {        this.isBuy = false;    }    public PooledConnection(boolean isBuy, Connection connection) {        this.isBuy = isBuy;        this.connection = connection;    }    public boolean isBuy() {        return isBuy;    }    public void setBuy(boolean buy) {        isBuy = buy;    }    public Connection getConnection() {        return connection;    }    public void setConnection(Connection connection) {        this.connection = connection;    }}
/** * 内部类单列模式 * * @Author yjian * @Date 16:40 2017/10/14 **/public class DataBaseSingleton {    private static class createDataBasePool {        private static DataBasePoolImpl poolImp = new DataBasePoolImpl();    }    /**     * 内部类单列模式,仿造类加载原理完美实现线程安全问题 JDK加载时内部类,线程互斥保证了线程安全     *     * @Author yjian     * @Date 16:37 2017/10/14     **/    public static DataBasePoolImpl getInstace() {        return createDataBasePool.poolImp;    }}
import java.sql.ResultSet;/** * 连接池测试类 * * @Author yjian * @Date 16:39 2017/10/14 **/@SuppressWarnings("ALL")public class DataBasePoolTest {    //内部类单例模式    private static DataBasePoolImpl poolImpl = DataBaseSingleton.getInstace();    public synchronized static void selectData() {        //获取连接池        PooledConnection connection = poolImpl.getConnection();        ResultSet rs = connection.queryBySql("select * from test");        System.out.println("线程名称:" + Thread.currentThread().getName());        try {            while (rs.next()) {                System.out.println(rs.getInt("id"));                System.out.println(rs.getString("name"));                System.out.println(rs.getString("nums"));                System.out.println();            }            //释放            rs.close();            //释放当前连接            connection.close();        } catch (Exception e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        for (int i = 0; i < 1500; i++) {            new Thread(new Runnable() {                public void run() {                    selectData();                }            }).start();        }    }}
原创粉丝点击