1 DBUtils工具类
1.1 如果我们使用jdbc进行开发,我们会发现代码重复度很高。
为了简化jdbc开发,所以apache commons 组件中给我们提供了一个成员DBUtils。
DBUtils 就是简化jdbc开发的工具包。
使用的时候需要在项目中导入jar包。
commons-dbutils-版本.jar
DBUtils封装了对jdbc的操作,简化了jdbc操作。
1.2 DBUtils中有三个核心对象
QueryRunner:提供了对sql语句操作的API。
ResultSetHandler接口:定义了执行完select语句后,如何封装结果集。
DbUtils:工具类,定义了关闭资源和与事务相关的方法。
注意:DBUtils仅仅只是封装了jdbc的操作。不仅需要导入DBUtils的jar包,一定不能忘了要导入 jdbc的jar包。
1.3 QueryRunner 核心类
构造方法
QueryRunner()
QueryRunner(DataSource ds)
成员方法
用于执行insert,update,delete语句
int update(Connection conn, String sql, Object… params)
int update(String sql, Object… params)
用于执行select语句
T query(Connection conn, String sql, ResultSetHandler rsh, Object… params)
T query(String sql, ResultSetHandler rsh, Object… params)
练习:使用QueryRunner完成增删改操作
package com.mysql.dbUtils.demo;
/*
- 使用DBUtils工具类完成增删改操作
- int update(Connection conn, String sql, Object… params)
- */
import com.mysql.dbUtils.jdbcutils.JdbcUtil;
import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test;
import java.sql.SQLException;
public class Demo1 {
@Test
public void insert() throws SQLException {
QueryRunner qr = new QueryRunner();
Object[] params = {50,“帅哥部”,“邮电大学”};
int i = qr.update(JdbcUtil.getConnection(), “insert into dept values (?,?,?)”, params);
System.out.println(i);
}
@Test
public void update() throws SQLException {
QueryRunner qr = new QueryRunner();
Object[] params = {"运营部","邮电",50};
int i = qr.update(JdbcUtil.getConnection(), "update dept set dname=?,address=? where deptid=?", params);
System.out.println(i);
}
@Test
public void delete() throws SQLException {
QueryRunner qr = new QueryRunner();
int i = qr.update(JdbcUtil.getConnection(), "delete from dept where deptid=?", 50);
System.out.println(i);
}
}
package com.mysql.dbUtils.jdbcutils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class JdbcUtil {
private JdbcUtil(){}
private static Properties info = new Properties();
private static Connection conn;
static{
InputStream is = JdbcUtil.class.getClassLoader().getResourceAsStream(“db.properties”);
try {
info.load(is);
} catch (IOException e) {
e.printStackTrace();
}
}
static{
try {
Class.forName(info.getProperty("driver"));
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
try {
conn = DriverManager.getConnection(info.getProperty("url"),info.getProperty("user"),info.getProperty("password"));
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
}
配置信息内容
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useSSL=false
user=root
password=123456
1.4 QueryRunner实现查询
T query(Connection conn, String sql, ResultSetHandler rsh, Object… params)
ResultSetHandler接口:结果集的处理类
实现类:
ArrayHandler:把结果集中第一条数据封装到一个Object数组中。
数组中的每一个元素就是这条记录中的每一个字段值。
ArrayListHandler:把结果集中每一条记录封装到一个Object数组中,
把数组在封装到List集合中。
BeanHandler:把结果集中的第一个数据封装到一个指定的javaBean中。
BeanListHandler:把结果集中的每一条数据封装到一个指定的javaBean中。
把每一个javaBean封装到集合中。
ColumnListHandler:把结果集中指定列的字段值封装到List集合中。
MapHandler:把结果集中的第一条数据封装到map集合中,key是列名,value是数据
MapListHandler:把结果集中的每一行封装到一个map集合中。
把map集合存储到List中。
ScalarHandler:用来获取单个数据。比如select count(*) from dept;
javaBean:就是一个java类,在开发中用于封装数据。
实现Serializable接口,这个可以省略,不影响代码
私有字段
无参构造
get和set方法
package com.mysql.dbUtils.demo;
import com.mysql.dbUtils.domain.Dept;
import com.mysql.dbUtils.jdbcutils.JdbcUtil;
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;
import java.util.Set;
/*
- 使用DBUtils工具类完成查询操作
- /
public class Demo2 {
@Test
//ArrayHandler
public void test1() throws SQLException {
QueryRunner qr = new QueryRunner();
Object[] obj = qr.query(JdbcUtil.getConnection(), “select * from dept”, new ArrayHandler());
System.out.println(Arrays.toString(obj));
}
@Test
//ArrayListHandler
public void test2() throws SQLException {
QueryRunner qr = new QueryRunner();
List<Object[]> list = qr.query(JdbcUtil.getConnection(), “select * from dept”, new ArrayListHandler());
for (Object[] objects : list) {
System.out.println(Arrays.toString(objects));
}
}
@Test
//BeanHandler
public void test3() throws SQLException {
QueryRunner qr = new QueryRunner();
Dept d = qr.query(JdbcUtil.getConnection(),“select * from dept”,new BeanHandler(Dept.class));
System.out.println(d);
}
@Test
//BeanListHandler
public void test4() throws SQLException {
QueryRunner qr = new QueryRunner();
List list = qr.query(JdbcUtil.getConnection(),“select * from dept”, new BeanListHandler(Dept.class));
for (Dept dept : list) {
System.out.println(dept);
}
}
@Test
//ColumnListHandler
public void test5() throws SQLException {
QueryRunner qr = new QueryRunner();
Object o = qr.query(JdbcUtil.getConnection(), “select * from dept”, new ColumnListHandler(2));
System.out.println(o);
}
@Test
//ScalarHandler 用来获取单个数据。比如select count() from dept;
public void test6() throws SQLException {
QueryRunner qr = new QueryRunner();
Object o = qr.query(JdbcUtil.getConnection(), “select count(*) from dept”, new ScalarHandler<>());
System.out.println(o);
}
@Test
//MapHandler
public void test7() throws SQLException {
QueryRunner qr = new QueryRunner();
Map<String, Object> map = qr.query(JdbcUtil.getConnection(), “select * from dept”, new MapHandler());
/Set keys = map.keySet();
for (String key:keys){
Object o = map.get(key);
System.out.println(key+"—"+o);
}/
Set<Map.Entry<String, Object>> entries = map.entrySet();
for (Map.Entry<String, Object> entry : entries) {
System.out.println(entry.getKey()+"—"+entry.getValue());
}
}
@Test
//MapListHandler
public void test8() throws SQLException {
QueryRunner qr = new QueryRunner();
List<Map<String, Object>> list = qr.query(JdbcUtil.getConnection(), “select * from dept”, new MapListHandler());
for (Map<String, Object> map : list) {
System.out.println(map);
}
}
}
2 连接池
开发中 不断的获取链接,然后释放资源 是非常消耗系统资源的。为了解决这类问题,我们开发的时候会使用链接池技术,就可以共享链接,这样的话我们就不用每次都创建链接,释放资源了。这些操作都交给连接池。
2.1 概述
用连接池来管理connection,可以重复使用connection。而且有了池后我们就不用自己创建connection了。而是通过池来获取connection对象。
当我们使用完成conn后,调用conn的close方法不会真正的关闭conn对象。
而是把conn对象归还给了池。池就可以再次利用这个conn对象了。
2.2 作用
数据库连接池负责分配,管理和释放数据库的链接。它允许程序重复使用一个现有的链接
而不是重新创建。
2.3 编写连接池需要实现javax.sql.DataSource 接口。
接口中有2个重载的getConnection方法
现在有很多厂商(web服务器,weblogic,tomcat。。。)都提供了DataSrouce的实现—连接池的实现。
还有很多开源组织也提供了数据源的独立实现:
dbcp
c3p0
druid
实际应用的时候不需要编写链接数据库的代码,直接从数据源中获取数据库的链接。
程序员编程的时候也应尽量使用这些数据源的实现,可以提高程序访问数据库的性能。
java为数据库连接池提供了公共的接口javax.sql.DataSource。
各个厂商根据这个规范做了具体的实现。方便我们切换不同的连接池。