本篇就是聊一个工具类库:
commons-dbutils.jar
.这个是Apache组织提供的开源的JDBC工作类库,其对JDBC 进行了简单的封装,其实在前面聊的时自己通过反射创建的一个简单的公用的工具类也是对JDBC的一个简单的封装,不过这个是人家提供的功能更强调,自然也会简化Jdbc的编码工作量。
其中最重用的有两个记住接口和类:
- 类 :org.apache.commons.dbutils.QueryRunner;
- 接口 :org.apache.commons.dbutils.ResultSetHandler;
因为这个工具库中最常用的一些方法都是通过这个接口实现,或者这个接口的子接口。
对这个说实话,不好解释,只能通过代码进行简单的演示。
而在演示中说实话也不能将所有的方法都演示,只能说简单的列出常用几个方法,如果需要更多那就可能需要看官方文档了。
准备
连接池工具类
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class jdbc_utils {
// 连接池一般会在运行的时候就启动 所以没必要每次都调用
static DataSource dataSource=null;
static {
Properties properties= new Properties();
try {
properties.load(test_druid.class.getClassLoader().getResourceAsStream("druid.properties"));
// 这个和C3P0有点区别,C3P0可以自动根据名字导入而这个需要的手动写一下
dataSource= DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
// 得到连接
public static Connection getCon() {
Connection con=null;
try {
con= dataSource.getConnection();
return con;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return con;
}
//释放资源 毕竟连接就算不用也要放回池子里面
public static void ColseStaCon(Statement stm, ResultSet rst,Connection con){
try {
if(rst!=null){
rst.close();
}
} catch ( SQLException throwables) {
throwables.printStackTrace();
}finally {
if (stm!=null){
try {
stm.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
if(con!=null){
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
}
}
配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?rewriteBatchedStatments=true
username=root
password=root
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大超时时间
maxWait=3000
创建一个bean类:
public class UserBean {
int uid;
String uname;
String uaddres;
public UserBean() {
}
public UserBean(int uid, String uname, String uaddres) {
this.uid = uid;
this.uname = uname;
this.uaddres = uaddres;
}
public int getUid() {
return uid;
}
public String getUname() {
return uname;
}
public String getUaddres() {
return uaddres;
}
public void setUid(int uid) {
this.uid = uid;
}
public void setUname(String uname) {
this.uname = uname;
}
public void setUaddres(String uaddres) {
this.uaddres = uaddres;
}
@Override
public String toString() {
return "UserBean{" +
"uid=" + uid +
", uname='" + uname + '\'' +
", uaddres='" + uaddres + '\'' +
'}';
}
}
插入一行的方法
public void insert_one() {
Connection con=null;
try {
con=jdbc_utils.getCon();
// 首先声明一个 queryrunnder类
QueryRunner queryRunner=new QueryRunner();
String sql="INSERT INTO test.UserBean (uid, uname, uaddres ) VALUES (?,?,?)";
// 运行一个插入
queryRunner.execute(con,sql,"001","张三","北京");
// 还可以调用另一个方法,返回一个操作的行数,这个方法支持 更新删除和插入
// int countrow=queryRunner.update(con,sql,"001","张三","北京");
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
jdbc_utils.ColseStaCon(null,null,con);
}
结构:
插入一些数据
public static void insert_some() {
Connection con=null;
try {
con=jdbc_utils.getCon();
// 首先声明一个 queryrunnder类
QueryRunner queryRunner=new QueryRunner();
String sql="INSERT INTO test.UserBean (uid, uname, uaddres ) VALUES (?,?,?)";
String[][] arruser={
{"003","张4","北京"},
{"004","张5","北京"},
{"005","张6","北京"},
};
int[] countrows=queryRunner.batch(con,sql,arruser);
System.out.println(Arrays.toString(countrows));
} catch ( Exception throwables) {
throwables.printStackTrace();
}finally {
jdbc_utils.ColseStaCon(null,null,con);
}
}
查询返回一条数据
public static void getOne(){
Connection con=null;
try {
con=jdbc_utils.getCon();
QueryRunner queryRunner=new QueryRunner();
String sql="SELECT uid, uname, uaddres FROM test.userbean WHERE uid=? ";
BeanHandler<UserBean> beanHandler= new BeanHandler<UserBean>(UserBean.class);
UserBean userBean= queryRunner.query(con, sql, beanHandler, "001");
System.out.println(userBean);
} catch (Exception e) {
e.printStackTrace();
}finally {
jdbc_utils.ColseStaCon(null, null, con);
}
}
查询多条数据
public static void getSome(){
Connection con=null;
try {
con=jdbc_utils.getCon();
QueryRunner queryRunner=new QueryRunner();
String sql="SELECT uid, uname, uaddres FROM test.userbean where uid < ?";
MapListHandler mapListHandler=new MapListHandler();
List<Map<String, Object>> list= queryRunner.query(con, sql, mapListHandler,"008" );
list.forEach(System.out::println);
} catch (Exception e) {
e.printStackTrace();
}finally {
jdbc_utils.ColseStaCon(null, null, con);
}
}
特殊的聚合函数
public static void getTe(){
Connection con=null;
try {
con=jdbc_utils.getCon();
QueryRunner queryRunner=new QueryRunner();
String sql="SELECT max(uid) FROM test.userbean ";
ScalarHandler scalarHandler=new ScalarHandler();
Object object=queryRunner.query(con,sql,scalarHandler);
System.out.println(object);
} catch (Exception e) {
e.printStackTrace();
}finally {
jdbc_utils.ColseStaCon(null, null, con);
}
}
简单理解下ResultSetHandler(实现这个接口)
先看代码
public static void getTEST(){
Connection con=null;
try {
con=jdbc_utils.getCon();
QueryRunner queryRunner=new QueryRunner();
String sql="SELECT uid, uname, uaddres FROM test.userbean WHERE uid=? ";
ResultSetHandler<UserBean> testresult= new ResultSetHandler<UserBean>() {
@Override
public UserBean handle(ResultSet resultSet) throws SQLException {
return new UserBean(100,"李四","好压");
}
};
UserBean userBean= queryRunner.query(con, sql, testresult, "001");
System.out.println(userBean);
} catch (Exception e) {
e.printStackTrace();
}finally {
jdbc_utils.ColseStaCon(null, null, con);
}
}
可以看出ResultSetHandler是一个对对象包装的容器,所以无论BeanHandler,还是MapListHandler都是对接口方法的实现的一种体现。
关闭的优化
上面写的关闭手动关闭了三个,其实还有一种方式
// 这种关闭需要排除异常
try {
DbUtils.close(con);
DbUtils.close(rst);
DbUtils.close(prst);
} catch (Exception e) {
e.printStackTrace();
}
为什么不用判断是否为空
还可以更加简单
// 这种就不需要try了 因为工具类库已经解决异常了
DbUtils.closeQuietly(con);
DbUtils.closeQuietly(rst);
DbUtils.closeQuietly(prst);
为什么不需要