学习目标:
1.数据库连接池
2.DBUtils工具
学习内容:
1.数据库连接池
1什么是数据库连接池
在JDBC编程中,每次创建和断开 Connection 对象都会消耗一定的时间和IO资源。这是因为在Java程序与数据库之间建立连接时,数据库端要验证用户名和密码,并且要为这个连接分配资源,Java程序则要把代表连接的java、sql. Connection 对象等加载到内存中,所以建立数据库连接的开销很大,尤其是在大量的并发访问时。假如某网站一天的访问量是10万,那么,该网站的服务器就需要创建、断开连接10万次,频繁地创建、断开数据库连接势必会影响数据库的访问效率,甚至导致数据库崩溃。
为了避免频繁地创建数据库连接,数据库连接池技术应运而生。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的数据库连接,而不是重新建立。接下来,通过一张图来简单描述应用程序如何通过连接池连接数据库。
2.DataSource 接口
为了获取数据库连接对象( Connection ),JDBC提供了javax. sql. Data Source接口,它负责与数据库建立连接,并定义了返回值为 Connection 对象的方法,具体如下。
Connection getConnection ()
-Connection getConnection (String username,String password)
上述两个重载的方法都能用来获取 Connection 对象。不同的是,第1个方法是通过无参的方式建立与数据库的连接,第2个方法是通过传入登录信息的方式建立与数据库的连接。
接口通常都会有其实现类,javax. squ. Data Source接口也不例外,通常习惯性地把实现了javax. sql. Data Source接口的类称为数据源,顾名思义,数据源即数据的来源。在数据源中存储了所有建立数据库连接的信息。就像通过指定文件名称可以在文件系统中找到文件一样,通过提供正确的数据源名称,也可以找到相应的数据库连接。
数据源中包含数据库连接池。如果数据是水,数据库就是水库,数据源就是连接到水库的管道,终端用户看到的数据集是管道里流出来的水。一些开源组织提供了数据源的独立实现,常用的有DBCP数据源和C3P0数据源。接下来的小节中,将会对这两种数据源进行详细的讲解。
3.DBCP数据源
DBCP是数据库连接池( DataBaseConnectionPool )的简称,是Apache组织下的开源连接池实现,也是Tomcat服务器使用的连接池组件。单独使用DBCP数据源时,需要在应用程序中导入两个JAR包:
1. commons-dbcp. jar包
commons-dbcp. jar包是DBCP数据源的实现包,包含所有操作数据库连接信息和数据库连接池初始化信息的方法,并实现了 DataSource 接口的 getConnection ()方法。
2. commons-pool. jar包
commons-pool. jar包是DBCP数据库连接池实现包的依赖包,为commons-dbcp. jar包中的方法提供了支持。可以这么说,没有该依赖包,commons-dbcp. jar包中的很多方法就没有办法实现。
这两个JAR包可以在Apache官网地址“ http://commons.apache.org/proper/ ”中查询下载到。其中,commons-dbcp. jar中包含两个核心的类,分别是 BasicDataSourceFactory 和 BasicDataSource ,它们都包含获取DBCP数据源对象的方法
1.通过 BasicDataSource 类直接创建数据源对象
在项目chapter10中导入mysql-connector-java-5.0.8-bin.jar 、commons-dbcp-1.4. jar以及commons-pool-1.6. jar 3个JAR包,并发布到类路径下,然后在项目的src日录下创建包cn.itcast.chapter10. example,并在该包下创建一个Example01类
结果:
2.通过读取配置文件创建数据源对象
除了使用 BasicDataSource 直接创建数据源对象外,还可以使用 BasicDataSourceFactory 工厂类读取配置文件,创建数据源对象,然后获取数据库连接对象。
(1)在chapter10项目的src目录下创建 dbopconfig . properties 文件,该文件用于设置数据库的连接信息和数据源的初始化信息。
(2)在cn.itcast.chapter10. example包下创建一个Example02类,该类中采用了从配置文件中获取数据库的连接信息和数据源的初始化信息的方式。
4.C3P0数据源
C3P0是目前最流行的开源数据库连接池之一,它实现了 DataSource 数据源接口,支持JDBC2和JDBC3的标准规范,易于扩展并且性能优越,著名的开源框架Hibernate和Spring都支持该数据源。在使用C3P0数据源开发时,需要了解C3P0中 DataSource 接口的实现类 ComboPooledDataSource ,它是C3PO的核心类,提供了数据源对象的相关方法。
1.通过 ComboPooledDataSource ()构造方法创建数据源对象
使用 ComboPooledDataSource ()构造方法创建数据源对象,需要手动给数据源对象设置属性值,然后获取数据库连接对象。
在项目chapter10中导入JAR包c3p0-0.9.1.2. jar,然后在cn.itcast.chapter10. example包下创建一个Example03类,该类采用C3PO数据源手动代码的方式获取 Connection 对象。
2.通过读取配置文件创建数据源对象
使用 ComboPooledDataSource (String configName )构造方法读取c3p0-config .xml配置文件,从而创建数据源对象,然后获取数据库连接对象。下面通过一个案例来演示读取配置文件创建数据源对象的使用,具体步骤如下。
(1)在src根目录下创建一个c3p0-config. xml文件,用于设置数据库的连接信息和数据源初始化信息
(2)在cn.itcast.chapter10、example包下创建一个Example04类,该类中使用C3PO数据源从配置文件中获取 Connection 对象
C3PO数据源对象成功获取到了数据库连接对象。需要注意的是,在使用 ComboPooledDataSource (String config Name)方法创建对象时必须遵循以下两点。
1)配置文件名称必须为c3p0-config. xml或者c3p0. properties ,并且位于该项目的sro目录下。
(2)当传入的 configName 值为空或者不存在时,则使用默认的配置方式创建数据源
2.DBUtils工具
1.DBUtils工具介绍
为了更加简单地使用JDBC,Apache组织提供了一个DBUtils工具,它是操作数据库的一个组件,实现了对JDBC的简单封装,可以在不影响性能的情况下极大地简化JDBC的编码工作量。
DBUtils工具可以在“ http://commons.apache.org/proper/commons-doubties/index.html 下载到,截止到目前它的最新版本为Apache CommonsDbUtils1 .6,本节也是针对该版本进行讲解的。
DBUtisT具的核心是org. apache. commons. dbuttls. QueryRunner 类和org. apache. commons. dbutils. ResultSetHandler 接口,了解它们对于DBUtils工具的学习和使用非常重要。
QueryRunner 类
QueryRunner 类简化了执行SQL语句的代码,它与 ResultSetHandler 组合在一起就能完成大部分的数据库操作,大大地减少了编码量。
QueryRunner 类提供了带有一个参数的构造方法,该方法以 javascript 、sql. Data Source作为参数传递到 QueryRunner 的构造方法中来获取 Connection 对象。针对不同的数据库操作, QueryRunner 类提供了几种常见的方法,具体如下。
●query(String sql, ResultSetHandlerrsh ,Object... params)方法该方法用于执行查询操作,它可以从提供给构造方法的数据源 DataSource 或使用的 setDataSource ()方法中获得连接。
。update(String sql,Object... params)方法
该方法用于执行插入、更新或者删除操作,其中,参数params表示SQL语句中的置换参数。
。update(String sql)方法该方法用来执行插入、更新或者删除操作,他不需要置换参数。
ResultSetHandler 接口
ResultSetHandler 接口用于处理ResultSet结果集,它可以将结果集中的数据转为不同的形式。根据结果集中数据类型的不同, ResultSetHandler 提供了几种常见的实现类,具体如下。
。 BeanHandler ;将结果集中的第1行数据封装到一个对应的JavaBean实例中。
。BeanListHandler :将结果集中的每一行数据都封装到一个对应的JavaBean实例中,并存放到List里。
。Scalar Handler:将结果集中某一条记录的其中某一列的数据存储成Object对象。
另外,在 RiesulliSetHandler 接口中,提供了一个单独的方法handle(java、sql、Result Setrs),如果上述实现类没有提供想要的功能,可以通过自定义一个实现 ResultSetHandler 接口的类,然后通过重写handle()方法,实现结果集的处理。
ResultSetHandler 实现类
1. BeanHandler 和 BeanListHandler
BeanHandler 和 BeanListHandler 实现类是将结果集中的数据封装到对应的JavaBean实例中,这也是实际开发中最常用的结果集处理方法。接下来,通过代码实现来学习如何使用 BeanHandler 和 BeanListHandler 以及两者的区别。具体步骤如下。
(1)在名为jdbc的数据库中创建数据表user并查询。
(2)将下载的DBUtils工具的JAR包commons-dbutls-1.6. jar添加到项目的lib目录中,将第9章中文件9- 5JDBCUtils 、java复制到cn. itcast.chapter10. example包下。
(3)在chapter10项目的cn, itcast.chapter10. example包中创建一个名为BaseDao的类,该类中编写了一个通用的查询方法
package cn.itcast.chapter10.example;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BaseDao {
// 优化查询
public static Object query(String sql, ResultSetHandler<?> rsh,
Object... params) throws SQLException {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
// 定义一个返回结果
Object obj = null;
try {
// 获得连接
conn = JDBCUtils.getConnection();
// 预编译sql
pstmt = conn.prepareStatement(sql);
// 将参数设置进去
for (int i = 0; params != null && i < params.length; i++)
{
pstmt.setObject(i + 1, params[i]);
}
// 发送sql
rs = pstmt.executeQuery();
// 让调用者去实现对结果集的处理
obj = rsh.handle(rs);
} catch (Exception e) {
// 出现异常,返回封装的异常信息
return new Exception(e.getMessage());
}finally {
// 释放资源
JDBCUtils.release(rs, pstmt, conn);
}
return obj;
}
}
在cn.licast.chapter10. example包下创建实体类user用该类来封装User对象
在cn.itcast.chapter10. example包下创建类 ResultSetTest1 ,该类用于演示Bean Handler类对结果集的处理,
package cn.itcast.chapter10.example;
import java.sql.SQLException;
import org.apache.commons.dbutils.handlers.BeanHandler;
public class ResultSetTest1 {
public static void testBeanHandler() throws SQLException {
BaseDao basedao = new BaseDao();
String sql = "select * from user where id=?";
// 获取查询结果
Object object = basedao.query(sql, new BeanHandler(User.class), 1);
// 判断查询结果,如果是User类就进行打印,否则打印查询的结果信息
if (object!=null && object instanceof User){
User user= (User) object;
System.out.print("id为1的User对象的name值为:" + user.getName());
}else {
System.out.println("查询结果为空: "+object);
}
}
public static void main(String[] args) throws SQLException {
testBeanHandler();
}
}
在cn. itcastchapter10 .example包下创建类ResulíSetTest2,该类用于演示 BeanListHander 类对结果集的处理
package cn.itcast.chapter10.example;
import java.sql.SQLException;
import java.util.ArrayList;
import org.apache.commons.dbutils.handlers.BeanListHandler;
public class ResultSetTest2 {
public static void testBeanListHandler() throws SQLException {
BaseDao basedao = new BaseDao();
String sql = "select * from user ";
ArrayList<User> list = (ArrayList<User>) basedao.query(sql,
new BeanListHandler(User.class));
for (int i = 0; i < list.size(); i++) {
System.out.println("第" + (i + 1) + "条数据的username值为:"
+ list.get(i).getName());
}
public static void main(String[] args) throws SQLException {
testBeanListHandler();
}
}
2. ScalarHandler
在使用DBU的Is工具操作数据库时,如果需要输出结果集中一行数据的指定字段值,可以使用Scalar Handler类。接下来,通过一个案例来演示Scalar Handler类的使用。
(1)在cn. itcastchapter10 .example包下创建类 ResuliSetTest3 ,该类用于演示Scalara Handler类的使用方法
package cn.itcast.chapter10.example;
import java.sql.SQLException;
import org.apache.commons.dbutils.handlers.ScalarHandler;
public class ResultSetTest3 {
public static void testScalarHandler() throws SQLException {
BaseDao basedao = new BaseDao();
String sql = "select * from user where id=?";
Object arr = (Object) basedao.query(sql,
new ScalarHandler("name"), 1);
System.out.println(arr);
}
public static void main(String[] args) throws SQLException {
testScalarHandler();
}
}
使用DBUtils实现增删改查
.创建C3p0Utils类
在项目chapter10的src目录下,创建一个名为cn.itcast.jdbc.utils的包,然后在该包下创C3pOUtils类,该类用于创建数据源
package cn.itcast.jdbc.utils;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3p0Utils {
private static DataSource ds;
static {
ds = new ComboPooledDataSource();
}
public static DataSource getDataSource() {
return ds;
}
}
2.创建 DBUtilsDao 类
在项目chapter10的src且录下,创建一个名为cn.itcast.jdbc.demo的包,然后在该包下创建一个 DBUtilsBao 类,该类实现了对user表增删改查的基本操作
3.测试 DBUtilsDao 类中的增删改查操作
(1)增加数据。在cn.itcast.jdbc.demo包中创建类 DBUtilsDaoTest1 对增加操作进行测试
修改数据。在包cn.itcast.jdbc.demo下创建测试类 DBUtilsDaoTest2
删除数据。在包cn.itcast.jdbc.demo下创建测试类 DBUtilsDaoTest3
查询数据。在包cn.itcast.jdbc.demo下创建测试类DBUtilsDaoTest4
2020080605009