myBatis mapper 返回任意类型

<select id="select" parameterType="String" resultType="T">
感谢两位的回答,我现在的要求不是说我不会用mybatis,我是会一些基础的东西,我现在想对mybatis 框架进行封装,所以想要一些 相关mybatis 的动态写法,希望朋友们,多多指教!

定义一个MapInterceptor用于拦截对应的结果集返回一个Map。
其代码如下所示:
@Intercepts(@Signature(method="handleResultSets", type=ResultSetHandler.class, args={Statement.class}))
public class MapInterceptor implements Interceptor {

/* (non-Javadoc)
* @see org.apache.ibatis.plugin.Interceptor#intercept(org.apache.ibatis.plugin.Invocation)
*/
public Object intercept(Invocation invocation) throws Throwable {
//通过invocation获取代理的目标对象
Object target = invocation.getTarget();
//暂时ResultSetHandler只有FastResultSetHandler这一种实现
if (target instanceof FastResultSetHandler) {
FastResultSetHandler resultSetHandler = (FastResultSetHandler) target;
//利用反射获取到FastResultSetHandler的ParameterHandler属性,从而获取到ParameterObject;
ParameterHandler parameterHandler = ReflectUtil.getFieldValue(resultSetHandler, "parameterHandler");
Object parameterObj = parameterHandler.getParameterObject();
//判断ParameterObj是否是我们定义的MapParam,如果是则进行自己的处理逻辑
if (parameterObj instanceof MapParam) {//拦截到了
MapParam mapParam = (MapParam) parameterObj;
//获取到当前的Statement
Statement stmt = (Statement) invocation.getArgs()[0];
//通过Statement获取到当前的结果集,对其进行处理,并返回对应的处理结果
return handleResultSet(stmt.getResultSet(), mapParam);
}
}
//如果没有进行拦截处理,则执行默认逻辑
return invocation.proceed();
}

/**
* 处理结果集
* @param resultSet
* @param mapParam
* @return
*/
private Object handleResultSet(ResultSet resultSet, MapParam mapParam) {
// TODO Auto-generated method stub
if (resultSet != null) {
//拿到Key对应的字段
String keyField = (String) mapParam.get(MapParam.KEY_FIELD);
//拿到Value对应的字段
String valueField = (String) mapParam.get(MapParam.VALUE_FIELD);
//定义用于存放Key-Value的Map
Map<Object, Object> map = new HashMap<Object, Object>();
//handleResultSets的结果一定是一个List,当我们的对应的Mapper接口定义的是返回一个单一的元素,并且handleResultSets返回的列表
//的size为1时,Mybatis会取返回的第一个元素作为对应Mapper接口方法的返回值。
List<Object> resultList = new ArrayList<Object>();
try {
//把每一行对应的Key和Value存放到Map中
while (resultSet.next()) {
Object key = resultSet.getObject(keyField);
Object value = resultSet.getObject(valueField);
map.put(key, value);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeResultSet(resultSet);
}
//把封装好的Map存放到List中并进行返回
resultList.add(map);
return resultList;
}
return null;
}

/**
* 关闭ResultSet
* @param resultSet 需要关闭的ResultSet
*/
private void closeResultSet(ResultSet resultSet) {
try {
if (resultSet != null) {
resultSet.close();
}
} catch (SQLException e) {

}
}

/* (non-Javadoc)
* @see org.apache.ibatis.plugin.Interceptor#plugin(java.lang.Object)
*/
public Object plugin(Object obj) {
return Plugin.wrap(obj, this);
}

/* (non-Javadoc)
* @see org.apache.ibatis.plugin.Interceptor#setProperties(java.util.Properties)
*/
public void setProperties(Properties props) {

}

}
温馨提示:答案为网友推荐,仅供参考
第1个回答  2020-01-02
虽然这个问题是N年前的了,但是我最近也用到了类似的功能,刚好也误打误撞碰巧做出来了,所以还是说一下我的解决方案吧,如有可改之处,敬请各位大佬不吝赐教。
首先,需求是,定义一个动态的方法,查询的时候根据查询语句直接查询,所以和楼主说的一样,我的select标签是这样的:
<select id="select" parameterType="java.lang.String" resultType="AllResultMap">
${_parameter}
</select>
其中,${_parameter}最好和我写的一样,因为我试过_param,发现报错了,我也不知道为什么,但是这么写是可以的。另外AllResultMap的具体实现为:
<resultMap type="java.util.Map" id="AllResultMap">
</resultMap>
这样,在XXXmapper.java文件里面,接口只需要这么写:
public LinkedList<Map> select(String _parameter);
这样最终查询出来的结果就是一个list里面有很多个map对象,而map中的key就是你的列名,value就是数据库一条record对应的值。然后剩下的就是按照你自己的意愿对map进行解析、封装成你自己想要的类的对象就好了。
第2个回答  2014-08-25
可以知道resultTyp="map",查询语句类似 SELECT name AS nameKey,age AS ageKey FROM table;返回用一个Hashmap接收,对应的可以map.get(nameKey);map.get(ageKey);就可以获得对应的值,然后再封装吧。追问

我目前的写法是

SELECT
*
FROM
users
WHERE
userId = 'userId'
可是结果,让我无法理解 本来应该是 userId userName 都有值,结果 就只把userId 的值 以字符串的形式给我返回来。

本回答被提问者采纳
第3个回答  2014-08-25
不行,myBatis要么你明确返回类型,配置某个类,要么你就返回HashMap。列表就用List<HashMap>追问

那怎么才能让它 根据我传入的类型,做为返回类型
例如 我传入 A 类 查询结果后 返回 A类

追答

http://zhidao.baidu.com/link?url=9NsAMlQyEjBT6Hk9wfLzQXogP4OzncU60LB4QGsiHisZJzJjD9X0yJC6gA-mZlejwPoZItXlcldSDKQYaiV8Eq

本回答被网友采纳
第4个回答  2014-08-25
你是想提供答案,还是求助,求助的话遇到什么问题追问

你好,刚才着急提交实在不好意思,我想求助
mybatis在查询时可不可以不指定返回类型,用T或Object目前我试过了,不行

相似回答