`通过 BasicDataSource 类直接创建数据源对象
在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目录下创建包rabbit.example,并在该包下创建一个Example01类,该类采用手动方式获取数据库的连接信息和数据源的初始化信息
package rabbit.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("123456");
//设置参数池的参数
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());
}
}
运行main()方法后,程序的运行结果如图
通过读取配置文件创建数据源对象
除了使用BasicDataSource 直接创建数据源对象外,还可以使用BasicDataSourceFactory工厂类读取配置文件,创建数据源对象,然后获取数据库连接对象。
(1)在chapter10项目的src目录下创建dbcpconfig.properties文件,该文件用于设置数据库的连接信息和数据源的初始化信息
(2)在rabbit.example包下创建一个Example02类,该类中采用了从配置文件中获取数据库的连接信息和数据源的初始化信息的方式
package rabbit.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());
}
}
运行main()方法后,程序的运行结果如图
通过 ComboPooledDataSource()构造方法创建数据源对象
(1)在项目chapter10中导入JAR包c3p0-0.9.1.2.jar,然后在cn.itcast.chapter10.example
包下创建一个Example03类,该类采用C3PO数据源手动代码的方式获取Connection对象
package rabbit.example;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class Example03 {
public static DataSource ds= null;
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(15);
ds = cpds;
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static void main(String[] args) throws SQLException{
System.out.println(ds.getConnection());
}
}
运行main()方法后,程序的运行结果如图
通过读取配置文件创建数据源对象
使用 ComboPooledDataSource(String configName)构造方法读取c3p0-config.xml配
置文件,从而创建数据源对象,然后获取数据库连接对象。
(1)在src根目录下创建一个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">123456</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="rabbit">
<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">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">15</property>
</named-config>
</c3p0-config>
↑↑↑↑ c3p0-config.xml 配置了两套数据源,.…中的信息是默认配置,在没有指定配置时默认使用该配置创建C3p0数据源对象;…</ named-config >中的信息是自定义配置,一个配置文件中可以有零个或多个自定义配置,当用户需要使用自定义配置时,调用ComboPooledDataSource(String configName)方法,传入节点中name属性的值即可创建C3PO数据源对象。这种设置的好处是,当程序在后期更换数据源配置时,只需要修改构造方法中对应的name值即可。
(2)在pidan.example包下创建一个Example04类,该类中使用C3P0数据源从配置文件中获取Connection对象
package rabbit.example;
import java.sql.SQLException;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class Example04 {
public static DataSource ds= null;
static {
ComboPooledDataSource cpds = new ComboPooledDataSource("pidan");
ds = cpds;
}
public static void main(String[] args) throws SQLException{
System.out.println(ds.getConnection());
}
}
运行main()方法后,程序的运行结果如图
DBUtils 工具
ResultSetHandler 实现类
- 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');
为了查看数据是否添加成功,使用SELECT语句查询user表
从图中可以看出,向user表添加数据成功。
(2)将下载的DBUtils 工具的JAR包commons-dbutils-1.6.jar添加到项目的 lib目录中,并将第9章中文件JDBCUtils.java复制到rabbit.example包下。
(3)在chapter10项目的rabbit.example包中创建一个名为BaseDao的类,该类中编写了一个通用的查询方法
package rabbit.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();
pstmt = conn.prepareStatement(sql);
for (int i = 0; params != null && i < params.length; i++) {
pstmt.setObject(i+1, params[i]);
}
rs = pstmt.executeQuery();
obj = rsh.handle(rs);
} catch (Exception e) {
return new Exception(e.getMessage());
}finally {
JDBCUtils.release(rs, pstmt,conn);
}
return obj;
}
}
(4)在rabbit.example包下创建实体类User,使用该类来封装User对象(建议自己getset)
package rabbit.example;
public class User {
private int id;
private String name,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)在 rabbit.example包下创建类ResultSetTest1,该类用于演示BeanHandler类对结果集的处理
package rabbit.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)执行类ResultSetTest1中的main()方法
输出结果可以看出,BeanHandler已成功将id为1的数据存入到了实体对象user中。
(7)在rabbit.example包下创建类ResultSetTest2,该类用于演示BeanListHandler类对结果集的处理
package rabbit.example;
import java.sql.SQLException;
import java.util.ArrayList;
import org.apache.commons.dbutils.handlers.BeanListHandler;
public class ResultSetTest2 {
public static void testBeanHandler() 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{
testBeanHandler();
}
}
(8)执行类ResultSetTest2中的main()方法
由输出结果可以看出,testBeanListHandler()方法可以将每一行的数据都封装到user实体对象中,并将其存放到list中。
- ScalarHandler
在使用DBUtils工具操作数据库时,如果需要输出结果集中一行数据的指定字段值,可以使用ScalarHandler类。
(1)在 rabbit.example 包下创建类 ResultSetTest3,该类用于演示 ScalarHandler类的使用方法
package rabbit.example;
import java.sql.SQLException;
import org.apache.commons.dbutils.handlers.ScalarHandler;
public class ResultSetTest3 {
public static void testBeanHandler() 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{
testBeanHandler();
}
}
(2)执行类ResultSetTest3中的main()方法
【任务】使用DBUtils实现增删改查
1.创建C3p0Utils类
在项目chapter10的src目录下,创建一个名为rabbit.jdbc.utils的包,然后在该包下创建C3p0Utils类,该类用于创建数据源
package rabbit.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目录下,创建一个名为rabbit.jdbc.demo的包,然后在该包下创建一个DBUtilsDao类,该类实现了对user表增删改查的基本操作。
package rabbit.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 pidan.example.User;
import pidan.jdbc.utils.C3p0Utils;
public class DBUtilsDao {
public List findAll() throws SQLException{
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
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 runner = new QueryRunner(C3p0Utils.getDataSource());
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 runner = new QueryRunner(C3p0Utils.getDataSource());
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 updata(User user) throws SQLException{
QueryRunner runner = new QueryRunner(C3p0Utils.getDataSource());
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 runner = new QueryRunner(C3p0Utils.getDataSource());
String sql = "delete from user where id=?";
int num = runner.update(sql,id);
if (num > 0) {
return true;
}
return false;
}
}
上述代码中,使用了QueryRunner类中带参的方法,将数据源传给QueryRunner对象,并使用QuervRunner对象创建和关闭了数据库连接。
这样,就实现了用DBUtils工具对数据库的基本操作。需要注意的是,在查询方法中,用到了 BeanHandler和BeanListHandler实现类来处理结果集,查询一条数据用的是能够处理一行数据的BeanHandler类,查询所有数据时用的是能处理所有行数据的BeanListHandler类,切勿错误使用,否则会造成程序报错。
3.测试DBUtilsDao类中的增删改查操作
(1)增加数据。在 rabbit.jdbc.demo包中创建类DBUtilsDaoTest1对增加操作进行测试
package rabbit.jdbc.demo;
import java.sql.SQLException;
import rabbit.example.User;
public class DBUtilsDaoTest1 {
private static DBUtilsDao dao = new DBUtilsDao();
public static void testInsert() throws SQLException{
User user = new User();
user.setName("zhaoliu");
user.setPassword("666666");
boolean b = dao.insert(user);
System.out.println(b);
}
public static void main(String[] args) throws SQLException{
testInsert();
}
}
执行DBUtilsDaoTest1的控制台执行结果
从图中可以看到,控制台的输出结果为true,这说明执行插入操作成功。此时在数据库中查询user表中的数据,查询结果如图
从图中可以看出,添加方法执行成功。
(2)修改数据。在rabbit.jdbc.demo包下创建测试类DBUtilsDaoTest2。
package rabbit.jdbc.demo;
import java.sql.SQLException;
import rabbit.example.User;
public class DBUtilsDaoTest2 {
private static DBUtilsDao dao = new DBUtilsDao();
public static void testupdate() throws SQLException{
User user = new User();
user.setName("zhaoliou");
user.setPassword("666777");
user.setId(4);
boolean b = dao.updata(user);
System.out.println(b);
}
public static void main(String[] args) throws SQLException{
testupdate();
}
}
执行DBUtilsDaoTest2的控制台执行结果
从图中可以看出,程序已经执行成功。此时再次查询数据库中user表的数据,查询结果如图
从图中可以看出,修改方法执行成功。
(3)删除数据。在rabbit.jdbc.demo包下创建测试类DBUtilsDaoTest3
package rabbit.jdbc.demo;
import java.sql.SQLException;
import rabbit.example.User;
public class DBUtilsDaoTest3 {
private static DBUtilsDao dao = new DBUtilsDao();
public static void testupdate() throws SQLException{
boolean b = dao.delete(4);
System.out.println(b);
}
public static void main(String[] args) throws SQLException{
testupdate();
}
}
执行DBUtilsDaoTest3的控制台执行结果
从图中可以看到,控制台显示的输出结果为true,此时查询数据库中user表的数据,查询结果如图
从图中可以看出,已成功删除user表中id为4的数据。
(4)查询数据。在rabbit.jdbc.demo包下创建测试类DBUtilsDaoTest4
package rabbit.jdbc.demo;
import java.sql.SQLException;
import rabbit.example.User;
public class DBUtilsDaoTest4 {
private static DBUtilsDao dao = new DBUtilsDao();
public static void testfind() throws SQLException{
User user = dao.find(2);
System.out.println(user.getId() +","+user.getName()+","+user.getPassword());
}
public static void main(String[] args) throws SQLException{
testfind();
}
}
执行DBUtilsDaoTest4的控制台执行结果