本帖最后由 小石姐姐 于 2018-5-23 16:50 编辑
JDBC高级部分
连接池
1.概述
* 连接池是装有连接的容器,使用连接的话,可以从连接池中进行获取,
使用完成之后将连接归还给连接池。
2.自定义连接池
2.1构建环境
* 新建一个lib 文件夹 , 引入mysql驱动包 mysql-connector-java-5.0.8-bin.jar
* 创建.properties 配置文件
* 创建MyDataSource类,实现 Javax.sql 包下的 DataSource接口,实现它的全部方法
** 只需注意DataSource下的getConnection()方法(作用:在连接池中获得连接的方法)
** 重写该方法返回一个Connection对象
** 创建一个集合用于存储连接对象
** 编写构造函数,获取几个Connection连接对象,存入集合
** 添加一个返还Connection连接对象的方法(也就将使用完后的连接对象回收回集合,不进行释放资源操作,继续使用)
3.自定义连接池的问题解决
* 增强的意思:修改一个类的方法,或是在该类的方法中加入其它的功能
* 问题:自定义连接池的连接归还问题,使用自定义命名的归还方法会增加用户的使用难度
** 解决分析的思路:
***原来在Connection中是有一个close方法的,colse方法完成了连接的销毁。
能不能做一个事情,将原有的连接的close方法改为归还。
***现在要做的事情就是将原有的close方法的逻辑改为归还。(增强一类中的方法)。
3.1.如何增强一个类中的方法
? 1.1 一种:采用继承的方式:
** 继承这种增强是最简单,但是是有使用条件的:必须能够控制这个类的构造!!!
1.2 二种:采用装饰者模式:(产生一个增强类)(实际开发很少使用)
* 装饰者模式使用条件:
** 一、增强的类和被增强的类实现相同的接口
** 二、在增强的类中获得被增强的类的引用
3.2使用装饰者模式增强Connection中的close方法
1.创建一个模板类
* 实现想要增强的接口(Connection)
例 : class 类名 implements Connection{}
* 实现一个有参构造,参数为要增强的接口的对象(Connection对象)
* 调用调用对象的方法去实现该接口的方法(也就是用接口的对象去实现接口本身的方法)
** 例 :
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return conn.isWrapperFor(iface);
}
* 这样就原封不动的获取了被增强的接口的实现类
2.创建包装类
* 创建一个类,去继承模板类
* 在包装类中重写模板类中要增强的方法;
例: 增强Connection的close()方法,将原本的释放资源
改为回收连接;
@Override
public void close() {
// super.close();
connList.add(conn);
}
* 这样就获得了增强close()方法的Connection的包装类;
3.创建连接池
* 创建一个实现DataSource接口的类(连接池)
* 创建一个存储Connection对象的List集合
* 创建一个无参构造方法,在构造方法中使用for循环,创建多个Connection
接口对象,并存入List集合;
* 添加DataSource接口的所有方法,重写其中的getConnection()方法;
** 在getConnection()方法中创建Connection的包装类,对List集合
中的Connection对象变为增强的Connection对象,并将该对象返回给
方法的调用者;
* 因为增强型的Connection对象的close()以进行了增强,因在连接池中就
不需要专门定义归还连接的方法了;
* 这样就解决了自定义连接池中需要用户单独记忆一个归还方法的问题;
=======================
4.Druid开源连接池的使用
4.1Druid的概述
* Druid阿里旗下开源连接池产品,使用非常简单,可以与Spring框架进行
快速整合。
* Druid
4.2Druid的环境配置
* 在Java的项目目录下创建一lib文件夹(其它名也行)
* 将Druid 的工具包 druid-1.0.9.jar 添加到lib文件夹
* 使用Built Path 将jar包添加到构建路径
* 这样就可以使用了
4.2Druid有两种使用方式(获取连接池)
4.2.1第一种:手动配置参数
* 获得连接池对象
DruidDataSource dataSource = new DruidDataSource();
* 手动设置数据库连接的参数:
//驱动路径
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
//数据库路径
dataSource.setUrl("jdbc:mysql://localhost:3306/web_test4");
//数据库用户名
dataSource.setUser("root");
//数据库密码
dataSource.setPassword("abc");
* 获得连接
Connection conn = dataSource.getConnection();
* 归还Connection连接
conn.close();
4.2.1第二种:使用配置方式(通过.properties配置文件获取)
* 注意:配置文件中的数据是以 'key=value' 方式存储的,
key值要跟DruidDataSource类的set方法的名一样,
也就是:driverClassName=xxx
url=xxx
user=xxx
password=xxx
每行都是顶格写,不能用空格
* 创建一个Properties对象,使用load()方法获取配置文件
* 将加载文件后的Properties对象以参数的形式传入Druid
的DruidDataSourceFactory.createDataSource();中来获取一个
DataSource接口的对象(连接池对象)
例:(工厂类)
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties对象);
//获取一个连接
Connection conn = dataSource.getConnection();
//归还Connection连接
conn.close();
=============
5.C3P0连接池
5.1概述
* C3P0是一个开源的JDBC连接池,它实现了数据源和JND绑定,支持JDBC3规范和JDBC2的
标准扩展.目前使用它的开源项目有Hibernate,Spring等.
5.2c3p0的环境配置
* 在Java的项目目录下创建一lib文件夹(其它名也行)
* 将c3p0 的工具包 c3p0-0.9.1.2.jar 添加到lib文件夹
* 使用Built Path 将jar包添加到构建路径
* 这样就可以使用了
5.2 C3PO连接池的使用,共有两种方式
5.2.1第一种: 收动配置参数
* 创建连接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
* 设置参数
//注册驱动
dataSource.setDriverClass("com.mysql.jdbc.Driver");
//配置数据库路径
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/web_test4");
//配置数据库用户名
dataSource.setUser("root");
//配置用户密码
dataSource.setPassword("abc");
*从连接池中获得连接
Connection conn = dataSource.getConnection();
5.2.2第二种:采用配置文件(.xml文件)
* 注意:
** 配置文件的名字为 'c3p0-config.xml' 不能更改
** 文件内容从c3p0帮助文档的configuration项中找到模板
复制到文件中,再添加需要的数据
** 配置文件要放在Java项目的src文件夹的根目录下
** 构建comboPooledDataSource 的对象时会自动加载配置文件,
不需要写路径,应配置文件的名字和存放路径一定要按规定设置;
* //创建连接池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//从连接池中获得连接
Connection conn = dataSource.getConnection();
//归还连接
conn.close();
=========
6.DBUtils
6.1Dbutils概述
* Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的
开源工具类库,使用它能够简化JDBC应用的开发,同时也不会影响程
序的性能;
* 它对JDBC的操作数据库的部分进行了封装;(增删改查和结果集的存储进行了封装)
6.2DBUtils环境配置
* 在Java的项目目录下创建一lib文件夹(其它名也行)
* 将c3p0 的工具包 commons-dbutils-1.4.jar 添加到lib文件夹
* 使用Built Path 将jar包添加到构建路径
* 这样就可以使用了
6.3Dbutils的API:
* 核心运行类 : QueryRunner
* 构造方法:
* QueryRunner()
** 先使用无参构造创建对象,在调用query()和update()方法时,
再
* QueryRunner(DataSource ds)
** 通过连接池创建一个对象
6.4QueryRunner类执行CRUD的操作
6.4.1第一种:在一般情况下如果执行CRUD的操作:(不开启事务情况)
* 构造:
** QueryRunner(DataSource ds);
方法:
//增删改
** int update(String sql,Object… args);
//查询
** query(String sql,ResultSetHandler rsh,Object… args);
6.4.2第二种:如果有事务管理的话使用另一套完成CRUD的操作
* 构造:
** QueryRunner();
* 方法:
//增删改
** int update(Connection conn,String sql,Object… args);
//查询
** T query(Connection conn,String sql,ResultSetHandler rsh,Object… args);
***使用无参构造,在方法中传入Connection 连接对象的原因:
**** 事务中的操作要保证是同一个连接,并且要是用连接开启事务;
6.4.3 案例:
* DBUtils的添加操作
** queryRunner.update("insert into account values (null,?,?)", "ddd",10000);
* DBUtils的修改操作
** queryRunner.update("update account set name=?,money=? where id =?", "eee",20000,4);
* DBUtils的删除操作
** queryRunner.update("delete from account where id = ?", 3);
6.5 Dbutils的查询操作步骤:
* 创建一个属性跟数据库表字段一样的JavaBean
* DBUtils为手动封装查询结果集也进行了封装
根据查询结果,使用不同的Handler的实现类,对结果集进行处理操作
* ArrayHandler
将一条记录封装到一个数组当中。这个数组应该是Object[]。
Object[] objs = queryRunner.query("select * from account",
new ArrayHandler(),1);
* ArrayListHandler
将多条记录封装到一个装有Object[]的List集合中
List<Object[]> list = queryRunner.query("select *from accout",
new ArrayListHandler());
* BeanHandler
将一条记录封装到一个JavaBean中。
Account account = queryRunner.query("select * from account",)
* BeanListHandler
List<Account> list = queryRunner.query("select * from account",
new BeanListHandler<Account>(Account.class));
* MapHandler
将一条记录封装到一个Map集合中,Map的key是列名,
Map的value就是表中列的记录值。
Map<String,Object> map = queryRunner.query("select * from account
where id = ?",new MapHandler(),4);
* MapListHandler
将多条记录封装到一个装有Map的List集合中。
List<Map<String,Object>> list = queryRunner.query("select * from
account",new MapListHandler());
* ColumnListHandler
将数据中的某列封装到List集合中。
List<Object> list = queryRunner.query("select name,money from
account",new ColumListHandler("name"));
** OutPut:虽然sql语句的查询结果设置的是返回两个字段,
但是只会把name字段对应的值返回到List集合
* ScalarHandler 将单个值封装。
Object obj = queryRunner.query("select count(*) from account",
new ScalarHandler());
** count 的返回值为long类型
* KeyedHandler
将一条记录封装到一个Map集合中。将多条记录封装到一个
装有Map集合的Map集合中。而且外面的Map的key是可以指定的。
Map<Object,Map<String,Object>> map = queryRunner.query("select *
from account",new KeyedHandler("id"));
#注意:
1.JavaBean的属性名和mysql表字段名不一致时的处理办法:
* 给查询语句中的字段名取一个与JavaBeanget/set方法名相同的别名(首字母要小写);
2.真正决定JavaBean属性的是get和set方法的方法名
3.创建一个JavaBean时要提供它的无参构造
4.结果集字段名跟表字段名不一定相同(查询时可能会给字段取别名)
|
|