一、DbUtils简介

DbUtils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用DbUtils能极大简化JDBC编码的工作量,同时也不会影响程序的性能。因此DbUtils成为很多不喜欢Hibernate的公司的首选。

二、使用DbUtils

2.1、DbUtils包下载地址

http://commons.apache.org/proper/commons-dbutils/download_dbutils.cgi

2.2、基于Maven

DbUtils依赖:

 <dependency><groupId>commons-dbutils</groupId><artifactId>commons-dbutils</artifactId><version>1.7</version>
</dependency>

三、DbUtils相关API

3.1、QueryRunner类 —— 组件的核心工具类:定义了所有与数据库操作的方法

  • int execute(Connection conn, String sql, Object... params) —— 执行DDL语句、存储过程调用语句等
  • <T> List<T> execute(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) —— 执行DDL语句、存储过程调用语句等
  • int update(Connection conn, String sql, Object... params) —— 执行DML语句,有占位符参数
  • int update(Connection conn, String sql, Object params) —— 执行DML语句,只有一个占位符参数
  • int update(Connection conn, String sql) —— 执行DML语句,没有占位符参数
  • <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params) —— 执行DQL语句,有占位符参数
  • <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh) —— 执行DQL语句,没有占位符参数

3.2、ResultSetHandler<T>接口的实现类

  • BeanHandler(Class<? extends T> type) —— 查询返回单个JavaBean对象
  • BeanListHandler(Class<? extends T> type) —— 查询返回包含多个JavaBean对象的List集合
  • ArrayHandler() —— 将结果集的第一行封装为Object数组
  • ArrayListHandler() —— 将结果集的每一行封装为Object数组,将这些Object数组添加到List集合中返回
  • ScalarHandler(int columnIndex) | ScalarHandler(String columnName) —— 返回结果集中第一行某一列的值

四、DbUtils示例

4.1、DDL语句

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();
// 2. 准备SQL语句(建表语句)
String sql = "CREATE TABLE Student(" + "sno CHAR(9) PRIMARY KEY, " + "sname CHAR(20), " + "ssex CHAR(2), " + "sage SMALLINT, " + "sdept CHAR(20)" + ");";
// 3. 实例化QueryRunner,并执行DDL语句
QueryRunner qr = new QueryRunner();
qr.execute(conn, sql);// 4. 关闭资源
conn.close();

4.2、DML语句

1)插入语句

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(插入记录)
String sql = "INSERT INTO Student VALUES(?, ?, ?, ?, ?);";// 3. 实例化QueryRunner,并执行DML语句
QueryRunner qr = new QueryRunner();
qr.update(conn, sql, "201215130", "张三", "男", 20, "IS");// 4. 关闭资源
conn.close();

2)更新语句

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(更新记录)
String sql = "UPDATE Student SET sname = ? WHERE sno = ?;";// 3. 实例化QueryRunner,并执行DML语句
QueryRunner qr = new QueryRunner();
qr.update(conn, sql, "李四", "201215130");// 4. 关闭资源
conn.close();

3)删除语句

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(删除记录)
String sql = "DELETE FROM Student WHERE sno = ?";// 3. 实例化QueryRunner,并执行DML语句
QueryRunner qr = new QueryRunner();
qr.update(conn, sql, "201215130");// 4. 关闭资源
conn.close();

4.3、DQL语句

1)查询一条记录

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(查询一条记录)
String sql = "SELECT * FROM Student WHERE sno = ?;";// 3. 实例化一个ResultSetHandler接口的实现类(将查询结果封装为一个Student对象)
ResultSetHandler<Student> rsh = new ResultSetHandler<Student>() {@Overridepublic Student handle(ResultSet rs) throws SQLException {while(rs.next()) {Student student = new Student();student.setSno(rs.getString("sno"));student.setSname(rs.getString("sname"));student.setSsex(rs.getString("ssex"));student.setSage(rs.getInt("sage"));student.setSdept(rs.getString("sdept"));return student;}return null;}
};// 4. 实例化QueryRunner,并执行DQL语句
QueryRunner qr = new QueryRunner();
Student  student = qr.query(conn, sql, rsh, "201215128");// 5. 关闭资源
conn.close();

DbUtils已经帮我们封装了一个类似功能的ResultSetHandler接口的实现类BeanHandler,所以上面的示例也可以这样实现:

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(查询一条记录)
String sql = "SELECT * FROM Student WHERE sno = ?;";// 3. 实例化QueryRunner,并执行DQL语句
QueryRunner qr = new QueryRunner();
Student  student = qr.query(conn, sql, new BeanHandler<Student>(Student.class), "201215128");// 4. 关闭资源
conn.close();

查询单条记录时,这种方式不需要我们编写ResultSetHandler接口的实现类,显然更加方便。

2)查询多条记录

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(查询多条记录)
String sql = "SELECT * FROM Student;";// 3. 实例化QueryRunner,并执行DQL语句
QueryRunner qr = new QueryRunner();
List<Student> list = qr.query(conn, sql, new BeanListHandler<Student>(Student.class));// 4. 关闭资源
conn.close();

DbUtils封装了一个ResultSetHandler接口的实现类ArrayHandler,用于返回多行查询结果的第一行记录:

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(查询多条记录)
String sql = "SELECT * FROM Student;";// 3. 实例化QueryRunner,并执行DQL语句
QueryRunner qr = new QueryRunner();
Object[] student = qr.query(conn, sql, new ArrayHandler());
for(Object fieldValue : student) {      // 每一个fieldValue表示第一行记录的一个分量(列值)System.out.print(fieldValue + " ");
}// 4. 关闭资源
conn.close();

很明显这种查询将多余的数据从数据库返回,降低了数据库查询效率,所以不推荐使用。

另外DbUtils也封装了一个ResultSetHandler接口的实现类ArrayListHandler,返回多行查询结果的所有记录,所以查询多条记录也可以这样:

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(查询多条记录)
String sql = "SELECT * FROM Student;";// 3. 实例化QueryRunner,并执行DQL语句
QueryRunner qr = new QueryRunner();
List<Object[]> list = qr.query(conn, sql, new ArrayListHandler());
for(Object[] student : list) {for(Object fieldValue : student) {System.out.print(fieldValue + " ");}System.out.println();
}// 4. 关闭资源
conn.close();

3)查询聚集函数结果

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(查询Student表的行数)
String sql = "SELECT COUNT(*) FROM Student;";// 3. 实例化QueryRunner, 执行查询操作,返回结果集第一行某一列的值
QueryRunner qr = new QueryRunner();
Long count = qr.query(conn, sql, new ScalarHandler<Long>(1));// 4. 关闭资源
conn.close();

4.4、调用存储过程(函数)

1)调用add函数

add函数:

使用DbUtils调用add函数:

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(调用add函数)
String sql = "SELECT add(?, ?);";// 3. 实例化QueryRunner, 执行查询操作
QueryRunner qr = new QueryRunner();
List<Integer> list = qr.execute(conn, sql, new ScalarHandler<Integer>(1), 100, 200);
for(Integer sum : list) {System.out.println(sum);   // 打印300
}// 4. 关闭资源
conn.close();

2)调用queryStudent函数

queryStudent函数:

// 1. 获取数据库连接
Connection conn = JdbcUtils.getConnection();// 2. 准备SQL语句(调用queryStudent函数)
String sql = "SELECT * FROM queryStudent(?)";// 3. 实例化QueryRunner, 执行查询操作,返回结果集第一行某一列的值
QueryRunner qr = new QueryRunner();
Student student = qr.query(conn, sql, new BeanHandler<Student>(Student.class), 20);// 4. 关闭资源
conn.close();

jdbc ?占位符不起作用_JDBC高级(二):DbUtils相关推荐

  1. mysql jdbc 占位符_JDBC中占位符报错是什么鬼啊

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import java.sql.*; import org.junit.Test; /** * 测试sql注入问题 * @author Wangjiany ...

  2. java jdbc 占位符_java-jdbc

    1.jdbc是什么,它有什么用? java database connection 让java程序员可以直接通过java程序操作数据. jdbc是标准,它是由类与接口组成,对于程序员只需要知道标准(C ...

  3. JDBC占位符的使用

  4. html 空格占位符_HTML常用英文单词,快来背单词吧

    页面布局(layout) header 头部/页眉: index 首页/索引: logo 标志: nav/sub_nav 导航/子导航: banner 横幅广告: main/content 主体/内容 ...

  5. java字符串占位符%s

    字符串占位符%s 一.String.format 二.MessageFormat.format 一.String.format 语法 : String.format(String format, Ob ...

  6. Oracle JDBC中的PreparedStatement占位符过多

    使用Oracle数据库时,导致ORA-01745("无效的主机/绑定变量名称错误")错误的原因有多种. 关于错误ORA-01500到ORA-02098的Oracle 9i文档提供了 ...

  7. C# 编程入门第二课 注释变量,VS2019快捷键,String和string,命名规则,赋值运算符,+号作用占位符,转义字符算术运算符,类型转换

    C# 编程入门第二课 文章目录 C# 编程入门第二课 1. 注释 2 变量 3.VS2019快捷键 4. String和string 5. 命名规则 6. 赋值运算符,+号作用 7. 占位符 8.转义 ...

  8. JDBC使用占位符插入数据报错

    JDBC使用占位符插入数据报错 插入数据时 String sql="insert into user(id,name) values (1,?)" PreparedStatemen ...

  9. 二、SQL注入使用占位符解决、JDBC工具类、封装

    一.SQL注入使用占位符解决 //使用jdbc发送sql语句, 到数据库tb_user 查询是否有该用户名和密码的用户Connection conn = null;PreparedStatement ...

最新文章

  1. windows和linux-JDK环境变量设置
  2. 【Python】深入理解Python函数的9个黄金法则
  3. 经典案例鸢尾花分类, 在Keras中使用sklearn调参
  4. Spring Boot 2应用程序和OAuth 2 –传统方法
  5. 如何开始了解一个新知识(Vuex)
  6. python书写风格_python书写风格
  7. python中set()函数==》创建一个无序不重复的元素集(创将一个集合)
  8. 模拟登录新浪微博(Python)
  9. SQL Server2012内存性能计数器和内存DMV的变化
  10. 路由器工作模式Classless与Classful实验分析
  11. [BZOJ 3052] [wc2013] 糖果公园 【树上莫队】
  12. SSH学习之四 OpenSSH安全
  13. ffplay播放器-数据读取线程
  14. c语言 for循环说课,《程序的循环结构-For循环语句》教学设计
  15. 如何将 M1 Mac(MacBook Pro、Air、iMac、Mac mini)恢复出厂设置?
  16. 2012年华为杯校园编程大赛决赛 类别:软件C/C++语言
  17. 地图与定位(LBS)-MapKit篇
  18. wordpress启动_如何通过7个简单步骤正确地启动WordPress博客(2020)
  19. ccd坏点测试软件,如何检测CCDLCD坏点
  20. Git版本控制管理——分支

热门文章

  1. HDOJ 1863畅通工程(最小生成树kruskal算法并查集实现)
  2. [POJ1961 Period]
  3. 华尔街日报评2010科技创新奖
  4. 什么是机器学习?(上)
  5. 个人永久性免费-Excel催化剂插件功能修复与更新汇总篇之七
  6. 面试官:自己搭建过vue开发环境吗?
  7. 学会使用JDK API
  8. 我心中的核心组件(可插拔的AOP)~大话开篇及目录
  9. 关于递归和斐波那契数列
  10. 请问诸位大神,Android怎么实现图片转动