mgds4j

尝试深入数据源与连接池的JAVA(mgds4j)实现

梦来梦往 2014-12-01 14:01

 

 

目录

1. 摘要 1

2. mgds4j的设计原理 1

3. mgds4jJAVA实现 2

3.1.mgds4j V1.0 2

3.2.mgds4j v1.1 3

3.3.mgds4j v2.0 3

3.4.mgds4j v2.1 4

4. mgds4j的问题 6

4.1.关于数据源连接池的关闭? 6

关于 梦来梦往: 6


1.摘要

我是这样来理解数据源与连接池这个名词的,数据源是使用连接池技术来缓存数据库连接资源对外工具包接口,连接池是一种在传统的jdbc上封装多个数据库Connection,来提高数据库访问效率的解决方案,也就是技术。

 

目前,比较流行的数据源有:

ApacheDBCP数据源,

开源牛人的C3P0数据源,

AlibabaDruid数据源,

Sourceforgeproxool数据源......

 

由于,在使用spring来开发JAVAWeb项目时,我们都可以很方便的加入各种数据源。但是,我在写一些比较小的JAVA项目时,却发现集成数据源不是很方便,或者说,本来就是一个小项目,加入一个数据源就比源项目要大的多,这样就有一点的不尝试的感觉。

而且,我也不想再在自己的项目中重复造同样的轮子,使用每次得到conncection用完之后,就和数据库断开连接的方式(这样效率不高,时间都浪费在获取连接的部分了)。

所以,我就有了自己写一个适合JAVA项目使用的精简版的数据源,取名为mgds4j,全称是mgang datasource for java

 

2.mgds4j的设计原理

在使用到数据源的时候,对数据源进行初始化。

---初始化连接池部分,默认5connection连接放到连接池向量中。

---要使用数据库连接,可以从数据源中获取,用完后归还到连接池中。

---当连接池中的可用连接数为0时,还有请求要使用连接的话,线程会等待2秒(默认);

  如果等待完成后,连接池中有可用的数据源连接就获取。

      如果等待完成后,连接池中还是没有可用的连接,数据源就会按照连接池的自动增长

属性来动态的创建数据库连接并放回到连接池中,这时连接池的总大小也会随之增 大。

切记,在程序退出时,请调用数据源的destory方法来关闭数据源和连接池,释放资源。

 

3.mgds4jJAVA实现

这个项目,我是放在github上来管理的。目前完成了基本的功能,有多个版本,v2.1是最终版。这里,我就慢慢地说一下实现的各个版本的细微差别。

3.1.mgds4j V1.0

mgds4j - 梦来梦往2013 - 梦来梦往的博客

  

上图是第一个版本v1.0的项目目录结构,这里我有两个住文件MgDataSource.javaMgConnectionPool.java。很明显,我在写第一个版本的时候,对数据源与连接池的概念理解的不是很清晰,把他们分成了两个东西。但是功能都还是实现了,只不过多个一层。

接着看source floderconfig中的mgds4j.properties文件,很明显这个版本是用properties文件来做配置文件的。

Mgds4j.properties文件内容如下:

#meigang datasource for java 

#梦来梦往 自己实现的数据源连接池 工具,自命名为mgds4j

#数据库驱动

mgds4j.driverName = com.mysql.jdbc.Driver

#数据库连接url

mgds4j.url = jdbc:mysql://localhost:3306/mgds4j?useUnicode=true&characterEncoding=UTF-8

#数据库用户名

mgds4j.userName = root

#数据库密码

mgds4j.password = root

#自动增长的大小,默认为1

mgds4j.autoIncrement = 1

#连接池的大小,默认为5个connection

mgds4j.poolSize = 5 

并且测试通过。

 

这里,大家不要担心,我是在github上写的,所以是开源的,欢迎大家来fork

Github:https://github.com/mg0324/mgds4j.git

gitOsChina:https://git.oschina.net/mgang/mgds4j.git

 

3.2.mgds4j v1.1

这个版本较v1.0没有太大的改动,只是将等待时间抽成了参数,可以在配置文件中配置了。

#v1.1,等待时间,单位是ms(毫秒)

mgds4j.waitTimeOut = 3000


3.3.mgds4j v2.0

V2.0升级日志:

---将两个主文件合并成一个主文件MgDataSource.java,使得更契合数据源和连接池的 概念。

 

项目目录结构:

mgds4j - 梦来梦往2013 - 梦来梦往的博客

 测试通过。

 

3.4.mgds4j v2.1

V2.1升级日志:

---考虑到主流的配置文件是xml,故将配置文件修改成mgds4j.xml,使用dom4j解析。

---使数据源单例化,从MgDataSourceFactory工厂中获取,使用反射机制来实现。

项目目录结构:

mgds4j - 梦来梦往2013 - 梦来梦往的博客

 测试通过。

细节部分:

Mgds4j.xml配置文件:

<?xml version="1.0" encoding="utf-8" ?>

<factory>

<!-- 数据源节点,name属性是放在DataSourceFactory中的key,class属性是用来反射生成MgDataSource对象的

 -->

<dataSource name="ds" class="com.mgang.mgds4j.core.MgDataSource">

<!-- property节点,就是配置的MgDataSource的属性 -->

<property key="driverName" value="com.mysql.jdbc.Driver" type="string"></property>

<property key="url" type="string"

value="jdbc:mysql://localhost:3306/mgds4j?useUnicode=true&characterEncoding=UTF-8"></property>

<property key="userName" value="root" type="string"></property>

<property key="password" value="root" type="string"></property>

<property key="autoIncrement" value="1" type="int"></property>

<property key="poolSize" value="5" type="int"></property>

<property key="waitTimeOut" value="3000" type="int"></property>

</dataSource>

</factory>

  

反射细节:

//通过调用static函数getInstance来得到单例对象

Class dsClass = Class.forName(clazz);

ds = (MgDataSource) dsClass.getMethod("getInstance"null).invoke(dsClassnull);

factory.put(nameds);

//得到dataSource下的property节点

Iterator ps = dsElement.elementIterator("property"); 

while(ps.hasNext()){

Element propertyElement = (Element) ps.next();

String key = propertyElement.attributeValue("key");

String value = propertyElement.attributeValue("value");

String type = propertyElement.attributeValue("type");

if(type.equals("string")){

Method m = MgDataSource.class.getMethod("set"+UpperFirst(key),String.class);

m.invoke(dsvalue);

}else if(type.equals("int")){

Method m = MgDataSource.class.getMethod("set"+UpperFirst(key),int.class);

m.invoke(ds, Integer.parseInt(value.trim()));

}

}

单例细节:

private static MgDataSource mgds = null;

private MgDataSource(){

}

/**

 * 得到MgDataSource的单例对象

 * @return

 */

public static MgDataSource getInstance(){

if(null == mgds){

mgds = new MgDataSource();

}

return mgds;

}


 工厂模式细节:

//创建工厂

MgDataSourceFactory.build();

//从工厂得到数据源

ds = MgDataSourceFactory.getMgDataSource("ds");


 

 

4.mgds4j的问题

4.1.关于数据源连接池的关闭?

答:向c3p0数据源,在配置的时候就会在dataSource节点上配置一个destory属性来关闭数据源。Destory=close,意思就是在项目关闭的时候调用数据源的close方法来关闭数据源。

所以,连接池的关闭应该是在程序退出或者是项目关闭的时候关闭的。Mgds4j提供了destory方法来关闭数据源的连接池,来释放资源。(手动添加)

 

未完待续...

 

关于 梦来梦往:

QQ:1092017732

网易博客:http://blog.163.com/mg_blog/

Github:https://github.com/mg0324/mgds4j

gitOsChina:http://git.oschina.net/mgang/mgds4j

在线展示:http://mg0324.github.io/mgds4j/

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值