commons-dbutils Helper VS JDBCTemplate

这两个JDBC轻量分装框架的确都是刚刚的。
但是相对来说commons-dbutils缺少封装, 接下来就测试上一篇的help.

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
	<comment>ENTITY event, TABLE events</comment>
	<entry key="eventsSequnce">
		EVENTS_SEQUENCE
	</entry> 
	<entry key="queryCounts">
		SELECT count(*) FROM events 
	</entry> 
	<entry key="queryEvents">
		SELECT event_id,event_date,title FROM events 
	</entry> 
	<entry key="queryEventById">
		SELECT event_id id,event_date,title FROM events WHERE event_id = ?
	</entry>
	<entry key="deleteEvent">
		DELETE events WHERE event_id = ?
	</entry>
	<entry key="updateEvent">
		UPDATE events SET event_date = ?, title = ? WHERE event_id = ?
	</entry>
	<entry key="insertEvent">
		INSERT into events(event_id,event_date,title) VALUES(?,?,?)
	</entry>
</properties>




1. 查询对象返回(单列单行)

Spring JDBC queryForObject.
int rowCount = this.jdbcTemplate.queryForObject("select count(*) from t_actor", Integer.class);


用起来真的方便,但是commons-dbutils没有这个方法,而且我感觉这个命名真的很棒.(抄袭下)
DbutilHelper helper = new DbutilHelper("/dbUtils.xml");	
//query for Object
Long counts = helper.queryForObject(helper.getSql("queryCounts"), Long.class);


这里的getSql和上面的语句一致,连传递的参数都一致。 是我抄袭了吗?不是的,而是dbutils和Spring这里的设计撞衫了.

Spring JDBC 使用如下借口

public interface RowMapper<T> {

	/**
	 * Implementations must implement this method to map each row of data
	 * in the ResultSet. This method should not call {@code next()} on
	 * the ResultSet; it is only supposed to map values of the current row.
	 * @param rs the ResultSet to map (pre-initialized for the current row)
	 * @param rowNum the number of the current row
	 * @return the result object for the current row
	 * @throws SQLException if a SQLException is encountered getting
	 * column values (that is, there's no need to catch SQLException)
	 */
	T mapRow(ResultSet rs, int rowNum) throws SQLException;


而commons dbutils,使用如下借口

public interface ResultSetHandler<T> {

    /**
     * Turn the <code>ResultSet</code> into an Object.
     *
     * @param rs The <code>ResultSet</code> to handle.  It has not been touched
     * before being passed to this method.
     *
     * @return An Object initialized with <code>ResultSet</code> data. It is
     * legal for implementations to return <code>null</code> if the
     * <code>ResultSet</code> contained 0 rows.
     *
     * @throws SQLException if a database access error occurs
     */
    T handle(ResultSet rs) throws SQLException;


其实我更喜欢commons-dbutils的设计更能让人理解. 原理都一样,处理结果集到对象.

2. 查询对象(单行)

Spring JDBC queryForObject.
Actor actor = this.jdbcTemplate.queryForObject(
        "select first_name, last_name from t_actor where id = ?",
        new Object[]{1212L},
        new RowMapper<Actor>() {
            public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
                Actor actor = new Actor();
                actor.setFirstName(rs.getString("first_name"));
                actor.setLastName(rs.getString("last_name"));
                return actor;
            }
        });


方法名没变, 不过是用对象数组做参数,还加了RowMapper.

//query bean Object 
		Event count = helper.queryBean(helper.getSql("queryEventById"), Event.class,161L);


我这里换了个名字,因为要做Bean的转化,如果column名称和对象的property名称对应,那么以上就可以了。 如果不对应怎么办?可以使用column Lable,因为这个优先级比较高
用法如下,修改sql是column与property对应.
SELECT event_id id,event_date date,title FROM events WHERE event_id = ?

一般情况下是没有问题的,但是遇上关键字,你就煞笔了吧(date is the keyword in database).[ 其实对象的属性命名也很重要,不要用关键字]

于是乎,我这里加了个转化方法,Map<String,String> columntopropertyoverrride.

Map<String,String> columntopropertyoverrides = new HashMap<String,String>();
		columntopropertyoverrides.put("EVENT_DATE", "date");
		Event count1 = helper.queryBean(helper.getSql("queryEventById"), Event.class,columntopropertyoverrides,161L);

这样就能绕过关键字了。

2. 查询对象列表(多行)

Spring JDBC query.
List<Actor> actors = this.jdbcTemplate.query(
        "select first_name, last_name from t_actor",
        new RowMapper<Actor>() {
            public Actor mapRow(ResultSet rs, int rowNum) throws SQLException {
                Actor actor = new Actor();
                actor.setFirstName(rs.getString("first_name"));
                actor.setLastName(rs.getString("last_name"));
                return actor;
            }
        });


其实spring很狡猾的, query查询的是list, queryForObject只是调用query去第一条. 所以看起来很简单,还是很清晰明白的,比使用框架好多了。[ no configuration]

//query List<bean> Object
		List<Event> events = helper.queryBeanList(helper.getSql("queryEvents"), Event.class);
		System.out.println(events);


这个功能,其实就是把一个对象放到list,两个没区别.


3. 添加
this.jdbcTemplate.update(
        "insert into t_actor (first_name, last_name) values (?, ?)",
        "Leonor", "Watling");



Long id = helper.insert(helper.getSql("insertEvent"), helper.getSql("eventsSequnce"), new java.sql.Date(new Date().getTime()),"good mood");


4. 更新

this.jdbcTemplate.update(
        "update t_actor set last_name = ? where id = ?",
        "Banjo", 5276L);



int effect = helper.update(helper.getSql("updateEvent"),new java.sql.Date(new Date().getTime()),"okok",150L);


5. 删除

this.jdbcTemplate.update(
        "delete from actor where id = ?",
        Long.valueOf(actorId));



int effect1 = helper.update(helper.getSql("deleteEvent"),170L);



这真的太像了。 如果commons-dbutils封装一下,还是一个不错的轻量级ORM. 和Spring JDBC差不多,不过如果使用Spring开发的同学,使用Spring JDBC就可以了,自己封装一下就可以了,就像我封装commons-dbutils一样

因为轻量,基本上使用JDBC操作,所以适合批量操作。
Object[][] params = new Object[5][];
		params[0] = new Object[]{"cao",140L};
		params[1] = new Object[]{"cao",141L};
		params[2] = new Object[]{"cao",142L};
		params[3] = new Object[]{"cao",161};
		params[4] = new Object[]{"cao",162}; 
		
		//batch update in batchSize
		int[] effect2 = helper.batch("update events set title=? where event_id=?", params, 2);
		for(int effect2s:effect2){
			System.out.println("batch:"+effect2s);
		}
		
		//batch update in params.length.
		int[] effectall = helper.batch("update events set title=? where event_id=?", params);
		for(int effectalls:effectall){
			System.out.println("batchall:"+effectalls);
		}
	/*
     * Indicates that a batch statement was executed with a successful result,
     * but a count of the number of rows it affected is unavailable.
     * public static final int SUCCESS_NO_INFO = -2; 
	 */



以上是批量更新,还有批量插入,批量查询。
可能有人会问批量查询????

if query large Datas, please set FecthSize, this will be improve performance.

一般情况下,我们select * from table, 默认一次fecth 10条,因为FecthSize默认为10, 如果我们要获取1000条,10000条?

if you increase this number, will be reduce client and oracle's response. but suggest not over than 100, or will be spend middle component's memory.

如果获取大数据的话,把这个值设置大一点,但是不要超过100,否这中间件压力很大。不过我没有测试过。但是调到1000来获取5W的数据和使用10来获取5W条数据,时间相差100倍。








猜你喜欢

转载自a123159521.iteye.com/blog/2201120