关于使用mybitis返回Map集合 而不是List<Map>集合
在网上也找过一些资料,多是拿
sqlMapClient.queryForMap的例子
说事,要不就是用List<Map>的例子来拿分走人
小白的我想找个完整例子偷懒,无奈不遂,只好自己动手丰衣足食了
关于原理,且看如下分解 粗陋之处多多见谅
查看SqlSession 接口
具体关于Map集合的 如下截图
如果直接使用返回的对象为List<Map>
而不是Map
查看其具体实现被DefaultSqlSession SqlSessionManager SqlSessionTemplate 实现
此时调用的为DefaultSqlSession
查看其对应代码
其中关键部分为DefaultResultHandler :处理结果集的地方
查看DefaultMapHandler具体处理 如图所示
其中是实现了ResultHandler的接口
关于ResultHandler 如下图所示
根据以上关键问题已经出来了
在DefaultMapResultHandler 中的结果处理
即如下图部分
所以自己写了个Map结果集的处理
如图所示
部分有重合 将就着看
=============分割线
代码部分
先贴下相关配置
<bean id="sqlSessionFactory_bit" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource_bit" />
<property name="configLocation" value="classpath:bit-sql-map-config.xml" />
</bean>
<bean id="userDAO"
class="UserDAO">
<property name="sqlSessionFactory" ref="sqlSessionFactory_bit" />
</bean>
Sql语句
<select id="getOsListByDate" parameterType="BaseCriteria " resultType="java.util.Map">
select OS ,OS_COUNT,CREATED_DATE
from VIEW_USER_OS
where CREATED_DATE=#{createdDate}
<if test="isPaging">
limit #{startIndex}, #{offset}
</if>
</select>
先列下代码
/**
* 条件查询
* @author skyyan
*
*/
public class BaseCriteria {
private static final long serialVersionUID=7580485976991375195L;
private int pageSize;
private int pageNo;
private String createdDate;
private boolean isPaging;//是否分页如果为true则表示分页,如果为 false则表示不分页
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize=pageSize;
}
public int getPageNo() {
return pageNo;
}
public void setPageNo(int pageNo) {
this.pageNo=pageNo;
}
public int getStartIndex() {
if(pageNo<=0){
this.pageNo=1;
}
return (pageNo - 1) * pageSize;
}
public int getOffset() {
return pageSize;
}
public boolean isPaging() {
return isPaging;
}
public void setPaging(boolean isPaging) {
this.isPaging = isPaging;
}
public void setCreatedDate(String createdDate){
this.createdDate=createdDate;
}
public String getCreatedDate() {
return createdDate;
}
}
======Map 结果集处理类
import java.util.Map;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
/***
* mybitis 返回Map对象处理
* @author skyyan
*
* @param <K>
* @param <V>
*/
@SuppressWarnings({"unchecked","rawtypes"})
public class MapResultHandler<K, V> implements ResultHandler {
private final Map mappedResults;
private final String mapKey;
private final ObjectFactory objectFactory;
private final ObjectWrapperFactory objectWrapperFactory;
private final String mapValue;
public MapResultHandler(String mapKey, String mapValue,ObjectFactory objectFactory,
ObjectWrapperFactory objectWrapperFactory) {
this.objectFactory = objectFactory;
this.objectWrapperFactory = objectWrapperFactory;
this.mappedResults = ((Map) objectFactory.create(Map.class));
this.mapKey = mapKey;
this.mapValue=mapValue;
}
public void handleResult(ResultContext context) {
Object value = context.getResultObject();
Object key=null;
if(value instanceof Map){
Map<K,V> temp=(Map<K,V>)value;
value=temp.get(this.mapValue);
key=temp.get(this.mapKey);
}
if(key==null){
MetaObject mo = MetaObject.forObject( context.getResultObject(), this.objectFactory,
this.objectWrapperFactory);
key = mo.getValue(this.mapKey);
}
this.mappedResults.put(key, value);
}
public Map<K, V> getMappedResults() {
return this.mappedResults;
}
}
**************DAO实现
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.executor.result.DefaultResultContext;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.RowBounds;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import BaseCriteria;
import MapResultHandler;
/***
*
* @author skyyan
*
* @param <K>
* @param <V>
*/
public class BaseDAO<K,V> extends SqlSessionDaoSupport{
/****
* 返回Map对象<String,String>
* @param paramString 执行的语句 如bit_clientUser_statistics.getOsListByDate
* @param criteria 参数
* @param mapKey 所返集合的key;此名字与查询语句中的列名对应,表示已那个字段作为key
* @param mapValue 所返集合的value,此名字与查询语句中的列名对应,表示已那个字段作为value
* @return
*/
public Map<K,V> getMap(String paramString,BaseCriteria criteria,String mapKey,String mapValue){
ObjectFactory objectFactory = this.getSqlSession().getConfiguration()
.getObjectFactory();
List list = this.getSqlSession().selectList(paramString, criteria,RowBounds.DEFAULT);
ObjectWrapperFactory objectWrapperFactory = this.getSqlSession()
.getConfiguration().getObjectWrapperFactory();
MapResultHandler mapResultHandler = new MapResultHandler(
mapKey,mapValue, objectFactory, objectWrapperFactory);
DefaultResultContext context = new DefaultResultContext();
for (Iterator i$ = list.iterator(); i$.hasNext();) {
Object o = i$.next();
context.nextResultObject(o);
mapResultHandler.handleResult(context);
}
Map selectedMap = mapResultHandler.getMappedResults();
return selectedMap;
}
}
可以直接使用
返回结果
注意:但是此时需要注意一些排重问题,因为这个是统计用 所以不存在key重复的情况,所以看具体应用情况,在具体自行处理