数据库连接池proxool的使用
浅析数据库连接池
什么是数据库连接池?为什么要使用数据库连接池?这是我们看到数据库连接池首先想到的问题。下面笔者将对数据库连接池以自己的理解进行简单的分析。
数据库连接池:顾名思义,连接数据库的一个池子。那么,你可能会问为什么要用一个池子去连接数据库,这个池子中都存在什么?对,为什么我们不直接使用数据库连接而要用一个池子呢?这是因为,数据库连接是一种很昂贵的资源,每一次数据库的连接将要付出很大的空间、时间代价,为此,我们建立一个池子,在这个池子中存放已经连接好的数据库对象,当我们要用到数据库的时候直接从数据库连接池去取已经连接好的对象直接使用,从而避免每一次操作数据库都先去连接的代价。原理图解:
-浅谈 proxool:
Proxool是一种Java数据库连接池技术。是sourceforge下的一个开源项目,这个项目提供一个健壮、易用的连接池,最为关键的是这个连接池提供监控的功能,方便易用,便于发现连接泄漏的情况。使用 proxool:
1.导入jar包
包括数据库mysql的连接jar包,proxool的核心jar包,最重要的是还要包含日志common、log4j的jar包,否则将会报nullPoint空指针异常。
2.在WEB-INF下中web.xml建立同级文件proxool.xml文件
proxool.xml文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<something-else-entirely>
<proxool>
<!-- 配置proxool别名 -->
<alias>mp</alias>
<!-- 配置数据库的连接信息 ?characterEncoding=UTF-8 -->
<driver-url>jdbc:mysql://localhost:3306/flowershop?characterEncoding=UTF-8</driver-url>
<driver-class>com.mysql.jdbc.Driver</driver-class>
<driver-properties>
<property name="user" value="user"/>
<property name="password" value="user"/>
</driver-properties>
<!-- 最大连接数 -->
<maximum-connection-count>100</maximum-connection-count>
<!-- 最小连接数 -->
<minimum-connection-count>10</minimum-connection-count>
<house-keeping-test-sql>select CURRENT_DATE</house-keeping-test-sql>
</proxool>
</something-else-entirely>
3.修改数据库连接工具类DbUtil.java
package cn.com.mp.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class DbUtil {
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("数据库驱动加载异常,请检查!");
e.printStackTrace();
}
}
private Connection conn = null;
private Statement stat = null;
private PreparedStatement ps = null;
private ResultSet rs = null;
private ResultSetMetaData rst = null;
private Connection setConn() {
try {
//修改getConnection(“proxool.别名”)
conn = DriverManager.getConnection("proxool.mp");
} catch (Exception e) {
System.out.println("数据源连接失败,请检查!");
}
return conn;
}
private PreparedStatement setPs(String sql) {
setConn();
try {
ps = conn.prepareStatement(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("创建查询结果集失败,请检查!");
e.printStackTrace();
}
return ps;
}
private void toClose() {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("查询结果集关闭失败!");
e.printStackTrace();
}
}
if (stat != null) {
try {
stat.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("语句对象关闭失败!");
e.printStackTrace();
} finally {
stat = null;
}
}
if (ps != null) {
try {
ps.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("语句对象关闭异常!");
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("数据源关闭失败!");
e.printStackTrace();
}
}
}
public int update(String sql, Object... obj) {
ps = setPs(sql);
try {
for (int i = 0; i < obj.length; i++) {
ps.setObject(i + 1, obj[i]);
}
return ps.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("更新失败,请检查!");
e.printStackTrace();
} finally {
toClose();
}
return -1;
}
public int update(String sql) {
return update(sql, new Object[] {});
}
public List<Map<String, Object>> query(String sql, Object... obj) {
List<Map<String, Object>> list = new LinkedList<Map<String, Object>>();
setPs(sql);
//System.out.println("哈哈哈哈哈");
//System.out.println(obj.length);
try {
for (int i = 1; i <= obj.length; i++) {
//System.out.println(obj[i - 1]+"**//");
ps.setObject(i, obj[i - 1]);
//System.out.println(ps);
}
//System.out.println(ps.getMetaData());
/*错误为:rs.next()为false直接跳出while循环*/
rs = ps.executeQuery();
rst = rs.getMetaData();
while (rs.next()) {
//System.out.println("haiglfdh");
Map<String, Object> map = new HashMap<String, Object>();
for (int i = 1; i <= rst.getColumnCount(); i++) {
String key = rst.getColumnName(i);
map.put(key, rs.getString(key));
//System.out.println("map:"+map.get(key));
}
list.add(map);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
System.out.println("查询出现异常!");
e.printStackTrace();
} finally {
toClose();
}
//System.out.println("list:"+list);
return list;
}
public List<Map<String, Object>> query(String sql) {
return query(sql, new Object[] {});
}
public void batch(String strs[]) {
try {
stat = setConn().createStatement();
conn.setAutoCommit(false);
for (String st : strs) {
stat.addBatch(st);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
stat.executeBatch();
} catch (SQLException e) {
// TODO Auto-generated catch block
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
conn.commit();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
toClose();
}
}
- 总结
无论大大小小的项目,都会使用到数据库,然后数据库的操作代价非常高,使用数据库连接池中已经连接好的对象,避免重复多次的连接操作,可以从某种程度上大大提高项目的整体效率,学习如何使用数据库连接池是非常有必要的,当然数据库连接池不仅仅只有proxool一种,还要很多种比如:C3P0等等,但是原理都是相同的,不同之处在于,各自拥有的特性,你可以根据喜好选择使用。
以上是笔者简单的自我学习,如有不对之处,还请指教。