前言:
使用JDBC的基本用法和操作来与数据库交互,由于每操作一次数据库,都会执行一次创建和断开Connection对象的操作,这种频繁的操作Connection对象十分影响数据库的访问效率,并且增加了代码量,所以在实际开发中,开发人员通常会使用数据库连接池来解决这些问题。Apache组织还提供了一个DBUtils工具类库,该类库实现了对JDBC的简单封装,能在不影响性能的情况下极大地简化JDBC的编码工作。
数据库连接池:
什么是数据库连接池:
在JDBC编程中,每次创建和断开Connection对象都会消耗一定的时间和IO资源。这是因为在Java程序与数据库之间建立连接时,数据库端要验证用户名和密码,并且要为这个连接分配资源,Java程序则要把代表连接的java.sql.Connection对象等加载到内存中,所以建立数据库连接的开销很大,尤其是在大量的并发访问时。假如某网站一天的访问量是10万,那么,该网站的服务器就需要创建、断开连接10万次,频繁地创建、断开数据库连接势必会影响数据库的访问效率,甚至导致数据库崩溃。为了避免频繁地建数据库连接,数据库连接池技术应运而生。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的数据库连接,而不是重新建立。接下来,通过一张图来简单描述应用程序如何通过连接池连接数据库,如下图所示。
从上图中可以看出,数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,当应用程序访问数据库时并不是直接创建Connection, 而是向连接池“申请”一个Connection。如果连接池中有空闲的Connection,则将其返回,否则创建新的Connection。使用完毕后,连接池会将该Connection回收,并交付其他的线程使用,以减少创建和断开数据库连接的次数,提高数据库的访问效率。
DataSource接口
为了获取数据库连接对象,JDBC提供了javax.sql.DataSource接口,它负责与数据库建立连接,并定义了返回值为Connection对象的方法,具体如下:
1.Connection getConnection()
2.Connection getConnection(String username,String password)
上述两个重载的方法都能用来获取Connection对象。不同的是,第1个方法是通过无参的方式建立与数据库的连接,第2个方法是通过传入登录信息的方式建立于数据库的连接
接口通常都会有其实现类,javax.sql.DataSource接口也不例外,通常习惯性地把实现了javax.sql.DataSource接口的类称为数据源,顾名思义,数据源即数据的来源。在数据源中存储了所有建立数据库的连接信息。就像通过指定文件名称可以在文件系统中找到文件一样,也可以找到相应的数据库连接
数据源包含数据库连接池。如果数据是水,数据库就是水库,数据源就是连接到水库的管道,终端用户看到的数据集是管道里流出来的水。一些开源组织提供了数据源的独立实现,常用的有DBCP数据源和C3P0数据源
DBCP数据源
DBCP:是数据库连接池的简称,是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包中的很多方法就没有办法实现
commons-dbcp.jar中包含两个核心的类,分别是BasicDataSourceFactory和BasicDataSource,它们都包含获取DBCP数据源对象的方法
BasicDataSourceFactory:是DataSource接口的实现类,主要包括设置数据源对象的方法,具体方法如下:
方法名 | 功能描述 |
---|---|
void setDriverClassName(String driverClassName) | 设置数据库的驱动名称 |
void setUrl(String url) | 设置连接数据库的路径 |
void setUsername(String username) | 设置数据库登录账户 |
void setPassword(String password) | 设置数据库的登录密码 |
void setInitialSize(int initialSixe) | 设置数据库连接池初始化的连接数目 |
void setMaxActive(int maxldle) | 设置数据库连接池最大活跃的连接数目 |
void setMinldle(int minldle) | 设置数据库连接池最小闲置的连接数目 |
connection getConnection() | 从连接池中获取一个数据库连接 |
在表中,列举了BasicDataSource对象的常用方法,其中,setDriverClassName()、setUrl()、setUsername()、setPassword()等方法都是设置数据库连接信息的方法,setlnitialSize()、
存储setMaxActive()、setMinldle()等方法都是设置数据库连接池初始化值的方法,getConnection()
方法表示从DBCP数据源中获取一个数据库连接。
BasicDataSourceFactory 是创建BasicDataSource 对象的工厂类,它包含一个返回值为
BasicDataSource对象的方法createDataSource(),该方法通过读取配置文件的信息生成数据源
对象并返回给调用者。这种把数据库的连接信息和数据源的初始化信息提取出来写进配置文件的方式,让代码看起来更加简洁,思路也更加清晰。
当使用DBCP数据源时,首先要创建数据源对象,数据源对象的创建方式有两种,具体如下。
数据源对象的创建
1.通过 BasicDataSource 类直接创建数据源对象
在使用 BasicDataSource类创建一个数据源对象时,需要手动给数据源对象设置属性值,然后获取数据库连接对象。接下来,通过一个案例来演示BasicDataSource类的使用,具体步骤如下。
(1)导包
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 {
// 获取DBCP数据源实现类对象
BasicDataSource bds = new BasicDataSource();
// 设置连接数据库需要的配置信息
bds.setDriverClassName("com.mysql.jdbc.Driver");
bds.setUrl("jdbc:mysql://localhost:3306/jdbc");
bds.setUsername("root");
bds.setPassword("root");
// 设置连接池的参数
bds.setInitialSize(5);
bds.setMaxActive(5);
ds = bds;
}
public static void main(String[] args) throws SQLException {
// 获取数据库连接对象
Connection conn = ds.getConnection();
//获取数据库连接信息
DatabaseMetaData metaData = conn.getMetaData();
//打印数据库连接信息
System.out.println(metaData.getURL()
+",UserName="+metaData.getUserName()
+","+metaData.getDriverName());
}
}
2.通过读取配置文件创建数据源对象
(1)除了使用 BasicDatasource自接创建数据源对象外,还可以使用BasicDataSourceFactory
工厂类读取配置文件,创建数据源对象,然后获取数据库连接对象。
#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=root
#初始化连接
initialSize=5
#最大连接数量
maxActive=10
#最大空闲连接
maxIdle=10
(2)创建一个Example02类,该类中采用了从配量文件中获取数据库的连接信息和数据源的初始化信息的方式
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) {
throw new ExceptionInInitializerError(e);
}
}
public static void main(String[] args) throws SQLException {
// 获取数据库连接对象
Connection conn = ds.getConnection();
//获取数据库连接信息
DatabaseMetaData metaData = conn.getMetaData();
//打印数据库连接信息
System.out.println(metaData.getURL()
+",UserName="+metaData.getUserName()
+","+metaData.getDriverName());
}
}
(3)运行main()方法
C3P0数据源
C3P0是目前最流行的开源数据库连接池之一,它实现了DataSource数据源接口,支持JDBC2和JDBC3的标准规范,易于扩展并且性能优越,著名的开源框架Hibernate和Spring都支持该数据源。在使用C3P0数据源开发时,需要了解C3P0中DataSource接口的实现类ComboPooledDataSource,它是C3P0的核心类,提供了数据源对象的相关方法,该类的常用方法介绍如下:
当使用C3P0数据源时,首先需要创建数据源对象,创建数据源对象可以使用Combo-PooledDataSource类,该类有两个构造方法,分别是ComboPooledDataSource()和ComboPooledDataSource(String configName)
1.通过ComboPooledDataSource()构造方法创建数据源对象
(1)创建Example03,采用C3p0数据手动代码的方式获取Connection对象
package cn.itcast.chapter10.example;
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("root");
// 设置连接池的参数
cpds.setInitialPoolSize(5);
cpds.setMaxPoolSize(15);
ds = cpds;
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static void main(String[] args) throws SQLException {
// 获取数据库连接对象
System.out.println(ds.getConnection());
}
}
(2)执行main方法
2.通过读取配置文件创建数据源对象
使用ComboPooledDataSource(String connfigName)构建方法读取c3p0-config.xml配置文件,从而创建数据源对象,获取数据库连接对象
(1)创建c3p0-config.xml,用于设置数据库的连接信息和数据源的初始化信息
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">
jdbc:mysql://localhost:3306/jdbc
</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="checkoutTimeout">30000</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
<named-config name="dashuju">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">
jdbc:mysql://localhost:3306/jdbc
</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">15</property>
</named-config>
</c3p0-config>
在文件中,c3p0-config.xml配置了两套数据源,<default-config>.….</default-config>中的信息是默认配置,在没有指定配置时默认使用该配置创建C3p0数据源对象;<named-config>…</ named-config >中的信息是自定义配置,一个配置文件中可以有零个或多个自定义配置,当用户需要使用自定义配置时,调用ComboPooledDataSource(String configName)方法,传入<named-config>节点中name属性的值即可创建C3PO数据源对象。这种设置的好处是,当程序在后期更换数据源配置时,只需要修改构造方法中对应的name值即可。
(2)创建Example04.该类使用C3P0数据源从配置文件中获取Connection对象
package cn.itcast.chapter10.example;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class Example04 {
public static DataSource ds = null;
// 初始化C3P0数据源
static {
// 使用c3p0-config.xml配置文件中的named-config节点中name属性的值
ComboPooledDataSource cpds = new ComboPooledDataSource("root");
ds = cpds;
}
public static void main(String[] args) throws SQLException {
System.out.println(ds.getConnection());
}
}
(3)执行main方法
从图可以看出,C3PO数据源对象成功获取到了数据库连接对象。需要注意的是,在使用ComboPooledDataSource(String configName)方法创建对象时必须遵循以下两点。
1)配置文件名称必须为c3p0-config.xml或者c3p0.properties,并且位于该项目的src根
目录下。
2)当传入的configName值为空或者不存在时,则使用默认的配置方式创建数据源。
DBUtils工具
DBUtils工具介绍
为了更加简单地使用JDBC,Apache组织提供了一个DBUtils工具,它是操作数据库的一个组件,实现了对JDBC的简单封装,可以在不影响性能的情况下极大地简化JDBC的编码工作量
DBUtils工具核心是org.apache.commons.dbutils.QueryRunner类和org.apache.commons.dbutils.ResultSetHandler接口,了解它们对于DBUtils工具的学习和使用非常重要
QueryRunner类
QueryRunner类简化了执行SQL语句的代码,它与ResultSetHandler组合在一起就能完成大部分的数据库操作,大大地减少了编码量
QueryRunner类提供了带有一个参数的构造方法,该方法以javax.sql.DataSource作为参数传递到QueryRunner的构造方法中来获取Connection对象。针对不同的数据库操作,QueryRunner类提供了几种常见的方法,具体如下:
(1)query(String sql,ResultSetHandler rsh,Object…params)方法
该方法用于执行查询操作,它可以从提供给构造方法的数据源DataSource或使用的setDataSource()方法中获得连接(2)update(String sql,object…params)方法
该方法用于执行插入,更新或者删除操作,其中,参数params表示SQL语句中的置换参数
(3)update(String sql)方法
该方法用来执行插入,更新或者删除操作,它不需要置换参数
ResultSetHandler接口
ResultSetHandler接口用于处理ResultSet结果集,它可以将结果集中的数据转为不同的形式。根据结果集中数据类型的不同,ResultSetHandler提供了几种常见的实现类型,具体如下:
(1)BeanHandler:将结果集中的第1行数据封装到一个对应的JavaBean实例中
(2)BeanListHandler:将结果集中的每一行数据都封装到一个对象的JavaBean实例中,并放到List里
(3)ScalarHandler:将结果集中某一条记录的其中某一列的数据存储成Object对象
(4)handle(java.sql.ResultSet rs):如果实现类没有提供想要的功能,可以通过自定义实现ResultSetHandler接口的类,然后通过重写handle()方法,实现结果集的处理
ResultSetHandler实现类
介绍了ResultSetHandler接口中常见实现类的作用。接下来,通过案例的形式,针对常见实现类的使用进行详细的讲解。
1. BeanHandler 和 BeanListHandler
BeanHandler和BeanListHandler实现类是将结果集中的数据封装到对应的JavaBean实例中,这也是实际开发中最常用的结果集处理方法。
(1)在名为jdbc的数据库中创建数据表user,创建语句如下。
USE jdbc;
CREATE TABLE user (
id INT (3) PRIMARY KEY AUTO INCREMENT,
name VARCHAR (20) NOT NULL,
password VARCHAR(20) NOT NULL
);
向user表插入3条数据,具体语句如下。
INSERT INTO user (name,password) VALUES ('zhangsan', '123456');
INSERT INTO user (name,password) VALUES ('lisi','123456');
INSERT INTO user (name,password) VALUES ('wangwu','123456');
(2)将下载的DBUtils 工具的JAR包commons-dbutils-1.6.jar添加到项目的lib目录中,并将第9章中文件9-5 JDBCUtils.java复制到cn.itcast.chapter10.example 包下。
(3)example包中创建一个名为BaseDao的类,该类中编写了一个通用的查询方法
package cn.itcast.chapter10.example;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.dbutils.ResultSetHandler;
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;
}
}
(4)创建实体类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;
}
}
(5)创建类ResultSetTest1,用于演示BeanHandler类对结果集的处理
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);
if (object != null && object instanceof User) {
User user = (User) object;
System.out.println("id为1的User对象的name值为:" + user.getName());
} else {
System.out.println("查询结果为空:" + object);
}
}
public static void main(String[] args) throws SQLException {
testBeanHandler();
}
}
(6)执行main()方法
BeanHandler已成功将ID为1的数据存入实体对象user中
(7)创建ResultSetTest2演示BeanListHandler类对结果集的处理
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();
}
}
(8)执行main()方法
可以看出testBeanListHandler()方法可以将每一行的数据都封装到user实体中,并存放到list中
2.ScalarHandler
在使用DBUtils工具操作数据库时,如果需要输出结果集中一行数据的指定字段值,可以使用ScalarHandler类。接下来,通过一个案例来演示ScalarHandler类的使用。
(1)创建类ResultSetTest3,该类用于演示ScalarHandler类的使用方法
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();
}
}
(2)执行main()方法
使用DBUtils实现增删改查
1.创建C3p0Utils类
用于创建数据源
package cn.itcast.jdbc.utils;
import java.sql.DatabaseMetaData;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3p0Utils {
private static ComboPooledDataSource ds;
static {
ds=new ComboPooledDataSource();
}
public static DataSource getDataSource() {
return ds;
}
}
2.创建DBUtilsDao类
实现对user表增删改查的基本操作
package cn.itcast.jdbc.demo;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import cn.itcast.chapter10.example.User;
import cn.itcast.jdbc.utils.C3p0Utils;
public class DBUtilsDao {
// 查询所有,返回List集合
public List findAll() throws SQLException {
// 创建QueryRunner对象
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
// 写SQL语句
String sql = "select * from user";
// 调用方法
List list = (List) runner.query(sql,
new BeanListHandler(User.class));
return list;
}
// 查询单个,返回对象
public User find(int id) throws SQLException {
// 创建QueryRunner对象
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
// 写SQL语句
String sql = "select * from user where id=?";
// 调用方法
User user = (User) runner.query(sql,
new BeanHandler(User.class), new Object[] { id });
return user;
}
// 添加用户的操作
public Boolean insert(User user) throws SQLException {
// 创建QueryRunner对象
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
// 写SQL语句
String sql = "insert into user (name,password) values (?,?)";
// 调用方法
int num = runner.update(sql,
new Object[] { user.getName(), user.getPassword() });
if (num > 0)
return true;
return false;
}
// 修改用户的操作
public Boolean update(User user) throws SQLException {
// 创建QueryRunner对象
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
// 写SQL语句
String sql = "update user set name=?,password=? where id=?";
// 调用方法
int num = runner.update(sql, new Object[] { user.getName(),
user.getPassword(),user.getId() });
if (num > 0)
return true;
return false;
}
// 删除用户的操作
public Boolean delete(int id) throws SQLException {
// 创建QueryRunner对象
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
// 写SQL语句
String sql = "delete from user where id=?";
// 调用方法
int num = runner.update(sql, id);
if (num > 0)
return true;
return false;
}
}
上述代码中,使用了QueryRunner类中带参的方法,将数据源传给QueryRunner对象,并使用QueryRunner对象创建和关闭了数据库连接。
这样,就实现了用DBUtils工具对数据库的基本操作。需要注意的是,在查询方法中,用到了BeanHandler和BeanListHandler实现类来处理结果集,查询一条数据用的是能够处理一行数据的BeanHandler类,查询所有数据时用的是能处理所有行数据的BeanListHandler类,切勿错误使用,否则会造成程序报错。
3.测试DBUtilsDao类中的增删查改操作
(1) 创建DBUtilsDaoTest1对其增加操作进行测试
package cn.itcast.jdbc.demo;
import java.sql.SQLException;
import cn.itcast.chapter10.example.User;
public class DBUtilsDaoTest1 {
private static DBUtilsDao dao = new DBUtilsDao();
public static void testInsert() throws SQLException {
User user = new User();
user.setName("chanyeo");
user.setPassword("777788");
boolean b = dao.insert(user);
System.out.println(b);
}
public static void main(String[] args) throws SQLException {
testInsert();
}
}
结果为true插入成功,在数据库查询user表数据
(2)创建DBUtilsDaoTest2,修改数据
package cn.itcast.jdbc.demo;
import java.sql.SQLException;
import cn.itcast.chapter10.example.User;
public class DBUtilsDaoTest2 {
private static DBUtilsDao dao = new DBUtilsDao();
public static void testupdate() throws SQLException {
User user = new User();
user.setName("cherry");
user.setPassword("666777");
user.setId(4);
boolean b = dao.update(user);
System.out.println(b);
}
public static void main(String[] args) throws SQLException {
testupdate();
}
}
(3)创建DBUtilsDaoTest3,删除数据
package cn.itcast.jdbc.demo;
import java.sql.SQLException;
public class DBUtilsDaoTest3 {
private static DBUtilsDao dao = new DBUtilsDao();
public static void testdelete() throws SQLException {
boolean b = dao.delete(4);
System.out.println(b);
}
public static void main(String[] args) throws SQLException {
testdelete();
}
}
(4)创建DBUtilsDaoTest4,查询数据
package cn.itcast.jdbc.demo;
import java.sql.SQLException;
import cn.itcast.chapter10.example.User;
public class DBUtilsDaoTest4 {
private static DBUtilsDao dao = new DBUtilsDao();
public static void testfind() throws SQLException {
User user = dao.find(5);
System.out.println(user.getId() + "," + user.getName() + ","
+ user.getPassword());
}
public static void main(String[] args) throws SQLException {
testfind();
}
}
成功显示id为5的数据信息,可以看出DBUtils工具在减少代码量的同时,还增强了代码的规整性和易读性
思考
1.请思考数据库连接池的工作机制是什么?
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,当应用程序访问数据库时并不是直接创建Connection,而是向连接池“申请”一个Connection。如果连接池中有空闲的Connection,则将其返回,否则创建新的Connection。使用完毕后,连接池会将该Connection回收,并交付其他的线程使用,以减少创建和断开数据库连接的次数,提高数据库的访问效率。
2、DriverManager和DataSource中的getConnection()方法的区别如下:
1)DriverManager每次调用getConnection方法都会初始化一个新的连接,而DataSource的getConnection只是从池中取出一个已存在的连接
2)DriverManager的close()是释放Connection,而DataSource的close()只会把Connection归还给连接池。