目标:连接池

一. 自定义连接池

使用DBUtils组件更新和查询数据库

QueryRunner qr = new QueryRunner();
qr.query(con,sql,rsh);
//rsh:ResultSetHandler接口,可以使用自定义实现类,改写handle()方法;也可以使用封装的实现类。
List<Person> list = qr.query(con,sql,new BeanListHandler<Person>(Person.class))

1. 思考:程序中连接如何管理?

  1. 连接资源很宝贵,MySQL最多大约200个连接,不够用
  2. 连接:
  • 创建连接,操作数据库
  • 操作结束,关闭连接
  • 频繁打开关闭,影响效率
  • 解决方案:预先创建一组连接,用则取出,用完释放;这些预先创建的连接存放在连接池(集合)中。
  1. 学习连接池:
  • 自定义连接池
  1. 程序实现思路:
  1. 指定初始化连接数目,app启动时,就执行创建!
  2. 指定最大连接数
  3. 指定当前使用连接个数:不能超出最大连接数
  1. 代码实现
  1. MyPool.java连接池类;
  2. 指定全局参数:初始化数目,最大连接数,当前连接数,连接池集合
  3. 构造函数:循环创建3个连接–写一个创建连接的方法
  4. 获取连接:
  • 池中有连接,直接拿
  • 池中没有连接,判断现有总连接数,若达到最大连接数,抛出异常;没有达到最大连接数,创建新的连接
  1. 释放连接:连接放回连接池集合中
  1. 通常,连接使用完,会采用connection.close()方法关闭与数据库的连接。这里,不应该频繁关闭连接,应该把该连接重新放入连接池(保证连接池中的和活跃的连接总数不大于最大连接数即可),留给下一个用户使用。

2. 代理模式:

  • 想对接口中某个或部分方法的功能进行扩展,而不像实现接口,可以使用(动态)代理模式 Java中有静态/动态/Cglib(spring)代理模式
  • 通过创建某个接口对象的代理对象,实现对接口中某个方法的监测,从而达到,不需要重写接口的所有方法,也可以修改或者扩展接口中某个方法的目的!

在使用代理模式时:

Proxy static Object new ProxyInstance(
    ClassLoader loader, //当前使用的类加载器this.getClass().getClassLoader()
    Class<?>[] interfaces,//获取接口对象实现的接口类型
    InvocationHandler h //事件处理器,当该对象执行接口中的方法时,会触发事件处理器代码,可以将需要改变的方法作为参数(method)传入;

);

获取具体类实现的接口:

obj.getClass().getInterfaces();

获取接口对象实现的接口

new Class[]{Object.class};

二. DBCP和C3P0连接池技术

通常我们把对接口 javax.sql.DataSource的实现,称为数据源,数据源中包含了数据库连接池的实现。由一些开源组织提供了数据源的独立实现:

  • DBCP(tomcat)数据库连接池
  • Commons-dbcp.jar
  • Commons-pool.jar
  • C3P0(hibernate)数据库连接池
  • c3p0.jar

1. DBCP连接池

核心类:BasicDataSource

@Test
public void testConfig() throws Exception {
    Properties prop = new Properties();
    InputStream in = DBCP_demo.class.getResourceAsStream("/db.properties");
    prop.load(in);

    DataSource dataSource = BasicDataSourceFactory.createDataSource(prop);
    Connection conn = dataSource.getConnection();
    PreparedStatement pstm = conn.prepareStatement("insert into employee values(?,'chenchen','nv',29,'dsadioua','dw@eewe','43243243');");
    pstm.setObject(1, 8);
    pstm.executeUpdate();
    conn.close();
}

使用配置文件获取数据源配置

  • 何时使用properties,何时使用xml来配置?
  • properties实现HashTable接口!存放的只是键值对

db.properties

url=jdbc:mysql://localhost:3306/day17
driverClassName=com.mysql.jdbc.Driver
username=root
password=root
initalSize=3
maxActive=6
maxIdle=5000
//注意key需要和DBCP的方法名匹配

2. C3P0连接池

最常用的连接技术,Spring和Hibernate框架支持C3P0连接池技术
核心类:CombopooledDataSource ds;

1. 硬编码方法

@Test
public void testC3P0() throws Exception {
    ComboPooledDataSource ds = new ComboPooledDataSource();
    ds.setJdbcUrl("jdbc:mysql://localhost:3306/day17");
    ds.setDriverClass("com.mysql.jdbc.Driver");
    ds.setUser("root");
    ds.setPassword("root");
    ds.setInitialPoolSize(3);
    ds.setMaxPoolSize(6);
    ds.setMaxIdleTime(1000);

    Connection conn = ds.getConnection();
    PreparedStatement pstm = conn.prepareStatement("delete from employee where id=?");
    pstm.setObject(1, 3);
    pstm.executeUpdate();

    conn.close();
}

2. XML配置方式

自动加载src目录下的c3p0-config.xml文件,配置连接池

@Test
public void testname() throws Exception {
    //自动加载src目录下的c3p0-config.xml配置文件
    ComboPooledDataSource ds = new ComboPooledDataSource();
    Connection conn = ds.getConnection();
    conn.prepareStatement("delete from employee where id=4;").execute();

    conn.close();
}

注意:property的name属性必须小写开头,再使用驼峰式命名!

<default-config>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/day17</property>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="user">root</property>
    <property name="password">root</property>
    <property name="initialPoolSize">10</property>
    <property name="maxPoolSize">25</property>
    <property name="maxIdleTime">3000</property>
  </default-config>


也可以使用特定的数据库配置

//获取连接池配置文件信息
ComboPooledDataSource ds = new ComboPooledDataSource("oracle-config");

<named-config name="oracle-config">
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/day17</property>
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="user">root</property>
    <property name="password">root</property>
    <property name="initialPoolSize">10</property>
    <property name="maxPoolSize">25</property>
    <property name="maxIdleTime">3000</property>
  </named-config>

使用d3p0连接池技术-步骤:

  1. 导入jar包
  2. 改写xml配置文件
  3. 创建数据源,获得连接,传递sql语句执行,关闭连接

三. 连接的管理

交给连接池!改写项目中DBUtils类