| 分類 | 說明 |
|---|---|
| 名稱 | DbUtils |
| 全稱 | Commons DbUtils |
| 功能 | 數(shù)據(jù)庫(kù)操作組件 |
Common DbUtils是由Apache組織提供的用于封裝JDBC簡(jiǎn)化DAO層開發(fā)的工具類,用于簡(jiǎn)化JDBC應(yīng)用程序的開發(fā)。
- 數(shù)據(jù)表讀操作后可將結(jié)果集轉(zhuǎn)換為L(zhǎng)ist、Array、Set等Java集合
- 數(shù)據(jù)表寫操作僅需書寫SQL語(yǔ)句
- 使用JNDI、數(shù)據(jù)庫(kù)連接池等技術(shù)優(yōu)化性能
- Bean Mapping:自動(dòng)將結(jié)果集封裝為JavaBean無需手動(dòng)封裝、類型轉(zhuǎn)換
- 沒有資源泄漏:確保不發(fā)生資源泄漏,無需清理或清除代碼。
資源地址
Maven項(xiàng)目添加DbUtils依賴
$ vim pom.xml
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
DbUtils包含三個(gè)核心類
| 核心類 | 說明 |
|---|---|
| DbUtils | 數(shù)據(jù)庫(kù)連接對(duì)象,控制連接、事務(wù)、驅(qū)動(dòng)加載...,線程安全。 |
| QueryRunner | SQL語(yǔ)句操作對(duì)象,可設(shè)置查詢結(jié)果集的封裝策略,線程安全。 |
| ResultSetHandler | 封裝數(shù)據(jù)的策略對(duì)象,將查詢結(jié)果集中的數(shù)據(jù)轉(zhuǎn)換為對(duì)象。 |
DbUtils安裝前準(zhǔn)備工作
| 類庫(kù) | 說明 |
|---|---|
| 驅(qū)動(dòng)程序 | MySQL驅(qū)動(dòng) |
| 數(shù)據(jù)源 | C3P0數(shù)據(jù)源 |
| 數(shù)據(jù)庫(kù)操作類 | DbUtils |
操作流程
創(chuàng)建QueryRunner對(duì)象調(diào)用query()執(zhí)行DSL語(yǔ)句或調(diào)用update()執(zhí)行DML語(yǔ)句。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.3</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
JavaBean
JavaBean組件是一個(gè)類,用于封裝數(shù)據(jù),具有以下特性:
- 需實(shí)現(xiàn)
java.io.Serializable接口 - 需提供私有字段
- 需提供
setter/getter方法 - 需提供無參構(gòu)造
例如:使用Lombok創(chuàng)建JavaBean
$ vim pom.xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>provided</scope>
</dependency>
將數(shù)據(jù)表sys_user映射為JavaBean組件
$ vim entity/BaseEntity.java
package com.jc.entity;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.util.Date;
@Data
public class BaseEntity implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String code;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createdAt;
private String createdBy;
@JsonFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date updatedAt;
private String updatedBy;
}
$ vim entity/SysUser.java
package com.jc.entity;
import lombok.Data;
@Data
public class SysUser extends BaseEntity{
private String username;
private String password;
}
QueryRunner
QueryRunner類是DbUtils庫(kù)的核心類,此類是線程安全的,它使用可插入策略執(zhí)行SQL查詢以處理ResultSet結(jié)果集。
public class QueryRunner extends AbstractQueryRunner
| 構(gòu)造方法 | 示例 | 說明 |
|---|---|---|
| 無參構(gòu)造 | QueryRunner qr = new QueryRunner(); |
調(diào)用query()或update()方法時(shí)需攜帶Connection類型參數(shù) |
| 有參構(gòu)造 | QueryRunner qr = new QueryRunner(DataSource dataSource); |
參數(shù)為連接池對(duì)象(DataSource dataSource) |
DSL
查詢操作靜態(tài)方法
qr.query(String sql, ResultSetHandler rsh, Param...)
qr.query(Connection con, String sql, ResultSetHandler rsh, Param...)
| 參數(shù) | 說明 |
|---|---|
| Connection con | 數(shù)據(jù)庫(kù)連接對(duì)象,使用有參構(gòu)造QueryRunner時(shí)可不傳。 |
| String sql | DSL語(yǔ)句 |
| ResultSetHandler rsh | 結(jié)果集處理方式 |
| Param | 可變參數(shù),對(duì)應(yīng)SQL語(yǔ)句占位符的值。 |
例如:使用有參構(gòu)造QueryRunner對(duì)象執(zhí)行查詢單條記錄操作
try {
QueryRunner qr = new QueryRunner(C3P0Util.getDataSource());
Long id = 4L;
String sql = "SELECT * FROM sys_user WHERE 1=1 AND id = ?";
ResultSetHandler<SysUser> rsh = new BeanHandler<>(SysUser.class);
SysUser d = qr.query(sql, rsh, id);
System.out.println(d.getId());
} catch (SQLException e) {
e.printStackTrace();
}
例如:使用無參構(gòu)造QueryRunner對(duì)象執(zhí)行查詢單條記錄操作
Connection conn = null;
QueryRunner qr = null;
try {
conn = C3P0Util.getConnection();
qr = new QueryRunner();
String sql = "SELECT * FROM sys_user WHERE 1=1 AND id = ?";
ResultSetHandler<SysUser> rsh = new BeanHandler<>(SysUser.class);
SysUser su = qr.query(conn, sql, rsh, 4);
System.out.println(su.getId());
} catch (SQLException e) {
e.printStackTrace();
}finally {
C3P0Util.release(conn);
}
ResultSetHandler
ResultSetHandler接口負(fù)責(zé)對(duì)結(jié)果集轉(zhuǎn)換成對(duì)象
public interface ResultSetHandler<T>
結(jié)果集處理方式,ResultSetHandler接口實(shí)現(xiàn)類。
| ResultSetHandler | 說明 |
|---|---|
| ArrayHandler | 將結(jié)果集首行存入數(shù)組 |
| ArrayListHandler | 將結(jié)果集每行數(shù)據(jù)存入數(shù)組,多個(gè)數(shù)組存入集合List<Object[]> |
| BeanHandler | 將結(jié)果集首行數(shù)據(jù)存入Java Bean對(duì)象 |
| BeanListHandler | 將結(jié)果集每行數(shù)據(jù)存入Java Bean對(duì)象,多個(gè)對(duì)象存入集合。 |
| ColumnListHandler | 將某列數(shù)據(jù)存入集合 |
| MapHandler | 將結(jié)果集首行數(shù)據(jù)存入Map集合 |
| MapListHandler | 將結(jié)果集每行數(shù)據(jù)存入Map集合,多個(gè)Map存入List集合。 |
| ScalarHandler | 獲取一個(gè)值,比如COUNT(1)、SUM(price)... |
DML
qr.update(String sql, Object ...params)
插入/修改/刪除
Connection conn = null;
QueryRunner qr = null;
try {
conn = C3P0Util.getConnection();
qr = new QueryRunner();
String username = "root";
String password = "root";
String sql = "INSERT INTO sys_user(username, password) VALUES(TRIM(?), MD5(?))";
int er = qr.update(conn, sql, username, password);
System.out.println("effected records = " + er);
} catch (SQLException e) {
e.printStackTrace();
}finally {
C3P0Util.release(conn);
}
二次封裝
獲取數(shù)據(jù)庫(kù)連接或數(shù)據(jù)源
$ util/ConnectionFactory.java
package com.jc.util;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
public class ConnectionFactory {
private static final ConnectionFactory cf = new ConnectionFactory();
public static ComboPooledDataSource ds;
private Connection conn = null;
static {
Properties p = new Properties();
try{
InputStream is = ConnectionFactory.class.getClassLoader().getResourceAsStream("c3p0.properties");
p.load(is);
ds = new ComboPooledDataSource();
}catch (IOException e) {
e.printStackTrace();
}
}
private ConnectionFactory(){}
public static ConnectionFactory getInstance(){
return cf;
}
public static ComboPooledDataSource getDataSource(){
return ds;
}
public Connection getConnection(){
if(ds != null){
try{
conn = ds.getConnection();
}catch(SQLException e){
e.printStackTrace();
}
}
return conn;
}
}
數(shù)據(jù)庫(kù)操作
$ vim util/DBUtil.java
package com.jc.util;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.*;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
public class DBUtil {
public static QueryRunner getQueryRunner(){
return new QueryRunner(ConnectionFactory.getDataSource());
}
public static int count(String sql){
try {
Object v = getQueryRunner().query(sql, new ScalarHandler<>());
return v==null?0:(int)v;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
public static Object[] getArray(String sql, Object... param){
try {
return getQueryRunner().query(sql, new ArrayHandler(), param);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static Map<String, Object> getMap(String sql, Object... param){
try {
return getQueryRunner().query(sql, new MapHandler(), param);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static <T> T getBean(Class<T> type, String sql, Object... param){
try {
return getQueryRunner().query(sql, new BeanHandler<>(type), param);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static List<Object[]> getArrayList(String sql, Object... param){
try {
return getQueryRunner().query(sql, new ArrayListHandler(), param);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static List<Map<String, Object>> getMapList(String sql, Object... param){
try {
return getQueryRunner().query(sql, new MapListHandler(), param);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static <T> List<T> getBeanList(Class<T> type, String sql, Object... param){
try {
return getQueryRunner().query(sql, new BeanListHandler<>(type), param);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static int insert(String sql, Object... param){
try {
return getQueryRunner().update(sql, param);
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
public static int update(String sql, Object... param){
try {
return getQueryRunner().update(sql, param);
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
public static int delete(String sql, Object... param){
try {
return getQueryRunner().update(sql, param);
} catch (SQLException e) {
e.printStackTrace();
}
return 0;
}
public static int[] batch(String sql, Object[][] param){
try {
return getQueryRunner().batch(sql, param);
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
public static void beginTransaction(Connection conn){
try {
conn.setAutoCommit(false);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static void commit(Connection conn){
try {
conn.commit();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static void rollback(Connection conn){
try {
conn.rollback();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
測(cè)試
try {
Long id = 4L;
String sql = "SELECT * FROM sys_user WHERE 1=1 AND id = ?";
SysUser d = DBUtil.getBean(SysUser.class, sql, id);
System.out.println(d.getId());
} catch (Exception e) {
e.printStackTrace();
}