2.读取配置文件,使用 BasicDataSourceFactory工厂类创建DataSource对象
在实际的开发中,需要频繁的对数据库进行操作,就必须频繁的“获取资源”和“释放资源”,而这两个操纵是非常消耗资源的,为了解决这个问题,我们可以使用连接池来对数据库进行操作。在建立连接池的时候,就在池中建立一个或者多个Connection对象,需要连接数据库的时候,直接从连接池中获取Connection对象,使用完毕后,调用close()方法将该对象归还给连接池,这些对象可以重复利用,那么操作数据库就比较的高效了。
连接池主要有两种:DBCP和C3P0。以下以DBCP连接池为例,C3P0连接池:https://blog.csdn.net/Y_Fei/article/details/87995778
使用DBCP连接池需要引入Apache Commons组件中成员:DBCP和Pool
在案例中,我会结合使用Apache Commons组件中的另一个成员:DbUtils
需要导入的jar包:commons-dbcp-1.4.jar commons-dbutils-1.6.jar commons-pool-1.5.6.jar
注意:现在已经有了dbcp2和pool2,如果使用的是这两个jar包的话,还需要导入 commons-logging-1.2.jar,否则会出现如下异常:
dbcp2中没有maxActive、maxWait两个属性,转而是maxTotal、maxWaitMillis,对应的设置方法为setMaxTotal()和setMaxWaitMillis(),在演示代码中的注释也会说明。此案例中未使用maxWait相关属性。
官方下载地址:http://commons.apache.org/
一、DBUtils工具类连接数据库
1.直接创建DataSource对象连接数据库
package jdbcutils;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
/*
* 使用连接池连接MySQL数据库
*/
public class JDBCUtils {
// 创建DateSource接口实现类对象,实现类不是我们自己写的,是jbcp.jar包中的BasicDataSource实现的
private static BasicDataSource dataSource = new BasicDataSource();
// 构造函数私有化
private JDBCUtils() {
}
// 数据库连接只需要执行一次,所以使用静态代码块
static {
// 连接数据库
dataSource.setDriverClassName("com.mysql.jdbc.Driver");// 注册驱动
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");// 设置url
dataSource.setUsername("root");// 设置username
dataSource.setPassword("123");// 设置password
// 自定义连接池,如果不设置,系统会默认设置
//dataSource.setInitialSize(10);// 初始化连接数
dataSource.setMaxIdle(5);// 最大空闲
dataSource.setMinIdle(1);// 最小空闲
/*
* 最大连接数
* 如果使用的是dbcp,使用setMaxActive方法
* 如果使用的是dbcp2,使用setMaxTotal方法
* 此处使用dbcp2
*/
//dataSource.setMaxActive(9);
dataSource.setMaxTotal(9);
}
// 对外提供一个方法,获取DataSource实现类对象
// 方法返回值建议为DataSource,而不是具体实现类,可以提高程序的扩展性
public static DataSource getDataSource() {
return dataSource;
}
}
2.读取配置文件,使用 BasicDataSourceFactory工厂类创建DataSource对象
配置文件放在src目录下,文件名db.properties(后缀名必须是properties),内容如下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=utf8
username=root
password=123
package jdbcutils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class DBCPUtils {
private static DataSource dataSource;
static{
try {
//1.加载找properties文件输入流
InputStream is = DBCPUtils.class.getClassLoader().getResourceAsStream("db.properties");
//2.加载输入流
Properties props = new Properties();
props.load(is);
//3.创建数据源
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("数据库连接失败");
}
}
public static DataSource getDataSource(){
return dataSource;
}
public static Connection getConnection(){
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("数据库连接失败");
}
}
}
二、测试类
package demo;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import jdbcutils.JDBCUtils;
public class DataSourceDemo {
public static void main(String[] args) {
insert();
}
// 插入一条记录
public static void insert() {
try {
// 通过工具类获取DataSource实现类对象
DataSource dataSource = JDBCUtils.getDataSource();
// 创建QueryRunner对象,使用带参构造函数
// 传入DataSource实现类对象,在执行SQL语句的时候就不需要传入Connection对象了
QueryRunner qr = new QueryRunner(dataSource);
// SQL语句
String sql = "INSERT INTO student(sname, sage) VALUES(?,?)";
// 填写占位符
Object[] params = { "石头", 3 };
// 执行SQL语句
int row = qr.update(sql, params);
System.out.println("影响了"+row+"行");
} catch (SQLException e) {
e.printStackTrace();
System.out.println("数据添加失败");
}
}
}