古老的榕树

JFinal 使用 HikariCP 数据库连接池

发表 2017-03-28 23:25 阅读(4382) 评论(0) 赞(2)

看了 HikariCP 的源码,比较感兴趣,想在 JFinal 中集成这样的数据库连接池,发现并没有支持的插件,于是自己动手尝试写了 JFinal  HikariCPPlugin 插件,得益于 JFinal 这么简洁的架构,几分钟时间就测试出炉了,肉眼测试,不严谨,如果有什么不妥的地方,希望网友补充斧正吧!


直接上代码,是程序员最喜欢干的事情:


package com.jfinal.plugin.hikaricp;

import javax.sql.DataSource;

import com.jfinal.plugin.IPlugin;
import com.jfinal.plugin.activerecord.IDataSourceProvider;
import com.zaxxer.hikari.HikariDataSource;

/**
 * @author 潘军杰 2017-02-28
 *
 */
public class HikariCPPlugin implements IPlugin, IDataSourceProvider {
    // 数据库连接字符串
    private String jdbcUrl;
    // 数据库用户名
    private String username;
    // 数据库连接密码
    private String password;
    // 数据库驱动类名
    private String driverClassName = null;

    // 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
    private int maxPoolSize = 10;
    // 一个连接 idle 状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟
    private long idleTimeoutMs = 600000;
    // 最小空闲数 默认 10
    private int minIdle = 10;
    // 一个连接的生命时长(毫秒),超时且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒,参考 MySQL
    // wait_timeout 参数(show variables like '%timeout%';)
    private long maxLifetimeMs = 1800000;
    // 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生 SQLException, 缺省:30秒
    private long connectionTimeoutMs = 30000;

    /**
     * hsqldb:"select 1 from INFORMATION_SCHEMA.SYSTEM_USERS" Oracle:"select 1
     * from dual" DB2:"select 1 from sysibm.sysdummy1" mysql:"select 1"
     */
    private String connectionTestQuery = "select 1";

    private HikariDataSource ds;
    private boolean isStarted = false;

    /**
     * 实例化
     * 
     * @param jdbcUrl
     *            数据库连接字符串
     *            如:jdbcUrl=jdbc:mysql://localhost:3306/dbname?useUnicode=true&autoReconnect=true&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useSSL=false
     * @param username
     *            数据库连接用户名
     * @param password
     *            数据库连接密码
     */
    public HikariCPPlugin(String jdbcUrl, String username, String password) {
	this.jdbcUrl = jdbcUrl;
	this.username = username;
	this.password = password;
    }

    @Override
    public boolean start() {
	if (isStarted) {
	    return true;
	}

	ds = new HikariDataSource();

	ds.setJdbcUrl(jdbcUrl);
	ds.setUsername(username);
	ds.setPassword(password);

	ds.setDriverClassName(driverClassName);

	ds.setConnectionTestQuery(connectionTestQuery);
	ds.setConnectionTimeout(connectionTimeoutMs);

	ds.setIdleTimeout(idleTimeoutMs);
	ds.setMaxLifetime(maxLifetimeMs);
	ds.setMaximumPoolSize(maxPoolSize);
	ds.setMinimumIdle(minIdle);

	isStarted = true;
	return true;
    }

    @Override
    public boolean stop() {
	if (ds != null) {
	    ds.close();
	}

	ds = null;
	isStarted = false;
	return true;
    }

    @Override
    public DataSource getDataSource() {
	return ds;
    }

    /**
     * 设置额外的关键参数
     * 
     * @param idleTimeoutMs
     *            单位毫秒 默认 600000 毫秒
     * @param maxLifetimeMs
     *            单位毫秒 默认 1800000 毫秒
     * @param maxPoolSize
     *            最大连接池数 默认 10 个
     * @param minIdle
     *            最小空闲数 默认 10 个
     * @return
     */
    public HikariCPPlugin set(long idleTimeoutMs, int maxLifetimeMs, int maxPoolSize, int minIdle) {
	this.idleTimeoutMs = idleTimeoutMs;
	this.maxLifetimeMs = maxLifetimeMs;
	this.maxPoolSize = maxPoolSize;
	this.minIdle = minIdle;
	return this;
    }

    /**
     * 设置数据库连接驱动类名
     * 
     * @param driverClassName
     * @return
     */
    public HikariCPPlugin setDriverClass(String driverClassName) {
	this.driverClassName = driverClassName;
	return this;
    }

    /**
     * 设置一个连接 idle 状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟
     * 
     * @param idleTimeoutMs
     * @return
     */
    public HikariCPPlugin setIdleTimeoutMs(long idleTimeoutMs) {
	this.idleTimeoutMs = idleTimeoutMs;
	return this;
    }

    /**
     * 设置一个连接的生命时长(毫秒),超时且没被使用则被释放(retired),缺省:30分钟,建议设置比数据库超时时长少30秒,参考 MySQL
     * wait_timeout 参数(show variables like '%timeout%';)
     * 
     * @param maxLifetimeMs
     * @return
     */
    public HikariCPPlugin setMaxLifetimeMs(int maxLifetimeMs) {
	this.maxLifetimeMs = maxLifetimeMs;
	return this;
    }

    /**
     * 设置连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
     * 
     * @param maxPoolSize
     * @return
     */
    public HikariCPPlugin setMaxPoolSize(int maxPoolSize) {
	this.maxPoolSize = maxPoolSize;
	return this;
    }

    /**
     * 设置最小空闲数 默认 10
     * 
     * @param minIdle
     * @return
     */
    public HikariCPPlugin setMinIdle(int minIdle) {
	this.minIdle = minIdle;
	return this;
    }

    /**
     * 设置连接测试查询
     * 
     * @param connectionTestQuery
     * @return
     */
    public HikariCPPlugin setConnectionTestQuery(String connectionTestQuery) {
	this.connectionTestQuery = connectionTestQuery;
	return this;
    }
}



使用方法,在 JFinal 配置文件中,配置插件,你懂的:


/**
 * 配置插件
*/
@Override
public void configPlugin(Plugins me) {
    HikariCPPlugin mysqlPool = new HikariCPPlugin(PropKit.get("jdbcUrl"),PropKit.get("user"),PropKit.get("password"));
    me.add(mysqlPool);

    // mysql ActiveRecrodPlugin 实例,并指定configName为 mysql
    ActiveRecordPlugin arpMysql = new ActiveRecordPlugin("mysql", mysqlPool);
    me.add(arpMysql);

    // 所有配置在 MappingKit 中搞定
   _MappingKit.mapping(arpMysql);
   ...
}


(完)

Donate

如果文章对您有帮助,请使用手机支付宝扫描二维码,捐赠X元,作者离不开读者的支持!

0 条网友评论

哇~~~ 竟然还没有评论!

称呼*
邮箱*
内容*
验证码*
验证码 看不清换张