1.为什么使用连接池重写工具类
Connection对象在JDBC使用的时候就会去创建一个对象,使用结束以后就会将这个对象给销毁了(close).每次创建和销毁对象都是耗时操作.需要使用连接池对其进行优化.程序初始化的时候,初始化多个连接,将多个连接放入到池(集合)中.每次获取的时候,都可以直接从连接池中进行获取.使用结束以后,将连接归还到池中.
2.连接池原理
目的:解决建立数据库连接耗费资源和时间很多的问题,提高性能。
3.1步骤
创建一个类,定义LinkedList集合作为连接池,在静态代码块中,向集合里面添加5个连接对象
添加addBack()方法,用作归还连接
代码:
public class MyDataSource { //连接池 static LinkedList<Connection> pool = new LinkedList<>(); //初始化连接 static{ try { for(int i = 0;i < 5;i++){ pool.add(JdbcUtils.getConnection()); } } catch (SQLException e) { e.printStackTrace(); } } //提供连接 public Connection getConnection(){ Connection connection = pool.removeFirst(); return connection; } //归还连接的方法 public void addBack(Connection connection){ //添加到最后 pool.addLast(connection); } //返回pool里面连接的个数 public int getCount(){ return pool.size(); } }
3.2datasource接口概述
Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商(用户)需要让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池!
常见的连接池:DBCP、C3P0。
3.3编写连接池遇到的问题
实现dataSource接口后,addBack()不能调用了.
能不能不引入新的api,直接调用之前的API.close(),但是这个close不是关闭,是归还
3.4解决办法
继承条件:可以控制父类的构
装饰者模式
目的:改写已存在的类的某个方法或某些方法,装饰设计模式(包装模式)
4.1 dbcp
4.1.1 dbcp概念
DBCP:Apache推出的Database Connection Pool
核心API:
basicDatasource
basicDatasourceFactory
BasicDataSource basicDataSource = new BasicDataSource(); basicDataSource.setDriverClassName("com.mysql.jdbc.Driver"); basicDataSource.setUrl("jdbc:mysql://localhost:3306/web10"); basicDataSource.setUsername("root"); basicDataSource.setPassword("123456"); Connection connection = basicDataSource.getConnection();
2.通过配置文件来配置
添加jar包 commons-dbcp-1.4.jar commons-pool-1.5.6.jar
添加配置文件到src目录
Properties p = new Properties(); p.load(DdcpDemo.class.getClassLoader().getResourceAsStream("dbcpconfig.properties")); //创建DataSource对象 DataSource basicDataSource = BasicDataSourceFactory.createDataSource(p); Connection connection = basicDataSource.getConnection();
C3P0开源免费的连接池!目前使用它的开源项目有:Spring、Hibernate等。使用第三方工具需要导入jar包,c3p0使用时还需要添加配置文件c3p0-config.xml.
使用C3P0需要添加c3p0-0.9.1.2.jar
通过硬编码来编写
ComboPooledDataSource cpds = new ComboPooledDataSource(); cpds.setDriverClass("com.mysql.jdbc.Driver"); // loads the jdbc driver cpds.setJdbcUrl("jdbc:mysql://localhost:3306/web10"); cpds.setUser("root"); cpds.setPassword("123456"); Connection connection = cpds.getConnection();
通过配置文件来编写
添加c3p0-0.9.1.2.jar
编写配置文件c3p0-config.xml,放在src中(注:文件名一定不要写错)
public class C3P0Utils { //创建一个连接池对象 private static DataSource ds = new ComboPooledDataSource(); //从池中获得一个连接 public static Connection getConnection() throws SQLException{ return ds.getConnection(); } //释放资源 public static void closeAll(ResultSet rs,Statement stmt,Connection conn){ if(rs!=null){ try { rs.close(); } catch (SQLException e) { throw new RuntimeException(e); } rs = null; } if(stmt!=null){ try { stmt.close(); } catch (SQLException e) { throw new RuntimeException(e); } stmt = null; } if(conn!=null){ try { conn.close();//放心的关。是否关闭取决连接是怎么来的 } catch (SQLException e) { throw new RuntimeException(e); } conn = null; } } }
二,使用DBUtils 增删改查的操作
1.案例分析
简化JDBC代码开发,本案例我们将采用apache commons组件一个成员:DBUtils。
DBUtils就是JDBC的简化开发工具包。需要使用技术:连接池(获得连接)、SQL语句都没有少. 第一个数据库框架(jar包),
2.案例相关知识
2.1javaBean组件
JavaBean就是一个类,在开发中常用于封装数据。具有如下特性
1.提供私有字段:private 类型 字段名;
2.提供getter/setter方法:get和set方法一定要是public
3.提供无参构造
4.需要实现接口:java.io.Serializable ,通常偷懒省略了。
javaBean不是功能, 也不是大公司的一个规定, 全世界的开发人员之间的一个约定俗成. 很多框架就依赖JavaBean属性来设计做功能
javabean属性: get和set方法, 去掉set,然后把set后面的字段首写字母变小写, 首写字母变成小写的字段就是javabean属性
public class Category { private String cid; private String cname; public String getCid() { return cid; } public void setCid(String cid) { this.cid = cid; } public String getCname() { return cname; } public void setCname(String cname) { this.cname = cname; } }
3.DBUtils完成CRUD
3.1概述
DBUtils是java编程中的数据库操作实用工具,小巧简单实用。 第一个操作数据库框架(jar),
DBUtils封装了对JDBC的操作,简化了JDBC操作流程,可以少写代码。
Dbutils三个核心功能介绍
QueryRunner. 执行sql语句. update(), query()
ResultSetHandler 封装查询结果集.(select )
3.2QueryRunner核心类
QueryRunner(DataSource ds) ,,构造函数. 底层自动维护连接connection
update(String sql, Object... params) ,执行更新数据 insert update delete 参数就是一个数组,参数个数取决于语句中?的个数.
query(String sql, ResultSetHandler<T> rsh, Object... params) ,执行查询 select
3.3ResultSetHandler结果集处理类
Handler类型 说明 ArrayHandler 将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值 ArrayListHandler 将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。 BeanHandler 将结果集中第一条记录封装到一个指定的javaBean中。 select *from user where id = 1 BeanListHandler 将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中 ColumnListHandler 将结果集中指定的列的字段值,封装到一个List集合中 KeyedHandler 将结果集中每一条记录封装到Map<String,Object>,在将这个map集合做为另一个Map的value,另一个Map集合的key是指定的字段的值。 MapHandler 将结果集中第一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值 MapListHandler 将结果集中每一条记录封装到了Map<String,Object>集合中,key就是字段名称,value就是字段值,在将这些Map封装到List集合中。 ScalarHandler 它是用于单个数据。例如select count(*) from 表操作。 3.4使用DBUtils完成数据库的CRUD
3.4.1开发步骤:
创建项目,并导入jar包
创建连接池
编写测试类
3.4.2增加
// 向user表里面,插入一条记录 insert into user values(null,'zl','111111','小赵') @Test public void fun01() throws SQLException { // 创建queryRunner DBUTIls自动维护connecton QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource()); String sql = "insert into user values(?,?,?,?)"; Object[] params = { null, "zl", "111111", "小赵" }; queryRunner.update(sql, params); }
3.4.3更新
// 把id为4的用户密码改成666666 @Test public void fun02() throws SQLException { // 创建queryRunner 对象 QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource()); // String sql = "update user set password = '666666' where id = 4"; String sql = "update user set password = ? where id = ?"; Object[] params = { "666666", 4 }; queryRunner.update(sql, params); }
3.4.4删除
// 把id为4的用户删除 @Test public void fun03() throws SQLException { // 创建queryRunner 对象 QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource()); // String sql = "delete from user where id = 4"; String sql = "delete from user where id = ?"; Object[] params = { 4 }; queryRunner.update(sql, params); }
3.4.5通过id查询
// 查询id为1的用户信息,把数据封装到user对象里面 @Test public void fun04() throws SQLException { // 创建queryRunner 对象 QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource()); // String sql = "select *from user where id = 1"; String sql = "select *from user where id = ?"; Object[] params = { 1 }; User user = queryRunner.query(sql, new BeanHandler<>(User.class), params); System.out.println(user.toString()); }
3.4.6查询所有记录
// 查询所有的用户 @Test public void fun05() throws SQLException { // 创建queryRunner 对象 QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource()); String sql = "select *from user";// 一条或者多条 List<User> list = queryRunner.query(sql, new BeanListHandler<>(User.class)); }