DbUtils

来源:互联网 发布:批量注册淘宝账号 编辑:程序博客网 时间:2024/05/10 14:26
今天花了一晚上的时间来学习dbutils,其实一开始都不知道有这个东西,都是通过一师兄说的,说这东西挺好用,操作又简单,于是就怀揣着一颗好奇的心去学习了一下dbutils。本身dbutils就是对jdbc做了一层薄薄的封装,前段时间也学习过JdbcTemplate,自己做了一下比较,感觉这俩东西很相似,毕竟都是对JDBC简单的封装,但是自我感觉dbutils更简单,更易于操作,对jdbc封装的更薄

既然是使用别人的东西,当然得把它的东西加进来。其实很小,这个包又不依赖于其他包,就只有一个包而已,然后再加上我们自己还要使用到的一些到,既然是对数据库操作,数据库的驱动包当然不能少了,我这里使用的mysql,再加上一个log4j。


下面直接来看一下例子吧。为了更省事,我将DAO层又简单的封装了一层。首先提取一个DAO接口。
/** *  */package org.byent.dao;import java.util.List;import java.util.Map;/** * @author Z.ting 2011-8-10 下午07:57:27 */public interface Dao {public <T> List<T> findAll(Class<T> clazz);public <T> T findById(Class<T> clazz, int id);public long insert(String sql, Object... args);public long update(String sql, Object... args);public List<Map<String, Object>> executeQuery(String sql, Object... args);public long executeUpdate(String sql, Object... args);public void delete(String sql, Object... args);public int[] batchUpdate(String sql, Object[][] objs);}                      
这里边就是定义一些CRUD的操作,大家对这个应该不陌生了。现在接口有了,当然需要写一个实现类来完成这个接口所定义的一些工作咯,下面来看下DAO的实现类。

/** *  */package org.byent.dao.impl;import java.sql.ResultSet;import java.sql.SQLException;import java.util.List;import java.util.Map;import java.util.Properties;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.ResultSetHandler;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;import org.apache.commons.dbutils.handlers.MapListHandler;import org.apache.log4j.Logger;import org.byent.dao.Dao;import com.mysql.jdbc.JDBC4Connection;import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;/** * @author Z.ting 2011-8-10 下午08:05:06 */public class DaoImpl implements Dao {private MysqlDataSource dataSource = new MysqlDataSource();private QueryRunner qryRun = null;private Logger logger = Logger.getLogger(getClass());private java.sql.DatabaseMetaData dbmb;public DaoImpl() {dataSource.setUrl("jdbc:mysql://localhost:3306/blog");dataSource.setUser("root");dataSource.setPassword("zhangting");qryRun = new QueryRunner(dataSource);dbmb = getDatabaseMetaData();}private java.sql.DatabaseMetaData getDatabaseMetaData() {Properties info = new Properties();info.setProperty("user", "root");info.setProperty("password", "zhangting");java.sql.DatabaseMetaData metaData = null;try {metaData = new JDBC4Connection("localhost", 3306, info, "blog", null).getMetaData();} catch (SQLException e) {e.printStackTrace();}return metaData;}@Overridepublic <T extends Object> List<T> findAll(Class<T> clazz) {ResultSetHandler<List<T>> rsh = new BeanListHandler<T>(clazz);List<T> result = null;try {result = qryRun.query("select * from " + clazz.getSimpleName(), rsh);logger.debug("SQL: select * from " + clazz.getSimpleName());} catch (SQLException e) {logger.error("Can not this query table " + clazz.getSimpleName(), e);}return result;}@Overridepublic <T> T findById(Class<T> clazz, int id) {ResultSetHandler<T> rsh = new BeanHandler<T>(clazz);T result = null;try {ResultSet rs = dbmb.getPrimaryKeys(null, null, clazz.getSimpleName());String primary_key = null;while (rs.next()) {primary_key = rs.getString("Column_name");}if (!"".equals(primary_key) || null != primary_key) {result = qryRun.query("select * from " + clazz.getSimpleName() + " where " + primary_key + "=?", rsh, new Object[] { id });logger.debug("SQL: select * from " + clazz.getSimpleName() + " where " +                     primary_key + "=" + id);} else {logger.error("This table " + clazz.getSimpleName() + " has not primary key");throw new SQLException("This table has not primary key");}} catch (SQLException e) {logger.error("Can not this query table " + clazz.getSimpleName(), e);}return result;}@Overridepublic List<Map<String, Object>> executeQuery(String sql, Object... args) {MapListHandler rsh = new MapListHandler();List<Map<String, Object>> result = null;try {result = qryRun.query(sql, rsh, args);} catch (SQLException e) {e.printStackTrace();}return result;}@Overridepublic long insert(String sql, Object... args) {return executeUpdate(sql, args);}@Overridepublic long update(String sql, Object... args) {return executeUpdate(sql, args);}@Overridepublic void delete(String sql, Object... args) {executeUpdate(sql, args);}@Overridepublic long executeUpdate(String sql, Object... args) {long id = 0;try {id = qryRun.update(sql, args);} catch (SQLException e) {logger.error("This table can not changed !", e);}return id;}@Overridepublic int[] batchUpdate(String sql, Object[][] objs) {int[] ids = null;try {ids = qryRun.batch(sql, objs);} catch (SQLException e) {e.printStackTrace();}return ids;}}                      


看见这个QueryRunner了吗,这个类就是我们应该控制的类。然后对数据库的一步步工作都由这个东西来帮我们完成了。

是不是突然觉得真的很简单?简简单单的一个调用就把一切工作都帮我们完成了,其实我们使用到的无非就是query、update、batch操作。

操作完成的结果都是由实现ResultSetHandler此接口的类来完成的。看一下我们都可以将结果包装成什么类型来返回给客户端吧。



看一下吧,都是我们常用到的容器类。实现一些常用的结果返回已经足够了。再来看一下它的core包。


BasicRowProcessor与BeanRowProcessor主要是将数据库的记录封装到各个容器与bean文件中。DbUtils主要就是完成了以前ResultSet,Connection,statement这些个的关闭啊,回滚啊。一些个我们以前写个简单查询就要噼里啪啦写一大堆的东西。现在没那么麻烦了,因为DbUtils已经帮我们完成了。

接下来再写个测试类来测试一下是否通过吧。
package org.byent.dao.impl.test;import java.util.List;import java.util.Map;import junit.framework.Assert;import org.byent.dao.Dao;import org.byent.dao.impl.DaoImpl;import org.byent.pojo.Sex;import org.junit.Before;import org.junit.Test;public class DaoImplTest {private Dao dao;@Beforepublic void testDaoImpl() {dao = new DaoImpl();}@Testpublic void testFindAll() {List<Sex> result = dao.findAll(Sex.class);Assert.assertEquals(result.size(), 6);}@Testpublic void testFindById() {Sex sex = dao.findById(Sex.class, 4);Assert.assertEquals(sex.getSex_mc(), "男");}@Testpublic void testExecuteQuery() {List<Map<String, Object>> result = dao.executeQuery("select * from sex where sex_id=?", new Object[] { 1 });Assert.assertEquals(result.get(0).get("sexId"), "女");}@Testpublic void testInsert() {long id = dao.insert("insert into sex (sex_mc) values (?)", new Object[] { "男" });Assert.assertNotNull(id);}@Testpublic void testUpdate() {long id = dao.update("update sex set sex_mc=? where sex_id=?", new Object[] { "男", 5 });Assert.assertEquals(id, 5);}@Testpublic void testDelete() {dao.delete("delete from sex where sex_id=?", new Object[] { 5 });}// @Testpublic void testExecuteUpdate() {}@Testpublic void testBatchUpdate() {Object[][] objs = new Object[][] { { "man" }, { "women" }, { "man" } };int[] ids = dao.batchUpdate("insert into sex (sex_mc) values(?)", objs);Assert.assertEquals(3, ids.length);}}                      

亮绿灯了,表明测试已经通过。

PS:现在操作数据库的框架可真多啊,东西多了,学习起来还真是个麻烦的事,打好基础才是王道,现在所谓的持久化框架最终还是基于JDBC开发。效率高才是真的好。

看一下官方给的Example:http://commons.apache.org/dbutils/examples.html
然后自己再深入到源码看一下就一切都明白了。
原创粉丝点击