ResultHandler,顾名思义,对返回的结果进行处理,最终得到自己想要的数据格式或类型。也就是说,可以自定义返回类型。下面通过一个例子讲解它的使用方法:
创建Goods实体类:
public class Goods implements Serializable{ /**
*
*/
private static final long serialVersionUID = 1L;
private String id;
private String name;
private String remark;
private String detail;
private BigDecimal price;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public BigDecimal getPrice() {
return price;
}
public void setPrice(BigDecimal price) {
this.price = price;
} }
创建Mapper接口:
public interface GoodsDao { public void selectGoods(ResultHandler resultHandler); }
创建映射文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.yht.mybatisTest.dao.GoodsDao"> <select id="selectGoods" resultType="map">
select price,name from goods
</select> </mapper>
mybatis配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration> <properties resource="db.properties">
<property name="age" value="26" />
</properties> <!-- settings是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 -->
<settings>
<!-- <setting name="localCacheScope" value="STATEMENT"/> -->
<setting name="logImpl" value="STDOUT_LOGGING" />
<setting name="cacheEnabled" value="true"/>
</settings> <typeAliases>
<typeAlias alias="goods" type="com.yht.mybatisTest.entity.Goods" />
</typeAliases> <environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments> <!-- 映射文件 -->
<mappers>
<!-- 通过resource指定Mapper文件 -->
<mapper resource="com/yht/mybatisTest/dao/goods.xml" />
</mappers> </configuration>
根据以上这些代码,我们知道,selectGoods方法的查询结果是List<Map>,假如现在有这么一个需求:想统计价格低于50的书籍有哪些,价格高于50的书籍有哪些,该怎么处理呢?这个时候就用到了ResultHandler,我们创建一个SelectGoodsResultHandler:
/**
* @author chenyk
* @date 2018年9月11日
* 假如price<50的书为低价书,price>=50的书为高价书
*/ public class SelectGoodsResultHandler implements ResultHandler{ private Map<String, List<String>> resultMap = new HashMap<String, List<String>>(); @SuppressWarnings("unchecked")
public void handleResult(ResultContext context) {
if(resultMap.get("lowPrice") == null && resultMap.get("highPrice") == null){
List<String> lowList = new ArrayList<String>();
List<String> highList = new ArrayList<String>();
resultMap.put("lowPrice", lowList);
resultMap.put("highPrice", highList);
}
@SuppressWarnings("unchecked")
Map<String,Object> resultObject = (Map<String, Object>)context.getResultObject();
BigDecimal price = (BigDecimal) resultObject.get("price");
String name = (String) resultObject.get("name");
if(price.intValue() < 50){
((List<String>)resultMap.get("lowPrice")).add(name);
}else{
((List<String>)resultMap.get("highPrice")).add(name);
} } public Map<String, List<String>> getResults(){
return resultMap;
} }
然后写一个测试demo运行:
public class GoodsDaoTest { private static SqlSessionFactory sqlSessionFactory = null; @Test
public void selectGoodsTest(){ SqlSession sqlSession = getSqlSessionFactory().openSession(true);
GoodsDao goodsMapper = sqlSession.getMapper(GoodsDao.class);
SelectGoodsResultHandler resultHandler = new SelectGoodsResultHandler();
goodsMapper.selectGoods(resultHandler);
System.out.println(resultHandler.getResults().toString());; } public static SqlSessionFactory getSqlSessionFactory() {
String resource = "spring-ibatis.xml";
if(sqlSessionFactory == null){
try {
sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources
.getResourceAsReader(resource));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return sqlSessionFactory;
} }
打印的结果:{highPrice=[c++从入门到放弃], lowPrice=[java从入门到放弃, php从入门到放弃, golang从入门到放弃, c从入门到放弃, python从入门到放弃]}
对于源码部分,在SQL的执行过程这篇文章中将进行分析。