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的执行过程这篇文章中将进行分析。