JDBC以及连接池DBCP、C3P0使用
学习本篇博客所需内容:
- 所需要的数据库及表和数据
CREATE DATABASE IF NOT EXISTS jdbcstudy CHARACTER SET utf8 COLLATE utf8_general_ci;
USE jdbcstudy;
CREATE TABLE `users`(
`id` INT PRIMARY KEY,
`name` VARCHAR(40),
`password` VARCHAR(40),
`email` VARCHAR(60),
`birthday` DATE
)ENGINE = INNODB DEFAULT CHARSET=utf8;
INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`)
VALUES(1,'zhangsan','123456','zs@sina.com','1980-12-04'),
(2,'lisi','123456','lisi@sina.com','1981-12-04'),
(3,'wangwu','123456','wangwu@sina.com','1979-12-04');
-
使用工具
idea2020.3.1(若想了解如何下载及破解请下方留言,尽快更新)
-
需要下载的内容
maven仓库(需要压缩包留言,看到必回复),mysql5.7.29(如何下载安装已发博客),jdk1.8
1.JDBC
1.1.JDBC的定义
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。
1.2.JDBC的用途
- 与数据库建立连接
- 发送操作数据库的语句
- 处理结果
1.3JDBC的使用
- 创建maven项目
- 添加依赖
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependencies>
说明:如果没有自动下载的可以去手动下载。(DBCP、C3P0的依赖若没有,也可进入该下载地址下载)
下载地址:http://search.maven.org/#search%7Cga%7C1%7Cmybatis
- 创建db.properties(放在resources目录下)
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
说明:安全连接MySQL 5.5.45+, 5.6.26+ or 5.7.6+默认useSSL=true,之前低版本为useSSL=false。
4.写工具类
/*
步骤:
1.创建四个静态资源
2.利用反射获取资源,返回到输入流对象中。
3.创建Properties对象。获取每个静态资源的值。
4.加载驱动。
5.获取连接。
6.释放资源。
*/
public class JdbcUtils {
private static String driver = null;
private static String url = null;
private static String username = null;
private static String password = null;
static {
try {
InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(in);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
//加载驱动
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
Connection connection = DriverManager.getConnection(url, username, password);
return connection;
}
//释放连接资源
public static void release(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
}
}
- 实现增删改,查。
public class TestInsert {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = JdbcUtils.getConnection();
//使用?占位符代替参数
String sql = "insert into users(`id`,`name`,`password`,`email`,`birthday`) values(?,?,?,?,?)";
preparedStatement = connection.prepareStatement(sql);//预编译sql,先写sql,然后不执行
//手动给参数赋值
preparedStatement.setInt(1, 4);
preparedStatement.setString(2, "haha");
preparedStatement.setString(3, "123456");
preparedStatement.setString(4, "hh@sina.com");
preparedStatement.setDate(5, new java.sql.Date(new Date().getTime()));
int i = preparedStatement.executeUpdate();
if (i > 0) {
System.out.println("插入成功!");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils.release(connection, preparedStatement, null);
}
}
}
说明:这里只演示增加,查询,注意的是,增删改执行对象调的方法是executeUpdate(),查询调的方法是executeQuery()。
public class TestQuery {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet =null;
try {
connection=JdbcUtils.getConnection();
String sql = "select * from users where `name` = ? and `password` = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, "haha");
preparedStatement.setString(2, "123456");
resultSet = preparedStatement.executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getInt("id"));
System.out.println(resultSet.getString("name"));
System.out.println(resultSet.getString("password"));
System.out.println(resultSet.getString("email"));
System.out.println(resultSet.getObject("birthday"));
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils.release(connection, preparedStatement, resultSet);
}
}
}
2.DBCP
2.1.DBCP的定义
DBCP(DataBase Connection Pool)数据库连接池,是Java数据库连接池的一种,由Apache开发,通过数据库连接池,可以让程序自动管理数据库连接的释放和断开。
2.2.DBCP的使用
- pom文件中添加依赖
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.6</version>
</dependency>
- resources目录下建立dbcpconfig.properties
#连接设置 这里面的名字,是DBCP数据源中定义好的
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456
#初始化连接
initialSize=10
#最大连接数量
maxActive=50
#最大空闲连接
maxIdle=20
#最小空闲连接
minIdle=5
#超时等待时间以毫秒为单位 6000毫秒/1000等于60秒
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=UTF8
#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true
#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=
#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED
- DBCP的工具类
public class JdbcUtils_DBCP {
private static DataSource dataSource = null;
static {
try {
InputStream in = JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
Properties properties = new Properties();
properties.load(in);
//创建数据源
dataSource= BasicDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//释放连接资源
public static void release(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
}
}
- 测试DBCP
public class TestDBCP {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = JdbcUtils_DBCP.getConnection();
//使用?占位符代替参数
String sql = "insert into users(`id`,`name`,`password`,`email`,`birthday`) values(?,?,?,?,?)";
preparedStatement = connection.prepareStatement(sql);//预编译sql,先写sql,然后不执行
//手动给参数赋值
preparedStatement.setInt(1, 6);
preparedStatement.setString(2, "hello");
preparedStatement.setString(3, "111111");
preparedStatement.setString(4, "hello@sina.com");
preparedStatement.setDate(5, new java.sql.Date(new Date().getTime()));
int i = preparedStatement.executeUpdate();
if (i > 0) {
System.out.println("插入成功!");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils_DBCP.release(connection, preparedStatement, null);
}
}
}
3.C3P0
3.1.C3P0的定义
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate、Spring等。
3.2.C3P0的使用
- 添加依赖
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.5</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>mchange-commons-java</artifactId>
<version>0.2.19</version>
</dependency>
- resources下创建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/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<!--若对象带参数则使用自定义的MySQL的配置 -->
<named-config name="MySQL">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">10</property>
<property name="minPoolSize">5</property>
<property name="maxPoolSize">20</property>
</named-config>
</c3p0-config>
- C3P0工具类
public class JdbcUtils_C3P0 {
private static ComboPooledDataSource dataSource = null;
static {
try {
//创建数据源
//dataSource = new ComboPooledDataSource("MySQL");//写参数则使用自定义配置
dataSource = new ComboPooledDataSource();//不写参数则使用默认的那一套配置(.xml)
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//释放连接资源
public static void release(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
}
}
- 测试C3P0
public class TestC3P0 {
public static void main(String[] args) throws SQLException {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
connection = JdbcUtils_C3P0.getConnection();
//使用?占位符代替参数
String sql = "insert into users(`id`,`name`,`password`,`email`,`birthday`) values(?,?,?,?,?)";
preparedStatement = connection.prepareStatement(sql);//预编译sql,先写sql,然后不执行
//手动给参数赋值
preparedStatement.setInt(1, 8);
preparedStatement.setString(2, "c3p02");
preparedStatement.setString(3, "6666667");
preparedStatement.setString(4, "c3p0@sina.com");
preparedStatement.setDate(5, new java.sql.Date(new Date().getTime()));
int i = preparedStatement.executeUpdate();
if (i > 0) {
System.out.println("插入成功!");
}
} catch (Exception e) {
e.printStackTrace();
}finally {
JdbcUtils_C3P0.release(connection, preparedStatement, null);
}
}
}
4.总结
- 执行对象由Statement换为PrepareStatement有效防止了SQL注入,并且效率更高。
- 连接池的本质都是实现了一个接口DataSource。
- 注意资源放的位置。
- 关于依赖找不到的问题,需手动下载,网址已提供,下载好放入本地仓库刷新即可。