当Ibatis的queryWithRowHandler不再满足我们

本文禁止转载,版权归本站、作者和北京电子工业出版社所有,
细节请购买和阅读:
《JavaScript高级应用与实践》
书号:ISBN 978-7-121-06123-3
北京电子工业出版社.博文视点.2008/03/31出版
购买地址:http://www.china-pub.com/39669
到作者网站进行了解:http://m9m.3322.org/doc/js/md00.jsp

注意:本文需要有一定ibatis和java基础的人阅读。

相信许多人都知道Ibatis的queryWithRowHandler是为了满足我们大数据操作的方法,
它为了避免了大量数据缓存于内存而设计的。而我们往往需要对Statement和ResultSet直接进行操作,
以满足我们的特殊需求,这时候,queryWithRowHandler就已经无法满足我们了。
下面我们通过在java中设计回调模式(call back),进行设计精巧的模式应用程序。

1、首先,我们设计一个接口,这个接口用作构造匿名函数对象而用,当然,也可以不用构造匿名函数对象:

import java.util.Map;

/***
* calback回调模式在获取表格列注释的应用
* @author 夏天
*
*/
public interface IMetaData {

/***
* 设置返回结果的Map对象,该方法必须返回this
* @param map
* @return
*/
public IMetaData setMap(Map map);

/***
* 返回要执行的Sql语句
* @return
*/
public String getSql();

/***
* 获取返回的Map对象
* @return
*/
public Map getResultMap();

/***
* 获取注释,并存放入map中
* @param rstSet
*/
public void getComment(ResultSet rstSet);
}

2、ibatis的dao中设计:
A、获取连接对象
/***
* 获取连接
* @return
*/
public Connection getConnection() {
try {
return super.getSqlMapClientTemplate().getDataSource().getConnection();
} catch (SQLException e) {
log.error(e);
}
return null;
}

B、回调模式的设计:
/***
* 回调模式(Callback)获取表格列注释的设计
* @param metaData
*/
public void callBackWithResultSet(IMetaData metaData)
{
Connection conn = null;
Statement statement = null;
ResultSet rstSet = null;
try
{
// 获取JDBC链接
conn = getConnection();
statement = conn.createStatement();
conn.setAutoCommit(true);
// 获取返回的对象
Map map = metaData.getResultMap();
// 执行SQL语句
rstSet = statement.executeQuery(metaData.getSql());
if(null != map)
while(rstSet.next())
{
// 回调中处理每一行的数据,如果直接将数据输出到response流或文件流中
// 则,大数据的处理就不至于将数据都缓存到内存而导致内存溢出了
// 获取注释,并存放入map中
metaData.getComment(rstSet);
}
}catch(Exception e){log.error(e);}
finally
{
if(null != rstSet)
try{rstSet.close();}catch(Exception e){log.error(e);}
if(null != statement)
try{statement.close();}catch(Exception e){log.error(e);}
if(null != conn)
try{conn.close();}catch(Exception e){log.error(e);}
}
}

3、我们来看如何进行调用:
ServiceLocator service = ServiceLocator.getInstance();
Jcs01Dao dao = (Jcs01Dao)service.getService("jcore.webframework.common.dao.Jcs01Dao");

Map map = new HashMap();
dao.callBackWithResultSet(new IMetaData()
{
private Map map = null;
public IMetaData setMap(Map map)
{
this.map = map;
return this;
}

public String getSql()
{
return "show full fields from jc02";
}

public Map getResultMap()
{
return map;
}

/***
* 获取注释,并存放入map中
* @param rstSet
*/
public void getComment(ResultSet rstSet)
{
try{
map.put(rstSet.getString(1), new String(rstSet.getString(9).getBytes("ISO8859-1"), "GB2312"));
}catch(Exception e){}
}
// 将返回的结果对象set进去
}.setMap(map));

// 对处理后的结果进行遍历
Iterator it = map.entrySet().iterator();
while(it.hasNext())
{
Map.Entry entry = (Map.Entry)it.next();
System.out.println(entry.getKey() + " = " + entry.getValue());
}

4、MySql注释获取的封装和调用方式:
A、抽取抽象类,为各种数据库的注释获取提供公共部分
import java.util.Map;
/***
* 抽取抽象类出来
* @author 夏天
*
*/
public abstract class BaseMetaData implements IMetaData {

protected Map map = null;
protected String tableName = null;

public BaseMetaData(String szTableName, Map rstMap)
{
this.tableName = szTableName;
map = rstMap;
}

public IMetaData setMap(Map map)
{
this.map = map;
return this;
}

public Map getResultMap()
{
return map;
}

}

B、为MySql单独进行封装:

import java.util.Map;
/***
* MySql 版本: 获取指定的表的列注释到给定的Map中
* @author 夏天
*
*/
public class MetaDataForMySql extends BaseMetaData implements IMetaData {

public MetaDataForMySql(String szTableName, Map rstMap)
{
super(szTableName, rstMap);
}

public String getSql()
{
return "show full fields from " + tableName;
}
/***
* 获取注释,并存放入map中
* @param rstSet
*/
public void getComment(ResultSet rstSet)
{
try{
map.put(rstSet.getString(1), new String(rstSet.getString(9).getBytes("ISO8859-1"), "GB2312"));
}catch(Exception e){}
}
}

C、调用:
ServiceLocator service = ServiceLocator.getInstance();
Jcs01Dao dao = (Jcs01Dao)service.getService("jcore.webframework.common.dao.Jcs01Dao");

Map map = new HashMap();
// 很巧妙的使用了抽象类
dao.callBackWithResultSet(new BaseMetaData("jc02", map)
{
// 如此一来,不同的数据库就不同于下面这两个方法了
public String getSql()
{
return "show full fields from " + tableName;
}

/***
* 获取注释,并存放入map中
* @param rstSet
*/
public void getComment(ResultSet rstSet)
{
try{
map.put(rstSet.getString(1), new String(rstSet.getString(9).getBytes("ISO8859-1"), "GB2312"));
}catch(Exception e){}
}
});
// 或者:
// dao.callBackWithResultSet(new MetaDataForMySql("jc02", map));

// 对处理后的结果进行遍历
Iterator it = map.entrySet().iterator();
while(it.hasNext())
{
Map.Entry entry = (Map.Entry)it.next();
System.out.println(entry.getKey() + " = " + entry.getValue());
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值