DbUtils輕量級ORM框架:從JDBC模板代碼中解脫
核心優勢
- Apache Commons組件,
commons-dbutils-1.7.jar僅約300KB
- 核心類
QueryRunner封裝Connection/Statement/ResultSet全生命周期
- 結果集自動映射為JavaBean/List/Map/單值,消除手寫映射代碼
- 無侵入性,可與Spring/JDBC/連接池無縫集成
Maven依賴
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
核心API速查
QueryRunner runner = new QueryRunner(dataSource); // 推薦注入DataSource
-- 更新操作(INSERT/UPDATE/DELETE)
int rows = runner.update("INSERT INTO user(name,age) VALUES(?,?)", "張三", 25);
-- 單對象查詢
User user = runner.query("SELECT * FROM user WHERE id=?",
new BeanHandler<User>(User.class), 1L);
-- 列表查詢
List<User> list = runner.query("SELECT * FROM user",
new BeanListHandler<User>(User.class));
-- 單值查詢(COUNT/MAX/單列)
Long count = runner.query("SELECT COUNT(*) FROM user",
new ScalarHandler<Long>());
-- Map查詢(無實體類場景)
Map<String,Object> map = runner.query("SELECT * FROM user WHERE id=1",
new MapHandler());
完整項目結構示例
src/
├─ main/
│ ├─ java/
│ │ ├─ com.example.util.DBUtils # 連接池工具類
│ │ ├─ com.example.domain.Person # 實體類
│ │ ├─ com.example.dao.PersonDao # 接口
│ │ └─ com.example.dao.impl.PersonDaoImpl # 實現
│ └─ resources/
│ └─ db-config.properties # JDBC配置
└─ test/
└─ com.example.test.DbUtilsTest
關鍵代碼片段
連接池工具類
public class DBUtils {
private static DataSource ds;
static {
Properties p = new Properties();
p.load(DBUtils.class.getClassLoader().getResourceAsStream("db-config.properties"));
ds = BasicDataSourceFactory.createDataSource(p);
}
public static DataSource getDataSource() { return ds; }
public static Connection getConnection() throws SQLException { return ds.getConnection(); }
}
DAO實現
public class PersonDaoImpl implements PersonDao {
private QueryRunner runner = new QueryRunner(DBUtils.getDataSource());
public void add(Person p) throws SQLException {
runner.update("INSERT INTO person(name,age,desc) VALUES(?,?,?)",
p.getName(), p.getAge(), p.getDesc());
}
public Person findById(int id) throws SQLException {
return runner.query("SELECT * FROM person WHERE id=?",
new BeanHandler<Person>(Person.class), id);
}
public List<Person> findAll() throws SQLException {
return runner.query("SELECT * FROM person",
new BeanListHandler<Person>(Person.class));
}
public long count() throws SQLException {
return runner.query("SELECT COUNT(*) FROM person",
new ScalarHandler<Long>());
}
}
進階技巧
- 事務控制:手動獲取
Connection,runner.update(conn, sql, params),最後conn.commit()
- 結果集自定義映射:實現
ResultSetHandler接口處理複雜嵌套對象
- 批量操作:
runner.batch(sql, Object[][] params)大幅提升批量寫入性能
避坑指南
- BeanHandler/BeanListHandler要求實體類有無參構造函數與Setter方法
- 列名與屬性名不一致時需用
AS別名或自定義RowProcessor
- 生產環境必須配合連接池(Druid/HikariCP),禁用
DriverManager.getConnection