这几天花了点时间弄了个 db4o 连接池,比较简单,连接池原型是论坛上面的一篇文章。很简单,欢迎拍砖。
从 servlet 开始,在这里初始化连接池:
package
com;
import
java.io.File;
import
java.util.Enumeration;
import
javax.servlet.ServletConfig;
import
javax.servlet.ServletException;
import
javax.servlet.http.HttpServlet;
public
class
ConnectionPollServlet
extends
HttpServlet {
private
static
final
String XML_FILE_PROPERTY
=
"
xmlFile
"
;
/**
* servlet init
*/
public
void
init(ServletConfig servletConfig)
throws
ServletException{
super
.init(servletConfig);
String appDir
=
servletConfig.getServletContext().getRealPath(
"
/
"
);
Enumeration names
=
servletConfig.getInitParameterNames();
while
(names.hasMoreElements()){
String name
=
(String) names.nextElement();
String value
=
servletConfig.getInitParameter(name);
if
(name.equals(XML_FILE_PROPERTY)) {
File file
=
new
File(value);
if
(file.isAbsolute()) {
XMLReader.configure(value);
}
else
{
XMLReader.configure(appDir
+
File.separator
+
value);
}
}
}
}
/**
* servlet destroy
*/
public
void
destroy() {
super
.destroy();
ConnectionPoll.destroy();
}
}
然后是 XML 解析类:
package
com;
import
java.io.File;
import
org.dom4j.Document;
import
org.dom4j.DocumentException;
import
org.dom4j.Element;
import
org.dom4j.io.SAXReader;
public
class
XMLReader {
/**
* parse XML file
*
@param
xmlFileName
*/
public
static
void
configure(String xmlFileName) {
try
{
File file
=
new
File(xmlFileName);
SAXReader reader
=
new
SAXReader();
Document doc
=
reader.read(file);
Element root
=
doc.getRootElement();
String fileName
=
file.getParent()
+
"
\\
"
+
root.elementText(
"
fileName
"
);
String sport
=
root.elementText(
"
port
"
);
String sminConn
=
root.elementText(
"
minConn
"
);
String sidelTime
=
root.elementText(
"
idelTime
"
);
int
port
=
Integer.parseInt(sport);
int
minConn
=
Integer.parseInt(sminConn);
int
idelTime
=
Integer.parseInt(sidelTime);
ConnectionPoll.init(fileName,port,minConn,idelTime);
}
catch
(DocumentException e) {
e.printStackTrace();
}
}
}
连接池类:
package
com;
import
java.util.concurrent.ConcurrentLinkedQueue;
import
com.db4o.Db4o;
import
com.db4o.ObjectContainer;
import
com.db4o.ObjectServer;
public
class
ConnectionPoll {
private
static
int
idelTime;
private
static
ConcurrentLinkedQueue
<
ObjectContainer
>
connectionQueue;
private
ConnectionPoll(){
}
/**
* init pool
*/
protected
static
void
init(String fileName,
int
port,
int
minConn,
int
it) {
idelTime
=
it;
ObjectServer objectServer
=
Db4o.openServer(fileName,port);
connectionQueue
=
new
ConcurrentLinkedQueue
<
ObjectContainer
>
();
for
(
int
i
=
0
; i
<
minConn; i
++
) {
connectionQueue.offer(objectServer.openClient());
}
}
/**
* get connection
*
@return
ObjectContainer
*
@throws
ConnectionTimeoutException
*
@throws
InterruptedException
*/
public
static
synchronized
ObjectContainer getConnection()
throws
ConnectionTimeoutException{
long
expiration
=
System.currentTimeMillis()
+
idelTime;
while
(connectionQueue.isEmpty())
{
if
(expiration
<
System.currentTimeMillis())
{
throw
new
ConnectionTimeoutException(
"
connection timeout!
"
);
}
}
ObjectContainer objectContainer
=
connectionQueue.poll();
return
objectContainer;
}
/**
* release connection
*
@return
ObjectContainer
*
@throws
InterruptedException
*/
public
static
synchronized
void
releaseConnection(ObjectContainer objectContainer) {
connectionQueue.offer(objectContainer);
}
/**
* destroy connection
*
*/
protected
static
void
destroy() {
while
(connectionQueue.iterator().hasNext()){
ObjectContainer objectContainer
=
connectionQueue.poll();
objectContainer.close();
}
}
}
超时异常类:
package
com;
public
class
ConnectionTimeoutException
extends
Exception{
public
ConnectionTimeoutException()
{
}
public
ConnectionTimeoutException(String s)
{
super
(s);
}
}
XML 配置文件,从上到下依次是,数据库文件名、端口、初始连接数、等待时间:
<?
xml version="1.0" encoding="utf-8"
?>
<
config
>
<
fileName
>
auto.yap
</
fileName
>
<
port
>
1010
</
port
>
<
minConn
>
10
</
minConn
>
<
idelTime
>
1000
</
idelTime
>
</
config
>
web.xml 用于初始化的时候加载:
<?
xml version="1.0" encoding="UTF-8"
?>
<!
DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"
>
<
web-app
>
<
servlet
>
<
servlet-name
>
ConnectionPoll
</
servlet-name
>
<
servlet-class
>
com.ConnectionPollServlet
</
servlet-class
>
<
init-param
>
<
param-name
>
xmlFile
</
param-name
>
<
param-value
>
WEB-INF/poolConfig.xml
</
param-value
>
</
init-param
>
<
load-on-startup
>
1
</
load-on-startup
>
</
servlet
>
</
web-app
>
数据库文件和参数配置文件都放在 WEB-INF 文件夹下。这个连接池还未实现 maxConn(最大连接数)和对多数据库文件的支持以及日志等。