连接池
概念: 是一个装载数据连接的容器.
当应用初始化好后, 容器被创建, 容器中会申请一些连接对象, 当用户来访问数据库时, 从容器中去拿连接对象, 用户访问完后, 会将连接对象归还给容器. (连接池)
优点: 节约资源, 操作高效.
实现:
通过标准接口实现: DataSource (javax.sql 包下)
一般不自己去写实现类, 有数据库厂商来做 (类似于 py 中的 DBUtils 中的 PooledDB 实现类)
-
C3P0: 一种数据库连接池技术
-
Druid: 数据库连接技术, 由阿里巴巴提供
常用方法:
-
getConnection(): 获取连接
-
Connection.close(): 归还连接
如果是连接对象 Connection 是从连接池中获取, 那么调用 close 方法是归还连接, 不是关闭.
C3P0
使用步骤:
-
导入 jar 包 (c3p0-0.9.5.2.jar 和 mchange-commons-java-0.2.12.jar)
不要忘记导入数据库驱动包 (mysql驱动)
-
定义配置文件
-
配置文件名称是固定的: c3p0.properties 或 c3p0-config.xml
-
配置文件路径: 直接放 src 目录下即可
-
-
创建数据库连接池对象 ComboPooledDataSource
-
获取连接对象: getConnection()
demo:
import com.mchange.v2.c3p0.ComboPooledDataSource; import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException; public class JdbcC3P0 { public static void main(String[] args) throws SQLException { // 创建数据连接池对象 (使用javax.sql 包下的DataSource 父类接口 指向子类引用, 多态写法) DataSource pool = new ComboPooledDataSource(); Connection conn = pool.getConnection(); // 打印连接对象 // com.mchange.v2.c3p0.impl.NewProxyConnection@33e5ccce [wrapping: com.mysql.jdbc.JDBC4Connection@5a42bbf4] System.out.println(conn); } }
配置文件: ( c3p0-config.xml )
<c3p0-config> <!-- 使用默认的配置读取连接池对象 --> <default-config> <!-- 连接参数 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://192.168.0.115:3306/JDBC</property> <property name="user">username</property> <property name="password">passwd</property> <!-- 连接池参数 --> <property name="initialPoolSize">5</property> <property name="maxPoolSize">10</property> <property name="checkoutTimeout">3000</property> </default-config> <!--另外的一个配置--> <named-config name="otherc3p0"> <!-- 连接参数 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property> <property name="user">root</property> <property name="password">root</property> <!-- 连接池参数 --> <property name="initialPoolSize">5</property> <property name="maxPoolSize">8</property> <property name="checkoutTimeout">1000</property> </named-config> </c3p0-config>
Druid
使用步骤:
-
导入 jar 包 druid-1.0.9.jar
-
定义配置文件
-
是 properties 形式
-
文件可以放在任意目录下, 通过路径加载配置文件
-
-
加载配置文件
-
获取数据库连接池对象: 通过工厂函数来获取: DruidDataSourceFactory.createDataSource()
-
获取连接 --> 获取执行对象 --> 处理结果集 --> 资源回收
JDBCDruidUtils 工具类:
import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties; /** * JDBCDruidUtils 工具类 */ public class JDBCDruidUtils { private static DataSource ds = null; static { try { // 加载配置文件 Properties pro = new Properties(); // 获取 src 路径下的文件 --> ClassLoader ClassLoader cl = JDBCDruidUtils.class.getClassLoader(); InputStream is = cl.getResourceAsStream("druid.properties"); pro.load(is); // 通过工厂函数 获取 数据库连接池 (传入配置文件) ds = DruidDataSourceFactory.createDataSource(pro); } catch (Exception e) { e.printStackTrace(); } } // 获取连接池对象 public static DataSource getDataSource(){ return ds; } // 获取连接对象 public static Connection getConnection() throws SQLException { return ds.getConnection(); } // 资源回收 public static void close(ResultSet ret, PreparedStatement pstat, Connection conn){ if (ret != null) { try { ret.close(); } catch (SQLException e) { e.printStackTrace(); } } if (pstat != null) { try { ret.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { ret.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
配置文件: ( druid.properties )
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://192.168.0.115:3306/JDBC
username=username
password=passwd
initialSize=5
maxActive=10
maxWait=3000
demo:
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class JdbcDruid { public static void main(String[] args) { Connection conn = null; PreparedStatement pstat = null; ResultSet ret = null; try { // 获取数据库连接 conn = JDBCDruidUtils.getConnection(); // 编写sql String sql = "select * from user where username = ?;"; // 获取执行 sql 对象 pstat = conn.prepareStatement(sql); // 给 sql 赋值 pstat.setString(1, "xiaoming"); // 执行sql ret = pstat.executeQuery(); // 读取一条记录 ret.next(); // 处理结果 ResultSet String passwd = ret.getString("passwd"); System.out.println(passwd); // 123 } catch (SQLException e) { e.printStackTrace(); } finally { JDBCDruidUtils.close(ret, pstat, conn); } } }
ending ~