【Java】连接池与DBUtils的使用
目录
查询一条记录(使用ArrayHandler,使用BeanHandler,使用MapHandler)
查询多条数据封装到List集合中(使用ArrayListHandler,使用BeanListHandler,使用MapListHandler)
1.为什么要使用连接池
Connection对象在JDBC使用的时候就会去创建一个对象,使用结束以后就会将这个对象给销毁了(close).每次创建和销毁对象都是耗时操作.需要使用连接池对其进行优化.
程序初始化的时候,初始化多个连接,将多个连接放入到池(集合)中.每次获取的时候,都可以直接从连接池中进行获取.使用结束以后,将连接归还到池中.
-
程序一开始就创建一定数量的连接,放在一个容器(集合)中,这个容器称为连接池。
-
使用的时候直接从连接池中取一个已经创建好的连接对象, 使用完成之后 归还到池子
-
如果池子里面的连接使用完了, 还有程序需要使用连接, 先等待一段时间(eg: 3s), 如果在这段时间之内有连接归还, 就拿去使用; 如果还没有连接归还, 新创建一个, 但是新创建的这一个不会归还了(销毁)
-
集合选择LinkedList
-
增删比较快
-
LinkedList里面的removeFirst()和addLast()方法和连接池的原理吻合
-
2.自定义连接池-初级版本
-
创建连接池类
-
在连接池类中,定义一个LinkedList集合(表示连接池)
-
在连接池类的静态代码块中,创建固定数量的连接,并存储到LinkedList集合中
-
提供一个公共的非静态方法来获取连接对象(getAbc)
-
提供一个公共的非静态方法来归还连接对象(addBack)
-
提供一个公共的静态方法来获取连接池中连接的数量
package com.jcli.demo02_自定义连接池初级版;
import com.jcli.utils.JDBCUtils;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.LinkedList;
/**
* - 创建连接池类
*/
public class MyDataSource01 {
//- 在连接池类中,定义一个LinkedList集合(表示连接池)
private static LinkedList<Connection> pools = new LinkedList<>();
//- 在连接池类的静态代码块中,创建固定数量的连接,并存储到LinkedList集合中
static {
for (int i = 0; i < 6; i++) {
try {
//获得连接
Connection connection = JDBCUtils.getConnection();
//把连接添加到连接池
pools.add(connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//- 提供一个公共的非静态方法来获取连接对象(getAbc)
public Connection getAbc() {
Connection connection = pools.removeFirst();
return connection;
}
//- 提供一个公共的非静态方法来归还连接对象(addBack)
public void addBack(Connection connection) {
pools.addLast(connection);
}
//- 提供一个公共的静态方法来获取连接池中连接的数量
public static int size() {
return pools.size();
}
}
测试:
// 1.创建连接池对象 // 2.获得连接 // 3.预编译sql语句,得到预编译对象 // 4.设置参数 // 5.执行sql语句,处理结果 // 取数据 // 6.归还连接 // 7.释放资源
package com.jcli.demo02_自定义连接池初级版;
import com.jcli.utils.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Test {
public static void main(String[] args) throws SQLException {
// 1.创建连接池对象
MyDataSource01 dataSource01 = new MyDataSource01();
System.out.println("获得连接之前:"+MyDataSource01.size());
// 2.获得连接
Connection connection = dataSource01.getAbc();
System.out.println("获得连接之后:"+MyDataSource01.size());
// 3.预编译sql语句,得到预编译对象
String sql = "select * from user where id = ?";
PreparedStatement ps = connection.prepareStatement(sql);
// 4.设置参数
ps.setInt(1,1);
// 5.执行sql语句,处理结果
ResultSet resultSet = ps.executeQuery();
// 取数据
while (resultSet.next()){
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String nickname = resultSet.getString("name");
}
System.out.println("归还连接之前:"+MyDataSource01.size());
// 6.归还连接
dataSource01.addBack(connection);
System.out.println("归还连接之后:"+MyDataSource01.size());
// 7.释放资源
JDBCUtils.release(resultSet,ps,null);
}
}
3.自定义连接池-进阶版本
实现接口DataSource,重写获取方法getConnection
-
创建连接池类, 实现DataSource接口,重写方法
-
在连接池类中,定义一个LinkedList集合(表示连接池)
-
在连接池类的静态代码块中,创建固定数量的连接,并存储到LinkedList集合中
-
使用重写的方法getConnection,来获取连接对象
-
提供一个公共的非静态方法来归还连接对象(addBack)
-
提供一个公共的静态方法来获取连接池中连接的数量
package com.jcli.demo03_自定义连接池进阶版;
import com.jcli.utils.JDBCUtils;
import javax.sql.DataSource;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.logging.Logger;
/**
* - 创建连接池类
*/
public class MyDataSource02 implements DataSource {
//- 在连接池类中,定义一个LinkedList集合(表示连接池)
private static LinkedList<Connection> pools = new LinkedList<>();
//- 在连接池类的静态代码块中,创建固定数量的连接,并存储到LinkedList集合中
static {
for (int i = 0; i < 6; i++) {
try {
//获得连接
Connection connection = JDBCUtils.getConnection();
//把连接添加到连接池
pools.add(connection);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//- 提供一个公共的非静态方法来获取连接对象(getAbc)
/*public Connection getAbc() {
Connection connection = pools.removeFirst();
return connection;
}*/
//- 提供一个公共的非静态方法来归还连接对象(addBack)
public void addBack(Connection connection) {
pools.addLast(connection);
}
//- 提供一个公共的静态方法来获取连接池中连接的数量
public static int size() {
return pools.size();
}
//- 重写getConnection方法,获得链接
@Override
public Connection getConnection() throws SQLException {
Connection connection = pools.removeFirst();
return connection;
}
@Override
public Connection getConnection(String username, String password) throws SQLException {
return null;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
@Override
public PrintWriter getLogWriter() throws SQLException {
return null;
}
@Override
public void setLogWriter(PrintWriter out) throws SQLException {
}
@Override
public void setLoginTimeout(int seconds) throws SQLException {
}
@Override
public int getLoginTimeout() throws SQLException {
return 0;
}
@Override
public Logger getParentLogger() throws SQLFeatureNotSupportedException {
return null;
}
}
测试:
package com.jcli.demo02_自定义连接池初级版;
import com.jcli.utils.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Test {
public static void main(String[] args) throws SQLException {
// 1.创建连接池对象
MyDataSource01 dataSource01 = new MyDataSource01();
System.out.println("获得连接之前:"+MyDataSource01.size());
// 2.获得连接
Connection connection = dataSource01.getAbc();
System.out.println("获得连接之后:"+MyDataSource01.size());
// 3.预编译sql语句,得到预编译对象
String sql = "select * from user where id = ?";
PreparedStatement ps = connection.prepareStatement(sql);
// 4.设置参数
ps.setInt(1,1);
// 5.执行sql语句,处理结果
ResultSet resultSet = ps.executeQuery();
// 取数据
while (resultSet.next()){
int id = resultSet.getInt("id");
String username = resultSet.getString("username");
String password = resultSet.getString("password");
String nickname = resultSet.getString("name");
}
System.out.println("归还连接之前:"+MyDataSource01.size());
// 6.归还连接
dataSource01.addBack(connection);
System.out.println("归还连接之后:"+MyDataSource01.size());
// 7.释放资源
JDBCUtils.release(resultSet,ps,null);
}
}
4.装饰者模式
-
作用:改写已存在的类的某个方法或某些方法
-
条件:
-
装饰类和被装饰类要实现同一个接口
-
装饰类里面要拿到被装饰类的引用
-
对需要增强的方法进行增强
-
对不需要增强的方法就调用被装饰类中原有的方法
-
package com.jcli.demo04_装饰者模式;
public interface Star {
void sing();
void dance();
}
package com.jcli.demo04_装饰者模式;
// 被装饰类
public class CiVi implements Star {
@Override
public void sing() {
System.out.println("CiVi在唱小星星~~~");
}
@Override
public void dance() {
System.out.println("CiVi在跳绳~~~");
}
}
package com.jcli.demo04_装饰者模式;
// 装饰类
public class CiViWrapper implements Star {
Star star;
public CiViWrapper(Star star) {
this.star = star;
}
@Override
public void sing() {
System.out.println("CiVi在唱小星星~~~");
System.out.println("CiVi在唱十年~~~");
System.out.println("CiVi在唱绿光~~~");
}
@Override
public void dance() {
star.dance();
}
}
package com.jcli.demo04_装饰者模式;
public class Test {
public static void main(String[] args) {
CiVi ciVi = new CiVi();
CiViWrapper cvw = new CiViWrapper(ciVi);
cvw.sing();
cvw.dance();
}
}
5.自定义连接池-终极版本
-
创建增强的连接类,对close方法进行增强,其余方法依然调用原有的连接对象的方法
-
创建连接池类, 实现DataSource接口,重写方法
-
在连接池类中,定义一个LinkedList集合(表示连接池)
-
在连接池类的静态代码块中,创建固定数量的连接,并存储到LinkedList集合中
-
使用重写的方法getConnection,来获取连接对象----->增强的连接对象
-
提供一个公共的静态方法来获取连接池中连接的数量
-
与进阶版的区别:
-
连接池类中不需要提供归还连接的方法
-
getConnection获得连接的方法不再返回被增强的连接对象,而是返回增强的连接对象
-
实现
//装饰类
//获取被装饰的引用
//创建linkedList集合
//对需要增强的方法增强~~~归还连接
//不需要增强的直接调用~~~被装饰类
//创建连接池类
//- 重写getConnection方法,获得链接
// 返回增强的连接对象
//- 取消归还连接对象(addBack)方法
package com.jcli.demo05_自定义连接池终极版;
import java.sql.*;
import java.util.LinkedList;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
// 装饰类
public class MyConnection implements Connection {
//获取被装饰的引用
Connection connection;
//创建linkedList集合
LinkedList<Connection> pools;
public MyConnection(Connection connection, LinkedList<Connection> pools) {
this.connection = connection;
this.pools = pools;
}
@Override
public void close() throws SQLException {
// 对需要增强的方法进行增强----归还连接
pools.addLast(connection);
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
// 对不需要增强的方法就调用被装饰类中原有的方法
return connection.createStatement();
}
@Override
public PreparedStatement prepareStatement(String sql) throws SQLException {
// 对不需要增强的方法就调用被装饰类中原有的方法
return connection.prepareStatement(sql);
}
@Override
public Statement createStatement() throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql) throws SQLException {
return null;
}
@Override
public String nativeSQL(String sql) throws SQLException {
return null;
}
@Override
public void setAutoCommit(boolean autoCommit) throws SQLException {
}
@Override
public boolean getAutoCommit() throws SQLException {
return false;
}
@Override
public void commit() throws SQLException {
}
@Override
public void rollback() throws SQLException {
}
@Override
public boolean isClosed() throws SQLException {
return false;
}
@Override
public DatabaseMetaData getMetaData() throws SQLException {
return null;
}
@Override
public void setReadOnly(boolean readOnly) throws SQLException {
}
@Override
public boolean isReadOnly() throws SQLException {
return false;
}
@Override
public void setCatalog(String catalog) throws SQLException {
}
@Override
public String getCatalog() throws SQLException {
return null;
}
@Override
public void setTransactionIsolation(int level) throws SQLException {
}
@Override
public int getTransactionIsolation() throws SQLException {
return 0;
}
@Override
public SQLWarning getWarnings() throws SQLException {
return null;
}
@Override
public void clearWarnings() throws SQLException {
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
return null;
}
@Override
public Map<String, Class<?>> getTypeMap() throws SQLException {
return null;
}
@Override
public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
}
@Override
public void setHoldability(int holdability) throws SQLException {
}
@Override
public int getHoldability() throws SQLException {
return 0;
}
@Override
public Savepoint setSavepoint() throws SQLException {
return null;
}
@Override
public Savepoint setSavepoint(String name) throws SQLException {
return null;
}
@Override
public void rollback(Savepoint savepoint) throws SQLException {
}
@Override
public void releaseSavepoint(Savepoint savepoint) throws SQLException {
}
@Override
public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
return null;
}
@Override
public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
return null;
}
@Override
public Clob createClob() throws SQLException {
return null;
}
@Override
public Blob createBlob() throws SQLException {
return null;
}
@Override
public NClob createNClob() throws SQLException {
return null;
}
@Override
public SQLXML createSQLXML() throws SQLException {
return null;
}
@Override
public boolean isValid(int timeout) throws SQLException {
return false;
}
@Override
public void setClientInfo(String name, String value) throws SQLClientInfoException {
}
@Override
public void setClientInfo(Properties properties) throws SQLClientInfoException {
}
@Override
public String getClientInfo(String name) throws SQLException {
return null;
}
@Override
public Properties getClientInfo() throws SQLException {
return null;
}
@Override
public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
return null;
}
@Override
public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
return null;
}
@Override
public void setSchema(String schema) throws SQLException {
}
@Override
public String getSchema() throws SQLException {
return null;
}
@Override
public void abort(Executor executor) throws SQLException {
}
@Override
public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
}
@Override
public int getNetworkTimeout() throws SQLException {
return 0;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
}
@Override
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
}
}
6.C3P0连接池
1.通过硬编码来编写【了解】
-
拷贝c3p0的jar包到模块下
-
创建c3p0连接池对象
-
设置连接参数
-
获得连接对象
-
预编译sql语句,得到预编译对象
-
设置sql语句参数
-
执行sql语句,处理结果
-
释放资源
package com.jcli.demo06_C3P0连接池;
import com.jcli.utils.JDBCUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class Test01 {
public static void main(String[] args) throws Exception {
//- 拷贝c3p0的jar包到模块下
// - 创建c3p0连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// - 设置连接参数
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jcli_ee");
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setInitialPoolSize(5);
// - 获得连接对象
Connection connection = dataSource.getConnection();
// - 预编译sql语句,得到预编译对象
String sql = "select * from user where id = ?";
PreparedStatement ps = connection.prepareStatement(sql);
// - 设置sql语句参数
ps.setInt(1, 1);
// - 执行sql语句,处理结果
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getInt("id"));
System.out.println(resultSet.getString("username"));
System.out.println(resultSet.getString("password"));
System.out.println(resultSet.getString("name"));
}
// - 释放资源
JDBCUtils.release(resultSet, ps, connection);
}
}
2.通过配置文件来编写
- 拷贝c3p0的jar包到模块下
- 拷贝c3p0-config.xml配置文件拷贝到模块的src路径下
- **c3p0-config.xml配置文件的文件名不能修改,必须为c3p0-config.xml**
- **c3p0-config.xml配置文件的路径必须在src路径下**
- **c3p0-config.xml配置文件中property标签的name属性值不能修改**
- 创建c3p0连接池对象
- 获得连接对象
- 预编译sql语句,得到预编译对象
- 设置sql语句参数
- 执行sql语句,处理结果
- 释放资源
package com.jcli.demo06_C3P0连接池;
import com.jcli.utils.JDBCUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class Test02 {
public static void main(String[] args) throws SQLException {
//- 拷贝c3p0的jar包到模块下
// - 拷贝c3p0-config.xml配置文件拷贝到模块的src路径下
// - **c3p0-config.xml配置文件的文件名不能修改,必须为c3p0-config.xml**
//- **c3p0-config.xml配置文件的路径必须在src路径下**
//- **c3p0-config.xml配置文件中property标签的name属性值不能修改**
//- 创建c3p0连接池对象
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// - 获得连接对象
Connection connection = dataSource.getConnection();
// - 预编译sql语句,得到预编译对象
String sql = "select * from user where id = ?";
PreparedStatement ps = connection.prepareStatement(sql);
// - 设置sql语句参数
ps.setInt(1, 1);
// - 执行sql语句,处理结果
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getInt("id"));
System.out.println(resultSet.getString("username"));
System.out.println(resultSet.getString("password"));
System.out.println(resultSet.getString("name"));
}
// - 释放资源
JDBCUtils.release(resultSet, ps, connection);
}
}
3.使用c3p0改写工具类
整个程序只需要创建一个连接池对象,其余地方直接使用这个唯一的连接池对象获得连接即可
- 创建唯一的连接池对象---->private static final修饰
- 提供一个获取连接池对象的静态方法
- 提供一个获取连接的静态方法
- 提供一个释放资源的静态方法
package com.jcli.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class C3P0Utils {
// - 创建唯一的连接池对象---->private static final修饰
private static final ComboPooledDataSource DATA_SOURCE = new ComboPooledDataSource();
//- 提供一个获取连接池对象的静态方法
public static DataSource getDataSource() {
return DATA_SOURCE;
}
//- 提供一个获取连接的静态方法
public static Connection getConnection() throws SQLException {
return DATA_SOURCE.getConnection();
}
//- 提供一个释放资源的静态方法
public static void release(ResultSet resultSet, Statement statement, Connection connection) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
package com.jcli.demo06_C3P0连接池;
import com.jcli.utils.C3P0Utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class Test3 {
public static void main(String[] args) throws Exception{
//- 创建c3p0连接池对象
DataSource dataSource = C3P0Utils.getDataSource();
//- 获得连接对象
Connection connection = dataSource.getConnection();
//- 预编译sql语句,得到预编译对象
String sql = "select * from user where id = ?";
PreparedStatement ps = connection.prepareStatement(sql);
//- 设置sql语句参数
ps.setInt(1,1);
//- 执行sql语句,处理结果
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getInt("id"));
System.out.println(resultSet.getString("username"));
System.out.println(resultSet.getString("password"));
System.out.println(resultSet.getString("name"));
}
//- 释放资源
C3P0Utils.release(resultSet,ps,connection);
}
}
7.DRUID连接池
1.通过硬编码方式【了解】
- 导入druid的jar包到模块中
- 创建druid的连接池对象
- 设置连接参数
- 获得连接对象
- 预编译sql语句,得到预编译对象
- 设置sql语句参数
- 执行sql语句,处理结果
- 释放资源
package com.jcli.demo07_DRUID连接池;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.jcli.utils.JDBCUtils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
public class Test01 {
public static void main(String[] args) throws Exception {
//- 导入druid的jar包到模块中
//- 创建druid的连接池对象
DruidDataSource dataSource = new DruidDataSource();
// - 设置连接参数
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/jcli_ee");
dataSource.setUsername("root");
dataSource.setPassword("root");
// - 获得连接对象
DruidPooledConnection connection = dataSource.getConnection();
// - 预编译sql语句,得到预编译对象
String sql = "select * from user where id = ?";
PreparedStatement ps = connection.prepareStatement(sql);
// - 设置sql语句参数
ps.setInt(1, 1);
// - 执行sql语句,处理结果
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getInt("id"));
System.out.println(resultSet.getString("username"));
System.out.println(resultSet.getString("password"));
System.out.println(resultSet.getString("name"));
}
// - 释放资源
JDBCUtils.release(resultSet, ps, connection);
}
}
2.通过配置文件方式
- 拷贝druid的jar包到模块下
- 拷贝druid.properties配置文件拷贝到模块的src路径下
- druid.properties配置文件的文件名可以修改
- druid.properties配置文件的路径建议在src路径下
- druid.properties配置文件中的键名不能修改
- 创建druid连接池对象,传入Properties对象
- 获得连接对象
- 预编译sql语句,得到预编译对象
- 设置sql语句参数
- 执行sql语句,处理结果
- 释放资源
package com.jcli.demo07_DRUID连接池;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.alibaba.druid.pool.DruidPooledConnection;
import com.jcli.utils.JDBCUtils;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class Test02 {
public static void main(String[] args) throws Exception {
//- 拷贝druid的jar包到模块下
//- 拷贝druid.properties配置文件拷贝到模块的src路径下
// - druid.properties配置文件的文件名可以修改
// - druid.properties配置文件的路径建议在src路径下
// - druid.properties配置文件中的键名不能修改
// 创建properties对象,加载druid.properties配置文件
Properties pro = new Properties();
InputStream is = Test02.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//- 创建druid连接池对象,传入Properties对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);
// - 设置连接参数
//dataSource.setDriverClassName("com.mysql.jdbc.Driver");
//dataSource.setUrl("jdbc:mysql://localhost:3306/jcli_ee");
//dataSource.setUsername("root");
//dataSource.setPassword("root");
// - 获得连接对象
Connection connection = dataSource.getConnection();
// - 预编译sql语句,得到预编译对象
String sql = "select * from user where id = ?";
PreparedStatement ps = connection.prepareStatement(sql);
// - 设置sql语句参数
ps.setInt(1, 1);
// - 执行sql语句,处理结果
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getInt("id"));
System.out.println(resultSet.getString("username"));
System.out.println(resultSet.getString("password"));
System.out.println(resultSet.getString("name"));
}
// - 释放资源
JDBCUtils.release(resultSet, ps, connection);
}
}
3.Druid工具类的制作
- 创建连接池成员变量
- 在静态代码块中加载配置文件,创建druid连接池对象
- 提供一个获取连接池对象的静态方法
- 提供一个获取连接的静态方法
- 提供一个释放资源的静态方法
package com.jcli.utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.jcli.demo07_DRUID连接池.Test02;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DruidUtils {
// - 创建连接池成员变量
private static DataSource dataSource;
//- 在静态代码块中加载配置文件,创建druid连接池对象
static {
try {
Properties pro = new Properties();
InputStream is = Test02.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//- 创建druid连接池对象,传入Properties对象
dataSource = DruidDataSourceFactory.createDataSource(pro);
} catch (Exception e) {
}
}
//- 提供一个获取连接池对象的静态方法
public static DataSource getDataSource() {
return dataSource;
}
//- 提供一个获取连接的静态方法
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
//- 提供一个释放资源的静态方法
public static void release(ResultSet resultSet, Statement statement, Connection connection) {
if (resultSet != null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement != null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection != null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
package com.jcli.demo07_DRUID连接池;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.jcli.utils.DruidUtils;
import com.jcli.utils.JDBCUtils;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class Test03 {
public static void main(String[] args) throws Exception {
//获得连接池对象
DataSource dataSource = DruidUtils.getDataSource();
/*// 创建properties对象,加载druid.properties配置文件
Properties pro = new Properties();
InputStream is = Test03.class.getClassLoader().getResourceAsStream("druid.properties");
//pro.load(is);
//- 创建druid连接池对象,传入Properties对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);*/
// - 获得连接对象
Connection connection = dataSource.getConnection();
// - 预编译sql语句,得到预编译对象
String sql = "select * from user where id = ?";
PreparedStatement ps = connection.prepareStatement(sql);
// - 设置sql语句参数
ps.setInt(1, 1);
// - 执行sql语句,处理结果
ResultSet resultSet = ps.executeQuery();
while (resultSet.next()) {
System.out.println(resultSet.getInt("id"));
System.out.println(resultSet.getString("username"));
System.out.println(resultSet.getString("password"));
System.out.println(resultSet.getString("name"));
}
// - 释放资源
JDBCUtils.release(resultSet, ps, connection);
}
}
8.DBUtils完成增删改
- 导入DButils的jar包---->mysql驱动包,第三方数据库连接池的jar包,配置文件,工具类
- 创建QueryRunner对象,传入连接池对象
- 调用update方法执行sql语句
package com.jcli.demo08_DBUtils完成增删改;
import com.jcli.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;
import java.sql.SQLException;
public class TestDemo {
//- 导入DButils的jar包---->mysql驱动包,第三方数据库连接池的jar包,配置文件,工具类
//- 创建QueryRunner对象,传入连接池对象
//- 调用update方法执行sql语句
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
@Test
public void add() throws SQLException {
String sql = "insert into user values(null,?,?,?)";
int rows = queryRunner.update(sql, "tq", "123", "田七");
System.out.println("insert受影响的行数:" + rows);
}
@Test
public void update() throws SQLException {
String sql = "update user set password=? where name=?";
int rows = queryRunner.update(sql, "11123", "田七");
System.out.println("update受影响的行数:" + rows);
}
@Test
public void delete() throws SQLException {
String sql = "delete from user where id = ?";
int rows = queryRunner.update(sql, 10);
System.out.println("delete受影响的行数:" + rows);
}
}
9.DBUtils完成查询
查询一条记录(使用ArrayHandler,使用BeanHandler,使用MapHandler)
package com.jcli.demo09_DBUtils完成查询;
import com.jcli.bean.User;
import com.jcli.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayHandler;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.junit.Test;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Map;
//查询一条记录
public class Test01 {
//- 创建QueryRunner对象,传入连接池对象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
// 查询结果为一条记录的封装成数组
@Test
public void selectById1() throws SQLException {
String sql = "select * from user where id = ?";
Object[] arr = queryRunner.query(sql, new ArrayHandler(), 1);
System.out.println(Arrays.toString(arr));
}
// 查询结果记录为一条记录的封装成javabean对象
@Test
public void selectById2() throws SQLException {
String sql = "select * from user where id = ?";
User arr = queryRunner.query(sql, new BeanHandler<User>(User.class), 1);
System.out.println(arr);
}
// 查询结果为一条记录的封装成map集合
@Test
public void selectById3() throws SQLException {
String sql = "select * from user where id = ?";
Map<String, Object> map = queryRunner.query(sql, new MapHandler(), 1);
System.out.println(map);
}
}
查询多条数据封装到List集合中(使用ArrayListHandler,使用BeanListHandler,使用MapListHandler)
package com.jcli.demo09_DBUtils完成查询;
import com.jcli.bean.User;
import com.jcli.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.*;
import org.junit.Test;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
//查询多条记录
public class Test02 {
//- 创建QueryRunner对象,传入连接池对象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
// 查询结果为多条记录的封装成list集合,类型Object数组
@Test
public void selectByAll1() throws SQLException {
String sql = "select * from user ";
List<Object[]> list = queryRunner.query(sql, new ArrayListHandler());
for (Object[] arr : list) {
System.out.println(Arrays.toString(arr));
}
}
// 查询结果记录为多条记录的封装成list集合,类型javabean对象
@Test
public void selectByAll2() throws SQLException {
String sql = "select * from user ";
List<User> list = queryRunner.query(sql, new BeanListHandler<User>(User.class) );
for (User user : list) {
System.out.println(user);
}
}
// 查询结果为多条记录的封装成list集合,类型+map集合
@Test
public void selectByAll3() throws SQLException {
String sql = "select * from user ";
List<Map<String, Object>> list = queryRunner.query(sql, new MapListHandler());
for (Map<String, Object> map : list) {
System.out.println(map);
}
}
}
查询单个数据(使用ScalarHandler())
package com.jcli.demo09_DBUtils完成查询;
import com.jcli.bean.User;
import com.jcli.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ArrayListHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
//查询单个数据(使用ScalarHandler())
public class Test03 {
//- 创建QueryRunner对象,传入连接池对象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
@Test
public void selectByAll1() throws SQLException {
String sql = "select count(*) from user ";
Long count = (Long) queryRunner.query(sql, new ScalarHandler());
System.out.println(count);
}
}
查询单列多个值(使用ColumnListHandler)
package com.jcli.demo09_DBUtils完成查询;
import com.jcli.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.ColumnListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;
import java.sql.SQLException;
import java.util.List;
//查询单列多个值(使用ColumnListHandler)
public class Test04 {
//- 创建QueryRunner对象,传入连接池对象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
@Test
public void selectByAll1() throws SQLException {
String sql = "select name from user ";
List<Object> list = queryRunner.query(sql,new ColumnListHandler());
System.out.println(list);
}
}
10.元数据
参数元数据
package com.jcli.demo10_自定义DBUtils;
import com.jcli.utils.JDBCUtils;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
//参数元数据
public class Test01 {
public static void main(String[] args) throws SQLException {
Connection connection = JDBCUtils.getConnection();
String sql = "select * from user where username = ? and password = ?";
PreparedStatement ps = connection.prepareStatement(sql);
//- 获取参数的元数据对象
ParameterMetaData pmd = ps.getParameterMetaData();
//- 根据参数的元数据对象 获取 参数的元数据
System.out.println("获取参数计数:"+pmd.getParameterCount());
//Parameter metadata not available for the given statement
System.out.println("获取参数类名称"+pmd.getParameterClassName(1));
}
}
结果集元素数据
package com.jcli.demo10_自定义DBUtils;
import com.jcli.utils.JDBCUtils;
import java.sql.*;
// 结果集元素数据
public class Test02 {
public static void main(String[] args) throws SQLException {
Connection connection = JDBCUtils.getConnection();
String sql = "select * from user";
PreparedStatement ps = connection.prepareStatement(sql);
ResultSet resultSet = ps.executeQuery();
// 获得结果集元数据对象
ResultSetMetaData rmd = resultSet.getMetaData();
// 使用结果集元数据对象 获得 结果集的元数据(列的个数,列的名称,类型...)
int columnCount = rmd.getColumnCount();
System.out.println("结果集中列的个数:"+columnCount);
// 循环遍历获取列名,列的类型
for (int i = 1; i <= columnCount; i++) {
System.out.println("结果集中列的名称:"+rmd.getColumnName(i));
System.out.println("结果集中列的sql类型:"+rmd.getColumnTypeName(i));
System.out.println("结果集中列的java类型:"+rmd.getColumnClassName(i));
System.out.println("----------------");
}
}
}
11.自定义DBUtils增删改
- 创建MyQueryRunner类
- 定义一个DataSource成员变量
- 定义一个有参构造方法,空参构造方法
- 定义一个update(String sql,Object... args)完成增删改操作
package com.jcli.demo11_自定义DBUtils增删改;
import com.jcli.utils.JDBCUtils;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* - 创建MyQueryRunner类
*/
public class MyQueryRunner {
// * - 定义一个DataSource成员变量
private DataSource dataSource;
// * - 定义一个有参构造方法,空参构造方法
public MyQueryRunner() {
}
public MyQueryRunner(DataSource dataSource) {
this.dataSource = dataSource;
}
// * - 定义一个update(String sql,Object... args)完成增删改操作
public int update(String sql, Object... args) throws SQLException {
//- 1.注册驱动,获得连接
Connection connection = dataSource.getConnection();
// - 2.预编译sql语句,得到预编译对象
PreparedStatement ps = connection.prepareStatement(sql);
// - 3.设置参数
// 3.1 获得参数的元数据对象
ParameterMetaData pmd = ps.getParameterMetaData();
// 3.2 通过参数元数据对象获取参数的个数
int parameterCount = pmd.getParameterCount();
// 3.3 循环遍历赋值
for (int i = 0; i < parameterCount; i++) {
ps.setObject(i + 1, args[i]);
}
// - 4.执行sql语句,处理结果
int rows = ps.executeUpdate();
// - 5.释放资源
JDBCUtils.release(null, ps, connection);
return rows;
}
}
package com.jcli.demo11_自定义DBUtils增删改;
import com.jcli.utils.C3P0Utils;
import org.junit.Test;
import java.sql.SQLException;
public class TestDemo {
//- 导入DButils的jar包---->mysql驱动包,第三方数据库连接池的jar包,配置文件,工具类
//- 创建QueryRunner对象,传入连接池对象
MyQueryRunner queryRunner = new MyQueryRunner(C3P0Utils.getDataSource());
//- 调用update方法执行sql语句
@Test
public void add() throws SQLException {
String sql = "insert into user values(null,?,?,?)";
int rows = queryRunner.update(sql, "tq", "123", "田七");
System.out.println("insert受影响的行数:" + rows);
}
@Test
public void update() throws SQLException {
String sql = "update user set password=? where name=?";
int rows = queryRunner.update(sql, "11123", "田七");
System.out.println("update受影响的行数:" + rows);
}
@Test
public void delete() throws SQLException {
String sql = "delete from user where id = ?";
int rows = queryRunner.update(sql, 10);
System.out.println("delete受影响的行数:" + rows);
}
}
代码: