Java -- JDBC 数据库连接池
1. 原理代码示例
public class JdbcPool implements DataSource {
private static LinkedList<Connection> list = new LinkedList<Connection>();
static{
try{
InputStream in = JdbcPool.class.getClassLoader().getResourceAsStream("db.properties");
Properties prop = new Properties();
prop.load(in);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
Class.forName(driver);
for(int i=0;i<10;i++){
Connection conn = DriverManager.getConnection(url, username, password);
System.out.println("获取到了链接" + conn);
list.add(conn);
}
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
/*
1.写一个子类,覆盖close方法
2、写一个connection的包装类,增强close方法
3、用动态代理,返回一个代理对象出去,拦截close方法的调用,对close进行增强
*/
public Connection getConnection() throws SQLException {
//proxyConnection.commit() proxyConnection.rollback
if(list.size()>0){
final Connection conn = list.removeFirst(); //myconnection.commit
System.out.println("池大小是" + list.size());
return (Connection) Proxy.newProxyInstance(JdbcPool.class.getClassLoader(), conn.getClass().getInterfaces(), new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(!method.getName().equals("close")){
return method.invoke(conn, args);
}else{
list.add(conn);
System.out.println(conn + "被还给池了!!");
System.out.println("池大小为" + list.size());
return null;
}
}
});
}else{
throw new RuntimeException("对不起,数据库忙");
}
}
public Connection getConnection(String username, String password)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PrintWriter getLogWriter() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public int getLoginTimeout() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
public void setLogWriter(PrintWriter arg0) throws SQLException {
// TODO Auto-generated method stub
}
public void setLoginTimeout(int arg0) throws SQLException {
// TODO Auto-generated method stub
}
}
/*
用包装设计模式对某个对象进行增强
1.写一个类,实现与被增强对象(mysql的connection)相同的接口
2、定义一个变量,指向被增强对象
3、定义一个构造方法,接收被增强对象
4、覆盖想增强的方法
5、对于不想增强的方法,直接调用被增强对象的方法
*/
class MyConnection implements Connection{
private Connection conn;
private List pool;
public MyConnection(Connection conn,List pool){
this.conn = conn;
this.pool = pool;
}
public void close() throws SQLException {
pool.add(conn);
}
public void clearWarnings() throws SQLException {
this.conn.clearWarnings();
}
public void commit() throws SQLException {
this.conn.commit();
}
public Statement createStatement() throws SQLException {
return this.conn.createStatement();
}
public Statement createStatement(int resultSetType, int resultSetConcurrency)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public Statement createStatement(int resultSetType,
int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public boolean getAutoCommit() throws SQLException {
// TODO Auto-generated method stub
return false;
}
public String getCatalog() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public int getHoldability() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
public DatabaseMetaData getMetaData() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public int getTransactionIsolation() throws SQLException {
// TODO Auto-generated method stub
return 0;
}
public Map<String, Class<?>> getTypeMap() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public SQLWarning getWarnings() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public boolean isClosed() throws SQLException {
// TODO Auto-generated method stub
return false;
}
public boolean isReadOnly() throws SQLException {
// TODO Auto-generated method stub
return false;
}
public String nativeSQL(String sql) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public CallableStatement prepareCall(String sql) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public CallableStatement prepareCall(String sql, int resultSetType,
int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PreparedStatement prepareStatement(String sql) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PreparedStatement prepareStatement(String sql, int[] columnIndexes)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PreparedStatement prepareStatement(String sql, String[] columnNames)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public PreparedStatement prepareStatement(String sql, int resultSetType,
int resultSetConcurrency, int resultSetHoldability)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
// TODO Auto-generated method stub
}
public void rollback() throws SQLException {
// TODO Auto-generated method stub
}
public void rollback(Savepoint savepoint) throws SQLException {
// TODO Auto-generated method stub
}
public void setAutoCommit(boolean autoCommit) throws SQLException {
// TODO Auto-generated method stub
}
public void setCatalog(String catalog) throws SQLException {
// TODO Auto-generated method stub
}
public void setHoldability(int holdability) throws SQLException {
// TODO Auto-generated method stub
}
public void setReadOnly(boolean readOnly) throws SQLException {
// TODO Auto-generated method stub
}
public Savepoint setSavepoint() throws SQLException {
// TODO Auto-generated method stub
return null;
}
public Savepoint setSavepoint(String name) throws SQLException {
// TODO Auto-generated method stub
return null;
}
public void setTransactionIsolation(int level) throws SQLException {
// TODO Auto-generated method stub
}
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
// TODO Auto-generated method stub
}
}
2. 开源连接池 •DBCP
数据库连接池
加入dbcp链接池
1.导入jar包
commons-dbcp-1.2.2.jar commons-pool.jar
2、在类目录下加入dbcp的配置文件:dbcpconfig.properties
3、在jdbcUtils的静态代码块中创建池
private static DataSource ds = null;
static{
try{
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties prop = new Properties();
prop.load(in); BasicDataSourceFactory factory = new BasicDataSourceFactory(); ds = factory.createDataSource(prop);
System.out.println(ds);
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
重写后的工具类
public class JdbcUtils_DBCP {
private static DataSource ds = null;
static{
try{
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties prop = new Properties();
prop.load(in);
BasicDataSourceFactory factory = new BasicDataSourceFactory();
ds = factory.createDataSource(prop);
System.out.println(ds);
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
public static void release(Connection conn,Statement st,ResultSet rs){
if(rs!=null){
try{
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try{
st.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
配置文档dbcpconfig.properties
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=root #<!-- 初始化连接 -->
initialSize=10 #最大连接数量
maxActive=50 #<!-- 最大空闲连接 -->
maxIdle=20 #<!-- 最小空闲连接 -->
minIdle=5 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000 #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:[属性名=property;]
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=UTF8 #指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true #driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly= #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=REPEATABLE_READ
3.开源数据库连接池 •C3P0
数据库连接池
配置文档 c3p0-config.xml 需要放在 src目录下,自动搜索
<?xml version="1.0" encoding="UTF-8"?> <!--
c3p0-config.xml
private static ComboPooledDataSource ds;
static{
try {
ds = new ComboPooledDataSource("c3p0config");
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
} --> <c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/transaction</property>
<property name="user">root</property>
<property name="password">123456</property> <property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">100</property> </default-config> <named-config name="c3p0config">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/transaction</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">100</property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
</named-config> </c3p0-config>
工具类:
public class JdbcUtils_C3P0 {
private static ComboPooledDataSource ds = null;
static{
try{
ds = new ComboPooledDataSource("c3p0config");
}catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
public static void release(Connection conn,Statement st,ResultSet rs){
if(rs!=null){
try{
rs.close();
}catch (Exception e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try{
st.close();
}catch (Exception e) {
e.printStackTrace();
}
}
if(conn!=null){
try{
conn.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
}
Java -- JDBC 数据库连接池的更多相关文章
- Java jdbc数据库连接池总结!(转)
1. 引言 近年来,随着Internet/Intranet建网技术的飞速发展和在世界范围内的迅速普及,计算机 应用程序已从传统的桌面应用转到Web应用.基于B/S(Browser/Server)架构的 ...
- JAVA jdbc(数据库连接池)学习笔记(二) SQL注入
PS:今天偶然间发现了SQL的注入...所以就简单的脑补了一下,都是一些简单的例子...这篇写的不怎么样...由于自己没有进行很深的研究... 学习内容: 1.SQL注入的概念... 所谓SQL注 ...
- JAVA jdbc(数据库连接池)学习笔记(一)
学习内容: 1.JDBC的含义... JDBC想必学过JAVA的就不会陌生,JDBC到底是什么呢?其实就是由JAVA的一些类和接口构成的API,保存在java.sql和javax.sql..包中的一些 ...
- JAVA jdbc(数据库连接池)学习笔记(转)
学习内容: 1.JDBC的含义... JDBC想必学过JAVA的就不会陌生,JDBC到底是什么呢?其实就是由JAVA的一些类和接口构成的API,保存在java.sql和javax.sql..包中的一些 ...
- Java自学-JDBC 数据库连接池
数据库连接池 与线程池类似的,数据库也有一个数据库连接池. 不过他们的实现思路是不一样的. 本章节讲解了自定义数据库连接池类:ConnectionPool,虽然不是很完善和健壮,但是足以帮助大家理解C ...
- JAVA之JDBC数据库连接池总结篇
JDBC数据库连接池 一.JDBC数据库连接池的必要性 二.数据库连接池技术 三.多种开源的数据库连接池 3.1 C3P0数据库连接池 3.2 DBCP数据库连接池 3.3 Druid(德鲁伊)数据库 ...
- JAVA基础知识之JDBC——JDBC数据库连接池
JDBC数据库连接池 数据库的连接和关闭是很耗费资源的操作,前面介绍的DriverManager方式获取的数据库连接,一个Connection对象就对应了一个物理数据库连接,每次操作都要打开一个连接, ...
- JDBC数据库连接池技术
在JDBC中,获得连接或释放资源是非常消耗系统资源的两个过程,为了解决此类性能问题,通常采用连接池技术,来共享连接.这样我们就不需要每次都创建连接.释放连接了,这些操作都交给了连接池. 用池的概念来管 ...
- java配置数据库连接池的方法步骤
java配置数据库连接池的方法步骤 java配置数据库连接池的方法步骤,需要的朋友可以参考一下 先来了解下什么是数据库连接池数据库连接池技术的思想非常简单,将数据库连接作为对象存储在一个Vecto ...
随机推荐
- TFS二次开发-基线文件管理器(5)-源码文件的读取
在上一节中,我们在保存标签之前,已经将勾选的文件路径保存到了Listbox中,这里只需要将保存的数据输出去为txt文档就可以做版本控制了. 版本文件比较复杂的是如何读取,也就是如何通过文件路径 ...
- event对象及各种事件
事件(event) event对象 (1)什么是event对象? Event 对象代表事件的状态,比如事件在其中发生的元素.键盘按键的状态.鼠标的位置.鼠标按钮的状态.事件通常与函数结合使用,函数不会 ...
- Vue中获取dom元素
Vue.js虽然说是数据驱动页面的,但是有时候我们也要获取dom对象进行一些操作. vue的不同版本获取dom对象的方法不一样 Vue.js 1.0版本中,通过v-el绑定,然后通过this.els ...
- Jquery的each遍历数据组成JSON
遍历每个标签的值 html代码: <volist name="parArr" id="item" key="$key"> ...
- python并发编程&多线程(二)
前导理论知识见:python并发编程&多线程(一) 一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性 官网链 ...
- 请听一个故事------>你真的认为iPhone只是一部手机?苹果惊天秘密!!
在网上看到的一篇小说,感觉有点意思,转载过来大家一起围观下,作者很幽默很风趣. 导读:iPhone的隐藏功能!Jobs的军方身份!图灵服毒自杀的传奇故事!中兴华为的神秘背景! 你真的认为iPhone只 ...
- django中的django admin插件
一.django admin前言 1.admin的作用 为了方便后台开发者快速的部署测试环境,于是就产生了admin,admin主要是操作models中的类从而实现对数据库中的数据增删改查的操作. 2 ...
- 前端基础之Bootstrap介绍
bootstrap简介 http://v3.bootcss.com/ Bootstrap优点: 下载: Bootstrap引入 <meta name="viewport" ...
- 预防SQL注入攻击
/** * 预防SQL注入攻击 * @param string $value * @return string */ function check_input($value) { // 去除斜杠 if ...
- 【转】Linux下查看进程打开的文件句柄数
---查看系统默认的最大文件句柄数,系统默认是1024 # ulimit -n 1024 ----查看当前进程打开了多少句柄数 # lsof -n|awk '{print $2}'|sort|uniq ...