初识数据库连接池开源框架Druid
Druid是阿里巴巴的一个数据库连接池开源框架,准确来说它不仅仅包括数据库连接池这么简单,它还提供强大的监控和扩展功能。本文仅仅是在不采用Spring框架对Druid的窥探,采用目前最新版本druid1.0.26 github地址:https://github.com/alibaba/druid。
在开始之前还是再说说为什么不配套使用Spring来使用Druid连接池,原因其实很简单,在Spring框架的配置文件中仅仅一个配置datasource就可以使用Druid了。那到底配置这个datasource数据源时Spring到底对它做了什么呢?它到底是怎么来实现这个datasource数据源的呢?如果不知其二只知其一,那才真是只是个搬砖的。
下面我们正式开始吧,首先还是一览工程包结构。

同样有两个jar需要引入,一是druid,二是mysql-connector。

我们首先实现util包里的DBPoolConnection类,这个类用来创建数据库连接池单例以及返回一个数据库连接。为什么数据库连接池需要单例呢?原因其实很简单,我们可以想象在一个web应用中,同时可能会存在多个请求如果为每一个请求都创建一个数据库连接池,那还有什么意义呢?应该是不论有多少个并发请求,都应该只存在一个数据库连接池,在这个数据库连接池中为每个请求创建一个数据库连接。
package util; import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.SQLException;
import java.util.Properties; import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.pool.DruidPooledConnection; /**
* 要实现单例模式,保证全局只有一个数据库连接池
* @author ylf
*
* 2016年10月21日
*/
public class DBPoolConnection {
private static DBPoolConnection dbPoolConnection = null;
private static DruidDataSource druidDataSource = null; static {
Properties properties = loadPropertiesFile("db_server.properties");
try {
druidDataSource = (DruidDataSource)DruidDataSourceFactory.createDataSource(properties); //DruidDataSrouce工厂模式
} catch (Exception e) {
e.printStackTrace();
}
} /**
* 数据库连接池单例
* @return
*/
public static synchronized DBPoolConnection getInstance(){
if (null == dbPoolConnection){
dbPoolConnection = new DBPoolConnection();
}
return dbPoolConnection;
} /**
* 返回druid数据库连接
* @return
* @throws SQLException
*/
public DruidPooledConnection getConnection() throws SQLException{
return druidDataSource.getConnection();
}
/**
* @param string 配置文件名
* @return Properties对象
*/
private static Properties loadPropertiesFile(String fullFile) {
String webRootPath = null;
if (null == fullFile || fullFile.equals("")){
throw new IllegalArgumentException("Properties file path can not be null" + fullFile);
}
webRootPath = DBPoolConnection.class.getClassLoader().getResource("").getPath();
webRootPath = new File(webRootPath).getParent();
InputStream inputStream = null;
Properties p =null;
try {
inputStream = new FileInputStream(new File(webRootPath + File.separator + fullFile));
p = new Properties();
p.load(inputStream);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (null != inputStream){
inputStream.close();
}
} catch (Exception e) {
e.printStackTrace();
}
} return p;
} }
第26行代码实例化一个DruidDataSource时,我们可以通过Druid框架为我们提供的DruidDataSourceFactory创建出一个DruidDataSource实例,工厂模式给我们提供了大大的便利。
第36行getInstance方法为我们创建出一个数据库连接池实例,这里即用到了单例模式,在这个地方我们可以使用synchronized方法来对getInstance加锁(懒加载)实现线程安全,同时我们也可以使用勤加载来实现线程安全即去掉synchronized关键字,删掉37-39行代码,将第20行代码修改为private static DBPoolConnection dbPoolConnection = new DBPoolConnection()。这两种方式各有其优缺点,懒加载好处就是“用到才实例化”,缺点就是“synchronized关键字对方法加锁的粒度稍稍有点大,采用同步的方式实现线程安全会带来额外的开销”,而勤加载的好处就是“不使用同步的方式实现线程安全,省去了同步机制带来的额外开销”,缺点即是“未用到也会实例化”。至于怎么选择,根据实际情况。这里是之前对单例模式的两篇博文,《单例模式》、《再说单例模式的线程安全问题》。
第55行代码loadPropertiesFile方法是对properties配置文件的加载。
我们在这个类所做的工作差不多就是在spring配置文件中的那一句<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">。很简单的一句话,这就是为什么我不想使用Spring框架来配合使用Druid,因为这只会造成只知其一不知其二的结果。
我们接在来实现dao包中的DruidDao类,开始对数据进行持久化操作。由于我们没有用到MyBatis等持久层框架,所以我们不得不使用JDBC来操作数据库,虽然麻烦一点,但这是所有所有框架的基础。
/**
*
*/
package dao; import java.sql.PreparedStatement;
import java.sql.SQLException; import com.alibaba.druid.pool.DruidPooledConnection; import util.DBPoolConnection; /**
* @author ylf
*
* 2016年10月21日
*/
public class DruidDao { public void insert(String sql){
DBPoolConnection dbp = DBPoolConnection.getInstance(); //获取数据连接池单例
DruidPooledConnection conn = null;
PreparedStatement ps = null;
try {
conn = dbp.getConnection(); //从数据库连接池中获取数据库连接
ps = conn.prepareStatement(sql);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (null != ps){
ps.close();
}
if (null != conn){
conn.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
我们只对数据做插入操作。下面我们测试一下,各个属性的含义可参考:https://github.com/alibaba/druid/wiki/DruidDataSource%E9%85%8D%E7%BD%AE%E5%B1%9E%E6%80%A7%E5%88%97%E8%A1%A8
/**
*
*/
package test; import dao.DruidDao; /**
* @author ylf
*
* 2016年10月21日
*/
public class Client { /**
* @param args
*/
public static void main(String[] args) {
DruidDao druidDao = new DruidDao();
String sql = "insert into test (name) values(\"keven\")";
druidDao.insert(sql);
} }
查看数据库插入成功。
另外db_server.properties数据库的配置文件如下:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/DruidTest
username=root
password=0000
filters=stat
initialSize=2
maxActive=300
maxWait=60000
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
validationQuery=SELECT 1
testWhileIdle=true
testOnBorrow=false
testOnReturn=false
poolPreparedStatements=false
maxPoolPreparedStatementPerConnectionSize=200
初识数据库连接池开源框架Druid的更多相关文章
- 初识轻量级Java开源框架 --- Spring
初识轻量级Java开源框架 --- Spring 作者:egg 微博:http://weibo.com/xtfggef 出处:http://blog.csdn.net/zhangerqing spri ...
- 数据库连接池优化配置(druid,dbcp,c3p0)
主要描述了数据库连接池参数配置的准则,针对常用的数据库连接池(c3p0,dbcp,druid)给出推荐的配置. 考虑因素 1:当前连接DB的规模 2:并发情况 3:执行db的响应时间 配置考虑 1 ...
- 从零开始学 Java - 数据库连接池的选择 Druid
我先说说数据库连接 数据库大家都不陌生,从名字就能看出来它是「存放数据的仓库」,那我们怎么去「仓库」取东西呢?当然需要钥匙啦!这就是我们的数据库用户名.密码了,然后我们就可以打开门去任意的存取东西了. ...
- 数据库连接池的选择 Druid
我先说说数据库连接 数据库大家都不陌生,从名字就能看出来它是「存放数据的仓库」,那我们怎么去「仓库」取东西呢?当然需要钥匙啦!这就是我们的数据库用户名.密码了,然后我们就可以打开门去任意的存取东西了. ...
- 【Druid】 阿里巴巴推出的国产数据库连接池com.alibaba.druid.pool.DruidDataSource
阿里巴巴推出的国产数据库连接池,据网上测试对比,比目前的DBCP或C3P0数据库连接池性能更好 简单使用介绍 Druid与其他数据库连接池使用方法基本一样(与DBCP非常相似),将数据库的连接信息 ...
- 数据库连接池(c3p0与druid)
1.数据库连接池概念 其实就是一个容器(集合),存放数据库连接的容器.当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归 ...
- 【spring boot】15.spring boot项目 采用Druid数据库连接池,并启用druid监控功能
在http://www.cnblogs.com/sxdcgaq8080/p/9039442.html的基础上,来看看spring boot项目中采用Druid连接池. GitHub地址:示例代码 == ...
- Mybatis技术一数据库连接池配置(druid)
只简单叙述,网上相关的内容很多,这里只是给出参考: 数据库连接池druid配置列表: 配置 缺省值 说明 name 配置这个属性的意义在于,如果存在多个数据源,监控的时候可以通过名字来区分开来.如 ...
- 【Java进阶】——初识数据库连接池
[简介] 数据库连接池:程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的链接进行申请,使用,释放. 相比之前的程序连接,减少了数据库的打开关闭次数,从而减少了程序响应的 ...
随机推荐
- Nagios安装部署
p.MsoNormal,li.MsoNormal,div.MsoNormal { margin: 0cm; margin-bottom: .0001pt; line-height: 150%; fon ...
- 重温Javascript(二)
对象 可以想象成散列表,键值对,值可以是数据或函数 创建对象的方式 1.工厂模式 function createPerson(name, age, job){ var o = new Object() ...
- 手机自动化测试:Appium源码之API(2)
手机自动化测试:Appium源码之API(2) TouchAction AppiumDriver的辅助类,主要针对手势操作,比如滑动.长按.拖动等.TouchAction的原理是讲一系列的动作放在 ...
- Gson解析复杂的Bean类实现Parcelable
import java.util.ArrayList; import android.os.Parcel; import android.os.Parcelable; import android.s ...
- Mybatis基础学习(四)—关系映射
一.模型分析 user和orders user---->orders 一个用户可以创建多个订单,一对多. orders--->user 一个订单只由一个用户创建,一对一. orders ...
- Java ClassLoader加载机制
一.体系结构(自上向下) 1.Bootstrap ClassLoader(BootStrapClassLoader) --- 启动类加载器或者叫引导类加载器,加载jdk核心的APIs,这些APIs一般 ...
- FunDA:一个开源的函数式数据处理工具库,也是Slick的补充
如果你是一个Slick用户,或者你是一个数据库编程人员正在尝试进入函数式编程模式,那么FunDA可能会帮到你. 目前市面上FRM(Functional Relational Mapper),即函数式的 ...
- 设置ZooKeeper服务器地址列表源码解析及扩展
设置ZooKeeper服务器地址列表源码解析及扩展 ZooKeeper zooKeeper = new ZooKeeper("192.168.109.130:2181",SESSI ...
- 浩哥解析MyBatis源码(八)——Type类型模块之TypeAliasRegistry(类型别名注册器)
原创作品,可以转载,但是请标注出处地址:http://www.cnblogs.com/V1haoge/p/6705769.html 1.回顾 前面几篇讲了数据源模块,这和之前的事务模块都是enviro ...
- 如何在 FineUIMvc 中引用第三方 JavaScript 库
声明:FineUIMvc(基础版)是免费软件,本系列文章适用于基础版. 引入第三方颜色选择器 在 FineUIMvc 中使用第三方 JavaScript 遵循一定的约定,也非常简单. 下面以官网示例为 ...