数据库链接池与DBUtils工具
由于每次操作数据库,都会执行创建和断开Connection对象的操作,这种频繁的操作Connection对象十分影响数据库的访问的效率,并且增加了代码量,所以在实际的开发中,开发人员通常会使用数据池来解决这类问题。
1.什么是数据库连接池
 1.1 DataSource 接口
 为了获取数据库连接对象( Connection), JDBC提供了javax.sql.DataSource 接口,它负责与数据库建立连接,并定义了返回值为Connection对象的方法。
1.3DBCP数据源
 DBCP是数据库连接池( DataBase Connection Pool )的简称,是Apache组织下的开源连
 接池实现,也是Tomcat服务器使用的连接池组件。单独使用DBCP数据源时,需要在应用程序
 中导入两个JAR包,具体如下。
 1.commons-dbcp.jar 包
 commons-dbcp.jar包是DBCP数据源的实现包,包含所有操作数据库连接信息和数据库
 连接池初始化信息的方法,并实现了DataSource接口的getConnection()方法。
commons-pool.jar 包
 commons- pool.jar包是DBCP数据库连接池实现包的依赖包,为commons -dbcp.jar包中的方法提供了支持。可以这么说,没有该依赖包,commons- dbep.jar包中的很多方法就没有办法实现,还有其他的包如图:
2.通过BasicDataSource类直接创建数据源对象
 1.需要手动给数据源对象设置属性值,然后获取数据库连接对象
 在Eclipse 中创建一个名称为chapter10 的Web项目,在项目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 类,该类采用手动方式获取数据库的连接信息和数据源的初始化信息。
package cn.itcast.chapter10.example;
import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
 public class example01 {
public static DataSource ds=null;
static {
	//
	BasicDataSource bds= new BasicDataSource();
	//
	bds.setDriverClassName("com.mysql.jdbc.Driver");
	bds.setUrl("jdbc:mysql://localhost:3306/jdbc");
	bds.setUsername("root");
	bds.setPassword("123456");
	
	//
	bds.setInitialSize(5);
	bds.setMaxActive(10);
	ds=bds;
}
public static void main(String[] args) throws SQLException {
	Connection conn= ds.getConnection();
	DatabaseMetaData metadata = conn.getMetaData();
	System.out.println(metadata.getURL());
	System.out.println(metadata.getUserName());
	System.out.println(metadata.getDriverName());
}
 
}
运行main()方法后通过读取配置文件创建数据源对象
package cn.itcast.chapter10.example;
 import java.io.InputStream;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.SQLException;
 import java.util.Properties;
 import javax.sql.DataSource;
 import org.apache.commons.dbcp.BasicDataSourceFactory;
 public class example02 {
 public static DataSource ds =null;
 static {
 Properties prop=new Properties();
 try {
 InputStream in =new example02().getClass().getClassLoader().getResourceAsStream(“dbcpconfig.properties”);
		prop.load(in);
		
		ds = BasicDataSourceFactory.createDataSource(prop);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
public static void main(String[] args) throws SQLException {
	Connection conn= ds.getConnection();
	DatabaseMetaData metadata = conn.getMetaData();
	System.out.println(metadata.getURL());
	System.out.println(metadata.getUserName());
	System.out.println(metadata.getDriverName());
 
}
 }
 C3P0数据源
 C3PO是目前最流行的开源数据库连接池之一,它实现了DataSource 数据源接口,支持JDBC2和JDBC3的标准规范,易于扩展并且性能优越,著名的开源框架Hibernate和Spring都支持该数据源。在使用C3PO数据源开发时,需要了解C3PO中DataSource接口的实现类
通过C欧美博Pool额度DataSource()构造方法创建数据源对象
 使用ComboPooledDataSource()构造方法创建数据源对象,需要手动给数据源对象设置属性值,然后获取数据库连接对象,具体步骤如下。
 ( 1 )在项目chapter10中导入JAR包c3p0- 0.9.1.2.jar, 然后在cn.itcast.chapter
 10.example包下创建一个example03类,该类采用C3P0数据源手动代码的方式获取Connection对象,如下
 package cn.itcast.chapter10.example;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.SQLException;
 import javax.sql.DataSource;
 import com.mchange.v2.c3p0.ComboPooledDataSource;
 public class example03 {
 public static DataSource ds = null;
 // 初始化C3P0数据源
 static {
 ComboPooledDataSource cpds = new ComboPooledDataSource();
 // 设置连接数据库需要的配置信息
 try {
 cpds.setDriverClass(“com.mysql.jdbc.Driver”);
 cpds.setJdbcUrl(“jdbc:mysql://localhost:3306/jdbc”);
 cpds.setUser(“root”);
 cpds.setPassword(“123456”);
 // 设置连接池的参数
 cpds.setInitialPoolSize(5);
 cpds.setMaxPoolSize(10);
 ds = cpds;
 } catch (Exception e) {
 e.printStackTrace();
	}
}
public static void main(String[] args) throws SQLException {
	// 获取数据库连接对象
	Connection conn= ds.getConnection();
	DatabaseMetaData metadata = conn.getMetaData();
	System.out.println(metadata.getURL());
	System.out.println(metadata.getUserName());
	System.out.println(metadata.getDriverName());
}
 
}
通过读取配置文件创建数据源对象
 使用ComboPooledDataSource ( String configName )构造方法读取c3p0-config.xml 配置文件,从而创建数据源对象,然后获取数据库连接对象。下面通过一个案例来演示读取配置文件创建数据源对象的使用,具体步骤如下。
 在src目录下创建dbcpconfig.properties
在cn.itcast.chapter10.example包下创建一个Example04类,该类中使用C3P0数据源从配置文件中获取Connection对象
package cn.itcast.chapter10.example;
import java.sql.Connection;
 import java.sql.DatabaseMetaData;
 import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class example04 {
 public static DataSource ds = null;
 // 初始化C3P0数据源
 static {
 ComboPooledDataSource cpds = new ComboPooledDataSource(“dashuju”);
 // 设置连接数据库需要的配置信息
 ds=cpds;
 }
 public static void main(String[] args) throws SQLException {
 // 获取数据库连接对象
 Connection conn= ds.getConnection();
 DatabaseMetaData metadata = conn.getMetaData();
	System.out.println(metadata.getURL());
	System.out.println(metadata.getUserName());
	System.out.println(metadata.getDriverName());
}
 
}
 二、DBUtils工具
 1.DBUtils工具介绍
 为了更加简单地使用JDBC, Apache组织提供了个DBUtis 工具,它是提作数据库的一 一个组件,实现了对JDBC的简单封装,可以在不影响性能的情况下极大地简化JDBC的编码工作量。DBUtis工具可以在“tp:.mmo.h apache orpromons-oduisindex htm”"下载到,截止到目前它的最新版本为Apache Commons DbUtils 1.6.
2.QueryRunner类
 QuerRunner类简化了执行SQL语句的代码,它与ResultHerdler组合在一起就能完成大部分的数据库操作,大大地减少了编码量。
QueryRunner类提供了带有一个参数的构造方法,该方法以javax.sal.DataSource作为参数传递到QueryRunner的构造方法中来获取Connection 对象。
3.ResultSetHandler接口
 ResultSetHandler接口用于处理ResultSet结果集,它可以将结果集中的数据转为不同的形式。根据结果集中数据类型的不同,ResultSetHandler 提供了几种常见的实现类,具体如下:
BeanHandler:将结果集中的第1行数据封装到一个对应的JavaBean实例中。
 BeanL istHandler:将结果集中的每一行数 据都封装到一个对应的JavaBean实例中,并存放到List里。
 ScalarHandler:将结果集中某一条记录的其中某一列的数据存储成Object对象。另外,在ResultSetHandler接口中,提供了-个单独的方法handle
 (java.sql.ResultSet rs),如果上述实现类没有提供想要的功能,可以通过自定义-一个实现ResultSetHandler接口的类,然后通过重写handle()方法,实现结果集的处理。
4.ResultSetHandler实现类
 在介绍了ResultSetHandler 接口中常见实现类的作用后。接下来,通过案例的形式,针对常见实现类的使用进行详细的讲解。
BeanHandler和BeanListHandler
 BeanHandler和BeanlistHandler实现类是将结果集中的数据封装到对应的JavaBean实例中,这也是实际开发中最常用的结果集处理方法。接下来,通过代码实现来学习如何使用BeanHandler和BeanListHandler以及两者的区别。具体步骤如下。
 (1)在名为jdbc的数据库中创建数据表user
向user表插入数据
查看数据是否添加成功
cn.itcast.chapter10.example,并在该包下创建一个JDBCUtils类,该类中编写一个通用的查询方法
package cn.itcast.chapter10.example;
 import java.sql.Connection;
 import java.sql.DriverManager;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 public class JDBCUtils {
 // 加载驱动,并建立数据库连接
 public static Connection getConnection() throws SQLException,
 ClassNotFoundException {
 Class.forName(“com.mysql.jdbc.Driver”);
 String url = “jdbc:mysql://localhost:3306/jdbc”;
 String username = “root”;
 String password = “123456”;
 Connection conn = DriverManager.getConnection(url, username,
 password);
 return conn;
 }
 // 关闭数据库连接,释放资源
 public static void release(Statement stmt, Connection conn) {
 if (stmt != null) {
 try {
 stmt.close();
 } catch (SQLException e) {
 e.printStackTrace();
 }
 stmt = null;
 }
 if (conn != null) {
 try {
 conn.close();
 } catch (SQLException e) {
 e.printStackTrace();
 }
 conn = null;
 }
 }
 public static void release(ResultSet rs, Statement stmt,
 Connection conn){
 if (rs != null) {
 try {
 rs.close();
 } catch (SQLException e) {
 e.printStackTrace();
 }
 rs = null;
 }
 release(stmt, conn);
 }
 }
cn.itcast.chapter10.example,并在该包下创建一个实体User类,使用该类来封装User对象
package cn.itcast.chapter10.example;
 public class User {
 private int id;
 private String name;
 private String password;
 public int getId() {
 return id;
 }
 public void setId(int id) {
 this.id = id;
 }
 public String getName() {
 return name;
 }
 public void setName(String name) {
 this.name = name;
 }
 public String getPassword() {
 return password;
 }
 public void setPassword(String password) {
 this.password = password;
 }
 }
cn.itcast.chapter10.example,并在该包下创建一个ResultSetTest1类,该类用于演示ResultSetTest1类对结果集的处理
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), 3);
 // 判断查询结果,如果是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.itcast.chapter10.example,并在该包下创建一个ResultSetTest2类,该类用于演示ResultSetTest1类对结果集的处理
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 list = (ArrayList) 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();
 }
 }
2020080605030










