JCBC——各种连接池的使用
各种连接池的使用
0、 目录
❝这里整理一下主要目录
1、 自定义JDBC
2、c3p0
3、dpcp
4、druid
5、小结
❞
0、 目录
前言
1、 自定义JDBC
1.1 配置文件和maven依赖
1.2 创建mysql数据库
1.3 创建对应模型beam类
1.4 建立Dao层
1.5 JDBC工具类
1.6 mysql插入数据
1.7 JDBC 查询数据
2、c3p0
2.1 配置文件和maven依赖
2.2 c3p0Util类
2.3 其它工作
2.4 c3p0查询数据
3、dbcp
3.1 配置文件和maven依赖
3.2 DBCPUtil类
3.3 复制自定义JDBC
3.4 dbcp查询数据
4、druid
4.1 配置文件和maven依赖
4.2 DruidUtil类
4.3 复制自定义JDBC
4.4 druid查询数据
5、 小结
5.1 小结
5.2 使用连接池步骤
前言
时隔了快一年的JDBC后文 (-_-!)
前文
->
1、 自定义JDBC
1.1 配置文件和maven依赖
1.1.1 导入maven依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
1.1.2 配置文件
#db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
user=root
password=yuyubuyu
minPoolSize=5
1.2 创建mysql数据库
1.3 创建对应模型beam类
public class User {
private Integer id; // 用户id
private String name; // 用户姓名
private Integer age; // 用户年龄
//Getter() and Setter()
}
1.4 建立Dao层
1.4.1 接口
public interface UserDao {
List<User> fetchUsers();
}
1.4.2 实现类
public class UserDaoImpl implements UserDao {
@Override
public List<User> fetchUsers() {
try {
String sql = "select * from tb_user";
Connection connection = JDBCUtil.getConnection();
List<Map<String, Object>> data =
JDBCUtil.query(connection, sql);
if(data==null) return null;
List<User> list = new ArrayList<>();
for (Map<String, Object> datum : data) {
User user = new User();
user.setId((Integer) datum.get("id"));
user.setName((String) datum.get("name"));
user.setAge((Integer) datum.get("age"));
list.add(user);
}
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
1.4.3 代理
public class UserDaoProxy implements UserDao{
UserDao userDao = new UserDaoImpl();
@Override
public List<User> fetchUsers() {
return userDao.fetchUsers();
}
}
1.4.4 工厂
public class DaoFactory {
public static UserDaoProxy newUserDao(){
return new UserDaoProxy();
}
}
1.5 JDBC工具类
public class JDBCUtil {
private static String driver;
private static String url;
private static String user;
private static String password;
// private static int maxPoolSize;
private static int minPoolSize;
private static LinkedList<Connection> connections = new LinkedList<>();
static{
try {
Properties properties = new Properties();
properties.load(JDBCUtil.class.getClassLoader().getResourceAsStream("db.properties"));
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("password");
if(properties.getProperty("minPoolSize")==null||"".equals(properties.getProperty("minPoolSize")))
minPoolSize = 5;
else minPoolSize = Integer.parseInt(properties.getProperty("minPoolSize"));
Class.forName(driver);
for( int i = 0; i < minPoolSize; i++ ){
connections.addLast(DriverManager.getConnection(url, user, password));
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
private JDBCUtil(){}
public static int update(Connection connection, PreparedStatement ps, String sql, Object... objects){
if(connection==null||sql==null||"".equals(sql)){
return 0;
}
try {
ps = connection.prepareStatement(sql);
for( int i = 0; i < objects.length; i++ ){
ps.setObject(i+1, objects[i]);
}
int count = ps.executeUpdate();
release(null, ps, null);
return count;
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
public static List<Map<String, Object>> query(Connection connection, String sql, Object... objects){
try {
List<Map<String, Object>> list = new ArrayList<>();
PreparedStatement ps = connection.prepareStatement(sql);
for( int i = 0; i < objects.length; i++ ){
ps.setObject(i+1, objects[i]);
}
ResultSet rs = ps.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
int cols_len = metaData.getColumnCount();
while (rs.next()) {
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < cols_len; i++) {
String cols_name = metaData.getColumnName(i + 1);
Object cols_value = rs.getObject(cols_name);
map.put(cols_name, cols_value);
}
list.add(map);
}
release(null, ps, rs);
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static Connection getConnection() throws SQLException {
if( connections.size() > 0 ) {
return connections.removeFirst();
}
return DriverManager.getConnection(url, user, password);
}
public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
try {
if(connection!=null){
connections.addLast(connection);
}
if(ps!=null)
ps.close();
if(rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void release(){
while(!connections.isEmpty()){
try {
connections.removeFirst().close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
1.6 mysql插入数据
1.7 JDBC 查询数据
1.7.1 程序
@Test
public void test(){
System.out.println("MyJDBC: " + DaoFactory.newUserDao().fetchUsers());
}
1.7.2 结果
2、c3p0
2.1 配置文件和maven依赖
2.1.1 导入maven依赖
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.4</version>
</dependency>
2.1.2 配置文件
<!-- c3p0-config.xml -->
<?xml version="1.0" encoding="utf-8" ?>
<c3p0-config>
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db_jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC</property>
<property name="driverClass">com.mysql.cj.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">yuyubuyu</property>
<property name="acquireIncrement">3</property>
<property name="initialPoolSize">5</property>
<property name="minPoolSize">2</property>
<property name="maxPoolSize">20</property>
</default-config>
</c3p0-config>
2.2 c3p0Util类
public class c3p0Util {
private static DataSource dataSource;
static {
dataSource = new ComboPooledDataSource();
}
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
❝有点麻烦,好浪费时间,所以导入DBUtils
❞
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
2.3 其它工作
❝其它没有写的部分copy自前文代码,没有修改
❞
2.3.1 改写c3p0Util
public class c3p0Util {
private static DataSource dataSource;
static {
dataSource = new ComboPooledDataSource();
}
public static QueryRunner getQueryRunner(){
return new QueryRunner(dataSource);
}
/**
* @author LOS
* @deprecated 已改用DBUtils
* @return fetch from dataSource
*/
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* @deprecated 已改用DBUtils
* @param connection 连接
* @param ps PreparedStatement
* @param rs ResultSet
*/
public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(ps!=null){
try {
ps.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
2.3.2 UserDao实现类
public class UserDaoImpl implements UserDao {
@Override
public List<User> fetchUsers() {
QueryRunner qr = c3p0Util.getQueryRunner();
String sql = "select * from tb_user";
try {
return qr.query(sql, new BeanListHandler<>(User.class));
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
2.4 c3p0查询数据
3、dbcp
3.1 配置文件和maven依赖
3.1.1 导入maven依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
3.1.2 配置文件
########DBCP配置文件##########
#驱动名
driverClassName=com.mysql.cj.jdbc.Driver
#url
url=jdbc:mysql://localhost:3306/db_jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
#用户名
username=root
#密码
password=yuyubuyu
#初试连接数
initialSize=30
#最大活跃数
maxTotal=30
#最大idle数
maxIdle=10
#最小idle数
minIdle=5
#最长等待时间(毫秒)
maxWaitMillis=1000
#程序中的连接不使用后是否被连接池回收(该版本要使用removeAbandonedOnMaintenance和removeAbandonedOnBorrow)
#removeAbandoned=true
removeAbandonedOnMaintenance=true
removeAbandonedOnBorrow=true
#连接在所指定的秒数内未使用才会被删除(秒)(为配合测试程序才配置为1秒)
removeAbandonedTimeout=1
3.2 DBCPUtil类
public class DBCPUtil {
private static DataSource dataSource;
static{
try {
Properties properties = new Properties();
properties.load(DBCPUtil.class.getClassLoader().getResourceAsStream("dbcp.properties"));
dataSource = BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
private DBCPUtil(){}
public static int update(Connection connection, PreparedStatement ps, String sql, Object... objects){
if(connection==null||sql==null||"".equals(sql)){
return 0;
}
try {
ps = connection.prepareStatement(sql);
for( int i = 0; i < objects.length; i++ ){
ps.setObject(i+1, objects[i]);
}
int count = ps.executeUpdate();
release(null, ps, null);
return count;
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
public static List<Map<String, Object>> query(Connection connection, String sql, Object... objects){
try {
List<Map<String, Object>> list = new ArrayList<>();
PreparedStatement ps = connection.prepareStatement(sql);
for( int i = 0; i < objects.length; i++ ){
ps.setObject(i+1, objects[i]);
}
ResultSet rs = ps.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
int cols_len = metaData.getColumnCount();
while (rs.next()) {
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < cols_len; i++) {
String cols_name = metaData.getColumnName(i + 1);
Object cols_value = rs.getObject(cols_name);
map.put(cols_name, cols_value);
}
list.add(map);
}
release(null, ps, rs);
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void release(Connection connection){
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
try {
if(connection!=null){
connection.close();
}
if(ps!=null)
ps.close();
if(rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
3.3 复制自定义JDBC
❝从自定义JDBC项目下复制以下包:
1、dao包
2、proxy包
3、factory包
4、model包
❞
3.4 dbcp查询数据
4、druid
4.1 配置文件和maven依赖
4.1.1 导入maven依赖
❝感觉用的还是有点早,其实c3p0和dbcp够学了
❞
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
4.1.2 配置文件
# druid.properties
url=jdbc:mysql://localhost:3306/db_jdbc?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
driverClassName=com.mysql.cj.jdbc.Driver
username=root
password=yuyubuyu
##初始连接数,默认0
initialSize=10
#最大连接数,默认8
maxActive=30
#最小闲置数
minIdle=10
#获取连接的最大等待时间,单位毫秒
maxWait=2000
#缓存PreparedStatement,默认false
poolPreparedStatements=true
#缓存PreparedStatement的最大数量,默认-1(不缓存)。大于0时会自动开启缓存PreparedStatement,所以可以省略上一句设置
maxOpenPreparedStatements=20
4.2 DruidUtil类
public class DruidUtil {
private static DataSource dataSource;
static{
try {
Properties properties = new Properties();
properties.load(DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties"));
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
private DruidUtil(){}
public static int update(Connection connection, PreparedStatement ps, String sql, Object... objects){
if(connection==null||sql==null||"".equals(sql)){
return 0;
}
try {
ps = connection.prepareStatement(sql);
for( int i = 0; i < objects.length; i++ ){
ps.setObject(i+1, objects[i]);
}
int count = ps.executeUpdate();
release(null, ps, null);
return count;
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
public static List<Map<String, Object>> query(Connection connection, String sql, Object... objects){
try {
List<Map<String, Object>> list = new ArrayList<>();
PreparedStatement ps = connection.prepareStatement(sql);
for( int i = 0; i < objects.length; i++ ){
ps.setObject(i+1, objects[i]);
}
ResultSet rs = ps.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
int cols_len = metaData.getColumnCount();
while (rs.next()) {
Map<String, Object> map = new HashMap<>();
for (int i = 0; i < cols_len; i++) {
String cols_name = metaData.getColumnName(i + 1);
Object cols_value = rs.getObject(cols_name);
map.put(cols_name, cols_value);
}
list.add(map);
}
release(null, ps, rs);
return list;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void release(Connection connection){
if (connection!=null) {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void release(Connection connection, PreparedStatement ps, ResultSet rs){
try {
if(connection!=null){
connection.close();
}
if(ps!=null)
ps.close();
if(rs!=null)
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
4.3 复制自定义JDBC
❝从自定义JDBC项目下复制以下包:
1、dao包
2、proxy包
3、factory包
4、model包
❞
4.4 druid查询数据
5、 小结
5.1 小结
我也是刚知道Druid
和hiKaryCP
这些连接池,也是兴冲冲一头扎进了相关文档啃了半天,琢磨了半天之后也得出了一件意义重大的结论:
❝学了这么多没什么卵用。
❞
它们也只是连接池,知乎上也经常有人吹:
❝得到的工具可以随时改换,学到的技术却是不分高低
❞
所以本文最大篇幅还是集中于自定义JDBC
中,知道传统的JDBC如何工作,又有什么麻烦的地方,才能知道工具带来什么便利。
5.2 使用连接池步骤
-
导入相关依赖 -
编辑配置文件 -
读取配置文件并生成 DataSource
实例 -
从 DataSource
实例获取Connection
-
数据库读写操作 -
回收 Connection