详解C3P0和DBUtils

8 篇文章 0 订阅

JDBC,MySQL

1. 数据库连接池
1.1 为什么要使用数据库连接池
PersonDao --> 
	BaseDao --> 
		通过JdbcUtil工具类获取数据库连接和关闭数据库连接

每一次SQL语句操作
	都要开启一次数据库,关闭一次数据库
	对于数据库频繁打开关闭操作非常浪费时间!!!

期望可以模仿共享单车模式
	1. 准备多个数据库连接对象
	2. 有程序数据,给予他数据库连接对象
	3. 需要数据库连接的程序较多,原始数据库连接对象不够用,创建新数据库连接
	4. 考虑饱和问题!!!
	5. 如果一个程序等了半天没有可以使用的数据库连接对象,TimeOut
	6. 程序使用过数据库连接对象之后,归还数据库连接给数据库连接池
	7. 当程序完全退出,清空数据库连接池

另外:
	在设计程序,框架,工具类时,需要考虑程序员的开发压力
	满足方法的统一性
		getConnection
		close
	C3P0数据库连接池提供的方式方法
1.2 C3P0数据库连接池使用
1.2.1 C3P0配置文件
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!-- 默认配置,如果没有指定则使用这个配置 -->
    <default-config>
        <property name="user">root</property>
        <property name="password">123456</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/javaee1911?useSSL=true</property>
        <property name="driverClass">com.mysql.jdbc.Driver</property>

        <!-- 数据库连接对象等待时间 -->
        <property name="checkoutTimeout">30000</property>
        <!-- 初始化Connection数据库连接对象个数 -->
        <property name="initialPoolSize">10</property>
        <!-- 数据库连接池中最大Connection连接个数 -->
        <property name="maxPoolSize">100</property>
        <!-- 数据库连接池中最少Connection连接个数 -->
        <property name="minPoolSize">2</property>
        <!-- 当前数据库连接池能够处理的最大SQL语句数量,能够处理的SQL语句搬运工个数 -->
        <property name="maxStatements">200</property>
    </default-config>
</c3p0-config>
<c3p0-config>
  <default-config>
    <property name="automaticTestTable">con_test</property>
    <property name="checkoutTimeout">30000</property>
    <property name="idleConnectionTestPeriod">30</property>
    <property name="initialPoolSize">10</property>
    <property name="maxIdleTime">30</property>
    <property name="maxPoolSize">100</property>
    <property name="minPoolSize">10</property>
    <property name="maxStatements">200</property>

    <user-overrides user="test-user">
      <property name="maxPoolSize">10</property>
      <property name="minPoolSize">1</property>
      <property name="maxStatements">0</property>
    </user-overrides>

  </default-config>

  <!-- This app is massive! -->
  <named-config name="intergalactoApp"> 
    <property name="acquireIncrement">50</property>
    <property name="initialPoolSize">100</property>
    <property name="minPoolSize">50</property>
    <property name="maxPoolSize">1000</property>

    <!-- intergalactoApp adopts a different approach to configuring statement caching -->
    <property name="maxStatements">0</property> 
    <property name="maxStatementsPerConnection">5</property>

    <!-- he's important, but there's only one of him -->
    <user-overrides user="master-of-the-universe"> 
      <property name="acquireIncrement">1</property>
      <property name="initialPoolSize">1</property>
      <property name="minPoolSize">1</property>
      <property name="maxPoolSize">5</property>
      <property name="maxStatementsPerConnection">50</property>
    </user-overrides>
  </named-config>
</c3p0-config>
	
1.2.2 启动C3P0核心类
/**
* 启动C3P0数据库连接,创建数据库连接池
*/
private static ComboPooledDataSource pool = new ComboPooledDataSource();

// 会自动加载对应的c3p0-config.xml文件中的配置内容,启动c3p0数据库连接池
2. DBUtils 轻量级ORM框架
2.1 DBUtils介绍
DBUtils是apache组织下的一个轻量级ORM框架
核心类:
	QueryRunner
核心方法:
	update
	Query

ResultSetHandler
2.2 DBUtils使用
package util;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;

import java.sql.*;
import java.util.List;
import java.util.Map;

/**
 * 数据库操作基类,主要提供update和query方法,满足数据库的基本操作
 *
 * @author Anonymous
 */
public class BaseDao {
    /**
     * 通用更新方法,用于处理update insert delete SQL语句
     *
     * @param sql    需要处理的SQL
     * @param params Object类型数组,是对应当前SQL语句的参数
     * @return 受到影响的行数 Affected Rows
     */
    public int update(String sql, Object[] params) {
        // DBUtils核心类
        int affectedRows = 0;
        QueryRunner queryRunner = new QueryRunner();
        Connection connection = JdbcUtil.getConnection();

        try {
            affectedRows = queryRunner.update(connection, sql, params);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(connection);
        }

        return affectedRows;
    }

    /**
     * 通用查询方法,执行的select SQL语句
     *
     * @param sql    需要执行的SELECT SQL语句
     * @param params 对应SQL语句的参数
     * @param cls    明确查询的到底是哪一个Java数据类型,也能利用反射思想【为所欲为】
     * @param <E>    约束当前List集合中存储的数据类型
     * @return 对应当前查询结果存储元素的List集合,如果没有任何一个元素,返回null
     */
    public <E> List<E> query(String sql, Object[] params, Class<E> cls) {
        QueryRunner queryRunner = new QueryRunner();
        Connection connection = JdbcUtil.getConnection();

        List<E> query = null;
        try {
            query = queryRunner.query(connection, sql, new BeanListHandler<>(cls), params);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(connection);
        }

        return query;
    }

    /**
     *
     * @param sql
     * @param params
     * @return
     */
    public Object[] query(String sql, Object[] params) {
        QueryRunner queryRunner = new QueryRunner();
        Connection connection = JdbcUtil.getConnection();

        Object[] query = new Object[0];
        try {
            query = queryRunner.query(connection, sql, new ArrayHandler(), params);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(connection);
        }

        return query;
    }

    /**
     *
     * @param sql
     * @param params
     * @return
     */
    public List<Map<String, Object>> queryMapList(String sql, Object[] params) {
        QueryRunner queryRunner = new QueryRunner();
        Connection connection = JdbcUtil.getConnection();

        List<Map<String, Object>> query = null;
        try {
            query = queryRunner.query(connection, sql, new MapListHandler(), params);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtil.close(connection);
        }

        return query;
    }
}
3. SQL之XX查询
3.1 SQL联表查询
use javaee1911;

-- 查询什么内容
-- 员工表内 id,name 以及 部门表 deptName
select employee.id,
       employee.name,
       dept.deptName
-- 从哪里查
from employee,
     dept
-- 什么条件 如果没有条件约束,到导致联表查询结果成为笛卡尔乘积
where employee.deptId = dept.id;

-- 查询什么内容
-- 员工表内 id,name 以及 部门表 deptName
select e.id,
       e.name,
       d.deptName
-- 从哪里查
from employee e,
     dept d
-- 什么条件 如果没有条件约束,到导致联表查询结果成为笛卡尔乘积
where e.deptId = d.id;

-- 查询什么内容
-- 员工表内 id,name 以及 部门表 deptName
select e.id,
       e.name,
       d.deptName
-- 从哪里查
from employee e
--  内连接查询,inner join 内连接操作之后,条件约束使用on
         inner join dept d on e.deptId = d.id;
-- 什么条件 如果没有条件约束,到导致联表查询结果成为笛卡尔乘积

-- 查询出所有部门对应的员工,如果当前部门没有员工,显示null
select d.deptName, e.name
from dept d
         -- left outer join 左表完整展示,右表匹配数据,
         -- 如果右表没有对应都是数据,显示null
         left outer join employee e on d.id = e.deptId;

select e.name, d.deptName
from employee e
         -- right outer join 右表完整显示,左表匹配数据
         -- 如果左表没有对应都是数据,显示null
         right outer join dept d on e.deptId = d.id;

3.2 子查询
查询的结果作为其他查询语句的条件
涉及到的一些关键字:
	in、not in、=、!=、exists、not exists

create table emp
(
    id int primary key auto_increment,
    name varchar(30) not null,
    deptId int not null
)

create table department
(
    id int primary key auto_increment,
    deptName varchar(30) not null
);

insert into emp(name, deptId) value('雷神', 1);
insert into emp(name, deptId) value('寡姐', 2);
insert into emp(name, deptId) value('钢铁侠', 3);
insert into emp(name, deptId) value('诺基', 1);
insert into emp(name, deptId) value('浩克', 2);

insert into department(id, deptName) value(1, '雷人部');
insert into department(id, deptName) value(2, '单身部');
insert into department(id, deptName) value(4, '虐狗部');
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值