Java模块 -- Tomcat JDBC Connection pool

Tomcat从7.0之后使用他自己的连接池,不在使用Commons-dbcp


Commons-dbcp的缺点:
1. 单线程,为了保证线程安全会锁整个连接池
2. 性能不佳
3. 太复杂,超过60个类
4. dbcp使用静态接口,
5.发展滞后 (似乎不太更新了??)


Tomcat JDBC Pool 特点
1. 近乎兼容dbcp , 性能更高.
2. 异步方式获取连接  ??
3. 使用 javax.sql.PooledConnection接口来获取连接.
4. 支持高并发应用环境
5. 简单,核心文件只有8个.
6.更好的空闲连接处理机制


官方文档地址:Apache Tomcat8 JDBC Connection Pool

这里的例子,是将Tomcat JDBC Connection Pool组件拿出来,单独使用

在工作中,可以将这个组件放到需要的项目中单独使用


代码以及jar包:Tomcat JDBC Connection Pool 代码以及Jar包


公共方法

public class CommonUtils {


    /**
     * 判断是否是windows操作系统
     *
     * @return
     */
    public static boolean isWindowsOS() {
        boolean isWindowsOS = false;
        String osName = System.getProperty("os.name");
        if (osName.toLowerCase().indexOf("windows") > -1) {
            isWindowsOS = true;
        }
        return isWindowsOS;
    }

    /**
     * 判断相对路径根路径(区分./和../)
     */
    static {
        if (isWindowsOS()) {
            systemRootPath = "./";
        } else {
            systemRootPath = "../";
        }
    }

    /**
     * 相对路径的根路径
     */
    public static String systemRootPath;

    /**
     * tomcat_jdbc_pool 配置文件
     */
    public static final String TOMCATJDBCPOOLPROFILEPATH = systemRootPath+"conf/tomcat_jdbc_pool.properties";

}

tomcat_jdbc_pool.properties配置文件

#数据库URL
URL=jdbc:mysql://localhost:3306/test

#数据库驱动
DRIVER=com.mysql.jdbc.Driver

#用户名
USERNAME=root

#密码
PASSWORD=123456

#初始化创建连接数
INITIALSIZE=10

#连接池最大连接数
MAXACTIVE=100

#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被释放。设为0表示无限制
MAXIDLE=50

#最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接
MINIDLE=10

#最大建立连接等待时间
MAXWAIT=500

#超过removeAbandonedTimeout时间后,是否进行没用连接(废弃)的回收(默认为false,调整为true)
REMOVEABANDONED=true

#超过时间限制,回收没有用(废弃)的连接(默认为300秒,调整为180)
REMOVEABANDONEDTIMEOUT=180


本地logger日志,只在控制台打印,不需要配置文件

public class Local_Logger {

    static {
        String pattern = "%d{yyyy-MM-dd HH:mm:ss} %l - %m%n";
        Logger rootLogger = Logger.getRootLogger();
        rootLogger.setLevel(Level.DEBUG);
        rootLogger.addAppender(new ConsoleAppender((new PatternLayout(pattern))));
    }

}

常量key

public class TomcatJdbcPool_Constants {

    /**
     * 数据库URL
     */
    public static final String URL = "URL";
    /**
     * 数据库驱动
     */
    public static final String DRIVER = "DRIVER";
    /**
     * 用户名
     */
    public static final String USERNAME = "USERNAME";
    /**
     * 密码
     */
    public static final String PASSWORD = "PASSWORD";
    /**
     * 初始化创建连接数
     */
    public static final String INITIALSIZE = "INITIALSIZE";
    /**
     * 连接池最大连接数
     */
    public static final String MAXACTIVE = "MAXACTIVE";
    /**
     * 最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被释放。设为0表示无限制
     */
    public static final String MAXIDLE = "MAXIDLE";
    /**
     * 最小空闲连接:连接池中容许保持空闲状态的最小连接数量,低于这个数量将创建新的连接
     */
    public static final String MINIDLE = "MINIDLE";
    /**
     * 最大建立连接等待时间
     */
    public static final String MAXWAIT = "MAXWAIT";
    /**
     * 超过removeAbandonedTimeout时间后,是否进行没用连接(废弃)的回收(默认为false,调整为true)
     */
    public static final String REMOVEABANDONED = "REMOVEABANDONED";
    /**
     * 超过时间限制,回收没有用(废弃)的连接(默认为300秒,调整为180)
     */
    public static final String REMOVEABANDONEDTIMEOUT = "REMOVEABANDONEDTIMEOUT";
}

Tomcat JDBC Connection Pool连接池实现代码

public class T_JDBC_Pool {

    public static final Logger logger = Logger.getLogger(T_JDBC_Pool.class);

    private static DataSource dataSource = new DataSource();

    private static String url;
    private static String driver;
    private static String username;
    private static String password;
    private static int initialSize;
    private static int maxActive;
    private static int maxIdle;
    private static int minIdle;
    private static int maxWait;
    private static boolean removeAbandoned;
    private static int removeAbandonedTimeout;

    public static void init() {

        //加载本地logger
        new Local_Logger();

        Properties properties = null;

        try {

            properties = new Properties();
            properties.load(new FileInputStream(new File(CommonUtils.TOMCATJDBCPOOLPROFILEPATH)));

            url = properties.getProperty(TomcatJdbcPool_Constants.URL);
            driver = properties.getProperty(TomcatJdbcPool_Constants.DRIVER);
            username = properties.getProperty(TomcatJdbcPool_Constants.USERNAME);
            password = properties.getProperty(TomcatJdbcPool_Constants.PASSWORD);
            initialSize = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.INITIALSIZE));
            maxActive = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.MAXACTIVE));
            maxIdle = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.MAXIDLE));
            minIdle = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.MINIDLE));
            maxWait = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.MAXWAIT));
            removeAbandoned = Boolean.valueOf(properties.getProperty(TomcatJdbcPool_Constants.REMOVEABANDONED));
            removeAbandonedTimeout = Integer.valueOf(properties.getProperty(TomcatJdbcPool_Constants.REMOVEABANDONEDTIMEOUT));

            logger.debug("url : " + url);
            logger.debug("driver : " + driver);
            logger.debug("username : " + username);
            logger.debug("password : " + password);
            logger.debug("initialSize : " + initialSize);
            logger.debug("maxActive : " + maxActive);
            logger.debug("maxIdle : " + maxIdle);
            logger.debug("minIdle : " + minIdle);
            logger.debug("maxWait : " + maxWait);
            logger.debug("removeAbandoned : " + removeAbandoned);
            logger.debug("removeAbandonedTimeout : " + removeAbandonedTimeout);


        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        PoolProperties poolProperties = null;
        try {
            poolProperties = new PoolProperties();
            poolProperties.setUrl(url);
            poolProperties.setDriverClassName(driver);
            poolProperties.setUsername(username);
            poolProperties.setPassword(password);
            poolProperties.setInitialSize(initialSize);
            poolProperties.setMaxActive(maxActive);
            poolProperties.setMaxIdle(maxIdle);
            poolProperties.setMaxWait(maxWait);
            poolProperties.setRemoveAbandoned(removeAbandoned);
            poolProperties.setRemoveAbandonedTimeout(removeAbandonedTimeout);

            dataSource.setPoolProperties(poolProperties);

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

    }

    /**
     * 获取连接
     *
     * @return
     */
    public static Connection getConnection() {
        Connection connection = null;
        try {

            connection = dataSource.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }
}

测试调用类

public class Test_jdbc_pool {

    /**
     * 调用一次
     */
    @Test
    public void testQueryDataSource() {

        String querySql = "SELECT * FROM STUDENT";

        T_JDBC_Pool.init();
        Connection connection = T_JDBC_Pool.getConnection();

        Statement statement = null;
        ResultSet resultSet = null;

        try {
            statement = connection.createStatement();

            resultSet = statement.executeQuery(querySql);

            while (resultSet.next()) {
                System.out.print(resultSet.getString("studentId") + " ");
                System.out.print(resultSet.getString("studentName") + " ");
                System.out.print(resultSet.getString("studentAge") + " ");
                System.out.println(resultSet.getString("studentPhone"));
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                connection.close();
                statement.close();
                resultSet.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 测试并发调用
     * @param args
     */
    public static void main(String[] args) {
        Test_jdbc_pool t = new Test_jdbc_pool();
        t.ConcurrentTest();
    }

    public void ConcurrentTest() {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {

                while (true) {
                    testQueryDataSource();
                }

            }
        });
        thread1.start();

        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    testQueryDataSource();
                }
            }
        });
        thread2.start();
    }

}

这里哦一直有个疑问

从连接池取出一个连接,用完之后,datasource没有将 连接 返还至连接池的方法....

后来去官方提供的Demo中看了下,官方Demo也仅仅是close了连接,没有将连接返还至连接池....


等有空的时候,翻翻源码...后面再补上



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值