网站首页 > 开源技术 正文
DbUtils的快速入门
1 简介
我们先来简单看下,DbUtils是干什么的。
这图大家简单看下就好,我下面会总结一下(噗,就是为了证明我是从官网找的233)
简而言之:DbUtils可以高效地使用JDBC进行开发,让你更加专注于查询和更新数据(可以自动完成实体类等的映射)。
特点:
- Small—— DbUtils内容不多,上手非常快,主要有两个核心:QueryRunner和ResultSetHandler。
- Transparent—— 你只需要负责操作(写sql)即可,DbUtils会执行sql返回结果并关闭资源
- Fast—— 引入DbUtils即可使用,不需要额外操作。
2 `QueryRunner`和`ResultSetHandler`
QueryRunner和ResultSetHandler是DbUtils的两个核心。
2.1 QueryRunner介绍
QueryRunner的作用主要是:处理sql语句,进行增删改查等。
常用构造器:
// Constructor for QueryRunner that takes a DataSource to use.
// 传入一个连接池给QR使用
QueryRunner(DataSource ds)
常用CRUD的API我会在章节4进行演示。
2.2 ResultSetHandler介绍
`ResultSetHandler的作用主要是:完成结果映射(使用反射),比如我们查出的结果可以直接是一个User实体类。
常用构造器:
// Creates a new instance of BeanHandler.
// 这是BeanHandler的构造器,传入一个想要转换的实体类的Class类型,因为底层还是使用反射
// 其他类似
BeanHandler(Class<? extends T> type)
3 上手小案例
3.1 建立 user 表
大家简单建立个user表即可。
create database if not exists jdbc_demo
use jdbc_demo
create table user
(
id bigint auto_increment,
username varchar(64) not null comment '帐号',
password varchar(64) not null comment '密码',
constraint user_pk
primary key (id)
)
comment '用户表';
INSERT INTO jdbc_demo.user (username, password) VALUES ('user1', '123');
INSERT INTO jdbc_demo.user (username, password) VALUES ('user2', '456');
INSERT INTO jdbc_demo.user (username, password) VALUES ('user3', '123456');
3.2 导入相关jar包
- mysql-connector-java-8.0.19.jar —— mysql驱动
- commons-dbutils-1.7.jar —— DbUtilsjar包下载地址(提取码:r7q9)
- druid-1.1.22.jar —— druid
3.3 操作流程
这里分了 6 点,主要是为了大家能够方便理解(●'?'●)
// 1.获取连接池
DataSource dataSource = JDBCUtil.getDataSource();
// 2.建立QueryRunner,将连接池当成参数传进构造器中
QueryRunner queryRunner = new QueryRunner(dataSource);
// 3.创建相关的ResultSetHandle,形成结果映射
BeanHandler<User> userBeanHandler = new BeanHandler<>(User.class);
// 4.编写sql语句
String sql = "select * from jdbc_demo.user where id = ?";
// 5.执行qr的query方法
// 参数1:sql语句
// 参数2:ResultSetHandler
// 参数3:类似preparedStatement,完成对sql语句占位符的替换
// 这个query底层就是使用preparedStatement
User user = queryRunner.query(sql, userBeanHandler, 1);
// 6.查看结果
System.out.println(user);
// Perfect (●'?'●)
// User{id=1, username='user1', password='123'}
哈哈,通过这个小案例,我们成功获取了User实体类的相关信息。
是不是感觉很方便→ v →,别着急,更精彩的还在后面(●'?'●)!
4. 常用CRUD的API介绍
4.1 查找单个数据
使用ScalarHandler
// 1.创建QueryRunner
QueryRunner queryRunner = new QueryRunner(JDBCUtil.getDataSource());
// 2. 查询,
// Tip:先写handler,再写sql语句,这样有提示
Long query = queryRunner.query("select count(*) from jdbc_demo.user", new ScalarHandler<>());
// 3.输入
System.out.println(query);
// 得到 3
4.2 查找单条数据
使用BeanHandler
// 1.创建QueryRunner
QueryRunner queryRunner = new QueryRunner(JDBCUtil.getDataSource());
// 2. 查询,
// Tip:先写handler,再写sql语句,这样有提示
User user = queryRunner.query(
"select * from jdbc_demo.user where username = ?",
new BeanHandler<>(User.class),
"user2");
// 3.输入
System.out.println(user);
// 得到 User{id=2, username='user2', password='456'}
4.3 查找多条数据
使用BeanListHandler
// 1.创建QueryRunner
QueryRunner queryRunner = new QueryRunner(JDBCUtil.getDataSource());
// 2. 查询,
// Tip:先写handler,再写sql语句,这样有提示
// 也可以使用where,这边只是举个例子
List<User> users = queryRunner.query(
"select * from jdbc_demo.user",
new BeanListHandler<>(User.class));
// 3.输出
System.out.println(users);
// 得到
// [User{id=1, username='user1', password='123'},
// User{id=2, username='user2', password='456'},
// User{id=3, username='user3', password='123456'}]
4.4 增加
// 1.创建QueryRunner
QueryRunner queryRunner = new QueryRunner(JDBCUtil.getDataSource());
// 2. 操作,
// Tip:先写handler,再写sql语句,这样有提示
// 也可以使用where,这边只是举个例子
// 增删改 都是 update
int res = queryRunner.update("insert into jdbc_demo.user values (null,'user4','user4')");
// 3.输出
System.out.println(res);
// 得到 1 说明成功(●'?'●)
我们可以看到数据库确实有新的数据。
4.5 更新
// 1.创建QueryRunner
QueryRunner queryRunner = new QueryRunner(JDBCUtil.getDataSource());
// 2. 操作,
// Tip:先写handler,再写sql语句,这样有提示
// 增删改 都是 update
int res = queryRunner.update(
"update jdbc_demo.user set password = '123456' where username = ?",
"user4");
// 3.输出
System.out.println(res);
// 得到 1 说明成功(●'?'●)
可以看到,数据库的数据已经被修改了。
4.6 删除
// 1.创建QueryRunner
QueryRunner queryRunner = new QueryRunner(JDBCUtil.getDataSource());
// 2. 操作,
// Tip:先写handler,再写sql语句,这样有提示
// 增删改 都是 update
int res = queryRunner.update(
"delete from jdbc_demo.user where username = ? ",
"user4");
// 3.输出
System.out.println(res);
// 得到 1 说明成功(●'?'●)
可以看到,数据库中的user4已经被删除啦OvO
4.7 批量操作
这里我们介绍下批量插入, 删除和更新也是类似的。(记住数据库的url 要写上 rewriteBatchedStatements=true)
// 1.创建QueryRunner
QueryRunner queryRunner = new QueryRunner(JDBCUtil.getDataSource());
// 2. 操作
// 使用batch方法,
// 参数1:批量操作的sql
// 参数2:二位数组,行数 -> 执行次数 ,列 -> 替换占位符
Object[][] params = new Object[10][];
for (int i = 0; i < params.length; i++) {
params[i] = new Object[]{"lemonfish" + i, i};
}
// batch代表每行语句执行的结果
int[] batch = queryRunner.batch(
"insert into jdbc_demo.user values (null,?,?)",
params
);
// 3.输出
System.out.println(Arrays.toString(batch));
// 得到 [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] 说明全部成功(●'?'●)
可以看到,10条数据被成功插入啦
4.8 事务操作
事务操作和之前的有一些区别,QueryRunner操作事务,需要用到connection(其实还是原生的JDBC),这时候用我们自己封装的工具类获取connection就行。
// 1.创建QueryRunner
QueryRunner queryRunner = new QueryRunner();
// 2. 获取开启事务的connection
Connection connection = JDBCUtil.getConnectionWithTransaction();
// 3. 业务
// 3.1 删除、添加
try {
int delete = queryRunner.update(connection,
"delete from jdbc_demo.user where username = ? ",
"user3");
int insert = queryRunner.update(connection,
"insert into jdbc_demo.user values (null,'user4','user4')");
// 3.2 手动制造错误,查看回滚效果
int error = 1 / 0;
// 3.3 手动提交
connection.commit();
} catch (SQLException throwables) {
// 3.4 进行回滚
connection.rollback();
throwables.printStackTrace();
} finally{
// 记住关闭
connection.close();
}
rollback会在代码执行出错的情况下,回滚到connection执行sql语句前的状态。
5. 封装BaseDAO
哈哈,相信大家看到这里,是不是已经感觉相比原生JDBC,DbUtils用起来已经很爽了呢。
别急,还有更爽的呢→ v →
我们接下来封装一个BaseDAO ,封装一些常用的增删改查操作,然后使用子类继承的方式即可使用。
增删改查,一句sql搞定
这个就是BaseDAO的代码,基本就是整合了下前面的API。
/**
* 封装基本的增删改查,以复用代码
*/
public class BaseDAO<T> {
QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
/**
* 增删改
*
* @param sql sql语句
* @param params 占位符
* @return
*/
public boolean update(String sql, Object... params) {
int result = 0;
try {
result = qr.update(sql, params);
} catch (SQLException e) {
e.printStackTrace();
}
return result > 0;
}
/**
* 查询 单个值
*
* @param sql
* @param params
* @return
*/
public Object selectScalar(String sql, Object... params) {
try {
return qr.query(sql, new ScalarHandler<>(), params);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 查询 单行
*
* @param sql
* @param clazz
* @param params
* @return
*/
public T selectOne(String sql, Class<T> clazz, Object... params) {
try {
return qr.query(sql, new BeanHandler<>(clazz), params);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 查询 多行
*
* @param sql
* @param clazz
* @param params
* @return
*/
public List<T> selectList(String sql, Class<T> clazz, Object... params) {
try {
return qr.query(sql, new BeanListHandler<>(clazz), params);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 批量操作 增删改
* @param sql
* @param params
* @return
*/
public int[] batch(String sql,Object[][] params){
int[] batch = new int[0];
try {
batch = qr.batch(sql,params);
} catch (SQLException e) {
e.printStackTrace();
}
return batch;
}
}
使用方式
- 编写一个UserDAO继承BaseDAO java public class UserDAO extends BaseDAO<User>{ // 可以自行拓展,BaseDAO只是封装了最基本的增删改查 }
- 使用实例 java // 1.获取UserDAO UserDAO userDAO = new UserDAO(); // 2.使用 User user = userDAO.selectOne("select * from user where username= ?", User.class, "user1"); // 3. 操作结果 System.out.println(user); // 输出结果:User{id=1, username='user1', password='123'}
哈哈!是不是简简单单一句sql就搞定查询啦OwO,增删改等等也是一样喔~~
DbUtils的底层实现主要是JDBC和反射(比如生成bean,然后调用setter等等),源码稍微看个大概不是很难,有兴趣的小伙伴可以自行阅读下。
6. 写在最后
看到这里,相信你对Java操作数据库又有了进一步的认识啦(●'?'●)
基本在接触持久层框架前,这算是比较好的处理办法啦。
猜你喜欢
- 2024-09-19 将Sentinel监控数据持久化到外部InfluxDB时间序列数据库
- 2024-09-19 【每日一学】解锁数据库之门:深入探讨JDBC技术的奇妙世界
- 2024-09-19 成为优秀的Java程序员要具备哪些技能?
- 2024-09-19 Java架构师的10个学习经验,不可错过
- 2024-09-19 软件测试学习教程——JDBC开发(jdbc 测试)
- 2024-09-19 文科妹子都能看懂Mybatis快速入门教程
- 2024-09-19 如何通过连接池提高API性能(连接池获取连接)
- 2024-09-19 应大家需要,Java常用开发工具汇总来了
- 2024-09-19 jSqlBox 4.0.8 发布,在 Java 里直接写 SQL 的 ORM 工具
- 2024-09-19 一行代码搞定数据库操作 ThinkJDBC
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- jdk (81)
- putty (66)
- rufus (78)
- 内网穿透 (89)
- okhttp (70)
- powertoys (74)
- windowsterminal (81)
- netcat (65)
- ghostscript (65)
- veracrypt (65)
- asp.netcore (70)
- wrk (67)
- aspose.words (80)
- itk (80)
- ajaxfileupload.js (66)
- sqlhelper (67)
- express.js (67)
- phpmailer (67)
- xjar (70)
- redisclient (78)
- wakeonlan (66)
- tinygo (85)
- startbbs (72)
- webftp (82)
- vsvim (79)
本文暂时没有评论,来添加一个吧(●'◡'●)