今日内容
- JDCB封装工具类
- DBUTils工具类(第三方)
- 连接池
- DAO封装
一.JDBC工具类封装
需求说明:
之前的CRUD(增删改查)代码中有一些重复的代码,我们可以将他们抽取出来封装成工具类。
封装的思想可以简化代码开发,提高代码的复用性,提高开发的效率。
封装的思路:
创建配置文件:jdbc.properties
mysql.driver= com.mysql.jdbc.Driver mysql.url = jdbc:mysql://localhost:3306/studb mysql.user = root mysql.password = root |
编写JDBC工具类:JDBCUtils
package com.ujiuye.utils;
import java.io.FileInputStream; import java.io.FileNotFoundException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Properties;
/*JDBC封装工具类*/ public class JDBCUtils { private static Connection conn = null; //定义静态代码块读取配置文本创建连接 static { //1.读取配置文件 Properties properties = new Properties(); FileInputStream fis = null; try { fis = new FileInputStream("day10/src/jdbc.properties"); properties.load(fis); } catch (Exception e) { e.printStackTrace(); } //2.读取属性值 String driver = properties.getProperty("mysql.driver"); String url = properties.getProperty("mysql.url"); String user = properties.getProperty("mysql.user"); String password = properties.getProperty("mysql.password"); System.out.println(driver+"-"+url+"-"+user+"-"+password); try { //3.加载驱动 Class.forName(driver); //4.创建连接 conn = DriverManager.getConnection(url, user, password); } catch (Exception e) { e.printStackTrace(); } }
//获取连接 public static Connection getConn(){ return conn; } //释放资源 public static void closeAll(ResultSet rs, PreparedStatement pstmt,Connection conn){ try { if(rs!=null){ rs.close(); } if (pstmt != null){ pstmt.close(); } if (conn != null) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } }
} |
测试工具类:
public static void main(String[] args) { String sql = "INSERT INTO admin(username,PASSWORD) VALUES(?,?)"; PreparedStatement pstmt = null; //调用工具类获取连接对象 Connection conn = JDBCUtils.getConn(); try { //创建执行SQL语句的对象 pstmt = conn.prepareStatement(sql); //给sql语句中?赋值 pstmt.setString(1,"xiaoliu"); pstmt.setString(2,"000"); //执行SQL语句 int row = pstmt.executeUpdate(); System.out.println(row); } catch (SQLException e) { e.printStackTrace(); }finally { JDBCUtils.closeAll(null,pstmt,conn); } } |
二.DBUTils工具类(优化JDBC编程)
commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。
Commons DbUtils是Apache组织提供的一个对JDBC进行简单封装的开源工具类库,使用它能够简化JDBC应用程序的开发,同时也不会影响程序的性能。尤其结合连接池使用效果更为理想。
DbUtils的核心是两个类一个接口:
1、DBUtils类:主要为关闭连接,装载JDBC驱动程序之类的常规工作提供方法,都是静态的方法。
2、QueryRunner类:为我们提供两个重要方法,调用方法之前需要先创建一个QueryRunner的对象。
为我们提供两个重要方法,调用方法之前需要先创建一个QueryRunner的对象。
QueryRunner qRunner=new QueryRunner();
QueryRunner qRunner=new QueryRunner(new ComboPooledDataSource());
创建对象时需要传入一个连接池的数据源,这里结合c3p0连接池来完成。
- qRunner.update(Connection conn,String sql, Object... params)
- qRunner.update(String sql, Object... params)
update()方法等价于executeUpdate(),支持DML操作
3)qRunner.query(Connection conn,String sql, ResultSetHandler rsh,Object... params)
4)qRunner.query(String sql, ResultSetHandler rsh,Object... params)
query()方法等价于executeQuery(),支持DQL操作
3、ResultSetHandler接口:用于处理ResultSet结果集,将结果集的的数据转换成不同形式。该接口的实现类有很多:
ArrayHandler | 将结果集中的第一条记录封装到一个Object[]数组中,数组中的每一个元素就是这条记录中的每一个字段的值。 |
ArrayListHandler | 将结果集中的每一条记录都封装到一个Object[]数组中,将这些数组在封装到List集合中。 |
BeanHandler | 将结果集中第一条记录封装到一个指定的javaBean中。 |
BeanListHandler | 将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中。 |
ColumnListHandler | 将结果集中指定的列的字段值,封装到一个List集合中。 |
ScalarHandler | 它是用于单列数据查询。例如:select count(*) from users 操作。 |
MapHandler | 将结果集中第一条记录封装到Map集合中,Key代表列名, Value代表该列数据。 |
MapListHandler | 将结果集中每一条记录封装到Map集合中,Key代表列名, Value代表该列数据,Map集合再存储到List集合 |
javabean封装规则 :
- public修饰类
- 成员属性私有private
- 属性一定要封装get/set方法
- 必须要有无参构造
package com.ujiuye.bean;
public class Admin { public Admin() { } public Admin(int id, String username, String password) { this.id = id; this.username = username; this.password = password; } //属性:属性名一定要与数据表中列名保持一致 private int id; private String username; private String password; //get/set
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
@Override public String toString() { return "Admin{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + '}'; } } |
使用步骤:
- 下载jar包导入项目中 lib/commons-dbutils-1.7.jar
- 编写代码
package com.ujiuye.dbutils;
import com.ujiuye.bean.Admin; import com.ujiuye.utils.JDBCUtils; import org.apache.commons.dbutils.DbUtils; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanHandler; import org.apache.commons.dbutils.handlers.BeanListHandler; import org.apache.commons.dbutils.handlers.ScalarHandler; import org.junit.Test;
import java.sql.Connection; import java.sql.SQLException; import java.util.List;
public class TestDBUTils { @Test public void insert_test(){ String sql = "INSERT INTO admin(username,PASSWORD) VALUES(?,?)"; //使用自己封装的工具类获取连接对象 Connection conn = JDBCUtils.getConn(); //创建QueryRunner QueryRunner runner = new QueryRunner(); try { //调用update(conn,sql,...params)执行添加方法,返回值为影响行数 int row = runner.update(conn, sql, "lisi", "123"); System.out.println(row); } catch (SQLException e) { e.printStackTrace(); }finally { try { //关闭连接方法 DbUtils.close(conn); } catch (SQLException e) { e.printStackTrace(); } } }
@Test public void select_one(){ String sql = "SELECT * FROM admin WHERE id = ?"; Connection conn = JDBCUtils.getConn(); QueryRunner runner = new QueryRunner(); //调用方法执行查询操作 try { Admin admin = runner.query(conn, sql, new BeanHandler<Admin>(Admin.class), 1); System.out.println(admin); } catch (SQLException e) { e.printStackTrace(); }finally { try { DbUtils.close(conn); } catch (SQLException e) { e.printStackTrace(); } } }
@Test public void select_multi(){ String sql = "SELECT * FROM admin"; Connection conn = JDBCUtils.getConn(); QueryRunner runner = new QueryRunner(); //调用方法执行查询操作 try { List<Admin> list = runner.query(conn, sql, new BeanListHandler<Admin>(Admin.class)); for (Admin admin : list) { System.out.println(admin); } } catch (SQLException e) { e.printStackTrace(); }finally { try { DbUtils.close(conn); } catch (SQLException e) { e.printStackTrace(); } } } @Test public void scale(){ String sql = "SELECT count(*) FROM admin"; Connection conn = JDBCUtils.getConn(); QueryRunner runner = new QueryRunner(); //调用方法执行查询操作 try { Object obj = runner.query(conn, sql, new ScalarHandler<>()); System.out.println(obj); } catch (SQLException e) { e.printStackTrace(); }finally { try { DbUtils.close(conn); } catch (SQLException e) { e.printStackTrace(); } } } } |
|
|
三.数据库连接池(优化数据库连接性能)
(一)连接池简介
为什么使用连接池?
数据库连接是一种关键的有限的昂贵的资源,传统数据库连接每发出一个请求都要创建一个连接对象,使用完直接关闭不能重复利用;
传统连接的缺点:
1.关闭资源需要手动完成,一旦忘记会造成内存溢出;
2.请求过于频繁的时候,创建连接极其消耗内存;
3.而且一旦高并发访问数据库,有可能会造成系统崩溃。

连接池原理
数据库连接池负责分配、管理和释放数据库连接,它的核心思想就是连接复用,通过建立一个数据库连接池,这个池中有若干个连接对象,当用户想要连接数据库,就要先从连接池中获取连接对象,然后操作数据库。一旦连接池中的连接对象被用完了,判断连接对象的个数是否已达上限,如果没有可以再创建新的连接对象,如果已达上限,用户必须处于等待状态,等待其他用户释放连接对象,直到连接池中有被释放的连接对象了,这时候等待的用户才能获取连接对象,从而操作数据库。这样就可以使连接池中的连接得到高效、安全的复用,避免了数据库连接频繁创建、关闭的开销。这项技术明显提高对数据库操作的性能。
连接池的优势
(1)程序启动时提前创建好连接,不用用户请求时创建,给服务器减轻压力;
(2)连接关闭的时候不会直接销毁connection,这样能够重复利用;
(3)如果超过设定的连接数量但是还没有达到最大值,那么可以再创建;
(4)如果空闲了,会默认销毁(释放)一些连接,让系统性能达到最优;
常用的开源连接池
1. DBCP
是Apache提供的数据库连接池,速度相对c3p0较快,但因自身存在BUG,Hibernate3已不再提供支持
2. C3P0
是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以。
3.Druid
是阿里提供的数据库连接池,据说是集DBCP 、C3P0 优点于一身的数据库连接池,但是速度不知道。
(二)c3p0连接池
- 下载jar包导入项目中

- 编写属性配置文件:c3p0.properties
注意事项:
- 属性配置文件的名称必须叫c3p0.properties,不能改文件名
- 该属性配置文件必须放在src路径目录下
- 属性配置文件中的属性名必须与上表中指定的名称相同,不能随意修改,而且必须加c3p0前缀。

选配:(了解)
c3p0.maxPoolSize = 100 最大连接数 默认15
c3p0.minPoolSize = 10 是小连接数 默认3
c3p0.initialPoolSize = 10 初始化连接数 在最大和最小之间
c3p0.maxIdleTime = 30 最大空闲时间,毫秒为单位
- 创建一个C3P0的工具类,获取数据源并返回连接对象。
package com.ujiuye.c3p0;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource; import java.sql.Connection; import java.sql.SQLException;
/*c3p0连接池工具类*/ public class C3p0Utils { //获取连接的方法 DataSource public static Connection getConn() throws SQLException { //创建数据源对象 DataSource ds = new ComboPooledDataSource(); //数据源对象调用getConnection() Connection connection = ds.getConnection(); return connection; } } |
- 测试查看 操作
package com.ujiuye.c3p0;
import com.mchange.v2.c3p0.ComboPooledDataSource; import com.ujiuye.bean.Admin; import org.apache.commons.dbutils.QueryRunner; import org.apache.commons.dbutils.handlers.BeanListHandler;
import java.sql.SQLException; import java.util.List;
public class TestC3p0Utils { public static void main(String[] args) { String sql = "select * from admin"; //创建QueryRunner使用c3p0连接池 QueryRunner runner = new QueryRunner(new ComboPooledDataSource()); //QueryRunner runner1 = new QueryRunner(); try { List<Admin> list = runner.query(sql, new BeanListHandler<Admin>(Admin.class)); for (Admin admin : list) { System.out.println(admin); } } catch (SQLException e) { e.printStackTrace(); } } } |
(三)Druid连接池
- 下载jar包
lib/druid-1.1.0.jar
- 编写druid.properties放在src目录下

- 创建工具类DruidUtils
package com.ujiuye.druid;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties;
public class DruidUtils { private static DataSource ds = null; //获取数据源 static { Properties properties = new Properties(); try { //InputStream is = new FileInputStream("D:\\savecode\\ideaPro\\changsha0308\\day10\\src\\druid.properties"); InputStream is = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties"); //调用load方法加载文件 properties.load(is); //druid连接池中提供了createDataSource()方法获取数据源 ds = DruidDataSourceFactory.createDataSource(properties); } catch (Exception e) { e.printStackTrace(); } }
//获取数据源对象 public static DataSource getDataSource(){ return ds; }
//获取连接 public static Connection getConn(){ try { return ds.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return null; }
} |
- 测试
package com.ujiuye.druid;
import org.apache.commons.dbutils.QueryRunner; import org.junit.Test;
import java.sql.Connection; import java.sql.SQLException;
public class TestDruidUtils { @Test public void test01() { String sql = "delete from admin where id = ?"; Connection conn = DruidUtils.getConn(); QueryRunner runner = new QueryRunner(); try { int row = runner.update(conn, sql, 24); System.out.println(row); } catch (SQLException e) { e.printStackTrace(); } }
@Test public void test02() { String sql = "delete from admin where id = ?"; QueryRunner runner = new QueryRunner(DruidUtils.getDataSource()); try { int row = runner.update(sql, 22); System.out.println(row); } catch (SQLException e) { e.printStackTrace(); } } } |
四.DAO
Data Access Object访问数据信息的类和接口,包括了对数据的CRUD(Create、Retrival、Update、Delete),而不包含任何业务相关的信息
三层:
表示层
业务逻辑层(最难)
数据访问层
为了实现功能的模块化,更有利于代码的维护和升级。
package com.ujiuye.dao;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import java.sql.SQLException;
import java.util.List;
public class BaseDao<T> {
QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
/*增删改*/
public int update(String sql,Object...params){
int row = 0;
try {
row = runner.update(sql, params);
} catch (SQLException e) {
e.printStackTrace();
}
return row;
}
/*查询集合*/
public List<T> queryMulti(String sql,Class<T> clazz,Object...params){
try {
return runner.query(sql, new BeanListHandler<T>(clazz), params);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/*查询单个值*/
public T querySingle(String sql,Class<T> clazz,Object...params){
try {
return runner.query(sql,new BeanHandler<T>(clazz),params);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/*查询聚合函数,单行单列*/
public Object scale(String sql,Object...params){
try {
return runner.query(sql,new ScalarHandler(),params);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
} |
package com.ujiuye.dao;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.ujiuye.entity.Admin;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.Test;
import java.sql.SQLException;
import java.util.List;
public class AdminDao extends BaseDao<Admin> {
@Test
public void insert_test(){
String sql = "INSERT INTO admin(username,PASSWORD)VALUES(?,?)";
int row = update(sql, "小刘", "333");
System.out.println(row);
}
@Test
public void select_multi(){
String sql = "select * from admin";
List<Admin> list = queryMulti(sql, Admin.class);
for (Admin admin : list) {
System.out.println(admin);
}
}
@Test
public void select_single(){
String sql = "select * from admin where id = ?";
Admin admin = querySingle(sql, Admin.class,1);
System.out.println(admin);
}
@Test
public void select_one(){
String sql = "select count(*) from admin";
Object count = scale(sql);
System.out.println(count);
}
} |