DbUtils

今天花了一晚上的時間來學習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;
	}
	@Override
	public <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;
	}
	@Override
	public <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;
	}
	@Override
	public 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;
	}
	@Override
	public long insert(String sql, Object... args) {
		return executeUpdate(sql, args);
	}
	@Override
	public long update(String sql, Object... args) {
		return executeUpdate(sql, args);
	}
	@Override
	public void delete(String sql, Object... args) {
		executeUpdate(sql, args);
	}
	@Override
	public 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;
	}
	@Override
	public 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;
	@Before
	public void testDaoImpl() {
		dao = new DaoImpl();
	}
	@Test
	public void testFindAll() {
		List<Sex> result = dao.findAll(Sex.class);
		Assert.assertEquals(result.size(), 6);
	}
	@Test
	public void testFindById() {
		Sex sex = dao.findById(Sex.class, 4);
		Assert.assertEquals(sex.getSex_mc(), "男");
	}
	@Test
	public 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"), "女");
	}
	@Test
	public void testInsert() {
		long id = dao.insert("insert into sex (sex_mc) values (?)", new Object[] { "男" });
		Assert.assertNotNull(id);
	}
	@Test
	public void testUpdate() {
		long id = dao.update("update sex set sex_mc=? where sex_id=?", new Object[] { "男", 5 });
		Assert.assertEquals(id, 5);
	}
	@Test
	public void testDelete() {
		dao.delete("delete from sex where sex_id=?", new Object[] { 5 });
	}
	// @Test
	public void testExecuteUpdate() {
	}
	@Test
	public 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
然後自己再深入到源碼看一下就一切都明白了。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章