自定义连接池

一.为什么要使用数据库连接池?
JDBC作为一种数据库访问技术,具有简单易用的优点。但每一次WEB请求都要建立一次数据库连接,建立连接是一个耗费资源的活动,每次都得花费0.05-1s的时间,而且系统还要分配内存资 源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销,可是对于现在web应用,尤其是大型的电子商务网站, 同时有几百人甚至几千人在线是很正常的事情。
我们一会可以测试以下,使用连接池和不使用连接池在效率上的差别,大约是5-10倍。
二.数据库连接池的实现分析
•1.并发问题
•为了使连接管理服务具有更大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,我们使用synchronized关键字即可确保线程的同步。示例代码:
• Public synchronized Connection getConnection()
•2.多数据库服务器和多用户
•对于大型的企业级应用,常常需要同时连接不同的数据库。如何连接不同的数据库呢?可以采用的策略是:设计一个符合单例模式的连接池管理类,在连接池管理类的 实例被创建时读取一个资源文件,其中资源文件中存放着多个数据库的连接信息。根据资源文件提供的信息,创建多个连接池类的实例,每一个实例都是一个特定数据库的连接池。连接池管理类实例为每个连接池实例取一个名字,通过不同的名字来管理不同的连接池。
•3.事务处理
•可以通过设置Connection的AutoCommit属性为false, 然后显示地调用commit或rollback来实现。但要高效地进行Connection复用,就必须提供相应的事务支持机制。可采用每一个事务独占一个连接来实现,这种方法可以大大降低事务管理的复杂性。
•4.连接池的分配和释放
•每当用户请求一个连接时,系统首先检查空闲池内有没有空闲连接。如果有就把建立时间最长的那个连接分配给他;如果没有则检查当前所开的连接池是否达到连接池所允许的最大连接数。如果没有达到,就新建一个连接;如果已经达到,就等待一定的时间。如果在等待的时间内有连接被释放出来,就可以把这个连接分配给等待的用户;如果等待时间超过预定时间,则返回空值;系统对已经分配出去正在使用的连接只做计数,当时用完后再返回给空闲池;对于空闲连接的状态,可开辟专门的线程定时检测,这样会花费一定的系统开销,但可以保证较快的相应速度;也可采取不开辟专门线程,只是在分配前检测的方法。
•5.连接池的配置和维护
•连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接数和最大连接数来控制连接池中的连接。最小连接数是系统启动时连接池所创建的连接数,最大连接数是连接池中允许连接的最大数目。
三.自定义连接池
1、创建一个新的项目:connpoll
2、导入jar包,MySQL驱动包
3、创建实体类
具体实现:
1.在src目录创建一个配置文件db.properties
1.DRIVER:com.mysql.jdbc.Driver
2.URL:jdbc:mysql://localhost:3306/db214
3.USER:root
4.PASSWORD:123456

2.编辑DBConnPool类:
连接池createConnection方法•
①定义:private static Connection createConnection()
•private static InputStream is=Thread.currentThread().getContextClassLoader().getResourceAsStream(“db.properties”);
• static{
• try {
• properties.load(is); //配置文件加载
• jdbcDriver=properties.getProperty(“DRIVER”); //获取驱动
• jdbcurl=properties.getProperty(“URL”); //获取URL
• userName=properties.getProperty(“USER”); //获取用户名
• password=properties.getProperty(“PASSWORD”); //获取密码
• Class.forName(jdbcDriver); //加载驱动
• is.close(); //关闭输入流
• } catch (IOException | ClassNotFoundException e) {
• e.printStackTrace();
• }
• }
• //获取数据库链接
• private static Connection createConnection(){ //定义方法获取数据库链接
• Connection conn=null;
• try {
• conn = DriverManager.getConnection(jdbcurl, userName, password); //获取数据库链接
• } catch (SQLException e) {
• e.printStackTrace();
• }
• return conn;
}

②getConnection方法
public synchronized static Connection getConnection() throws Exception{
    Connection conn=null;                   //数据库链接
    if(pool==null){                         //判断连接池是否已被初始化
        pool=new ArrayList<>();             //如果为null则直接初始化
    }
    if(pool.isEmpty()){
        conn=createConnection();            //如果连接池为空,则直接创建
    }else{
        conn = (Connection) pool.get(pool.size()-1);    //如果连接池中有链接元素则从连接池获取最后一个元素
        pool.remove(pool.size()-1);         //当获取到连接池最后一个元素后则在连接池中移除最后一个元素
    }
    return conn;                            //返回connection对象
}

closeConnection方法
public synchronized static void closeConnection(Connection conn) {
    if (conn!=null) {                       //判断链接是否为空
        if(pool.size()>=POOL_MAX_SIZE){ //判断连接池大小是否达到最大连接数
            try {
                conn.close();               //关闭链接
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }else {
            pool.add(conn);                 //如果没有达到最大连接数,则将链接归还连接池
        }
    }   }
    ③initPool方法
    public static void initPool() throws Exception{
    if(pool==null){
        pool=new ArrayList<>();
        while(pool.size()

}
用main方法测试使用连接池和不适用连接池的区别,开启链接的时间是0-6。
这里写图片描述
到此就结束了,我们可以发现,使用连接池和不使用连接池在效率上的差别,大约是5-10倍。

你可能感兴趣的:(自定义连接池,MYSQL,JDBC)