首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 其他教程 > 开源软件 >

Mybatis回到Map的一种实现

2013-10-16 
Mybatis返回Map的一种实现public class MapParam extends HashMapString, Object {/** **/private stati

Mybatis返回Map的一种实现
public class MapParam extends HashMap<String, Object> {/** * */private static final long serialVersionUID = 1L;/** * 作为Key的字段对应MapParam的Key */public static final String KEY_FIELD = "mapKeyField";/** * 作为Value的字段对应MapParam的Key */public static final String VALUE_FIELD = "mapValueField";public MapParam() {}/** * 指定keyField和valueField * @param keyField Map中key对应的字段 * @param valueField Map中value对应的字段 */public MapParam(String keyField, String valueField) {this.put(KEY_FIELD, keyField);this.put(VALUE_FIELD, valueField);}}

@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;//获取到当前的StatementStatement 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 stubif (resultSet != null) {//拿到Key对应的字段String keyField = (String) mapParam.get(MapParam.KEY_FIELD);//拿到Value对应的字段String valueField = (String) mapParam.get(MapParam.VALUE_FIELD);//定义用于存放Key-Value的MapMap<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) {}}

?

public class ReflectUtil {/** * 利用反射获取指定对象的指定属性 * @param obj 目标对象 * @param fieldName 目标属性 * @return 目标属性的值 */@SuppressWarnings("unchecked")public static <T> T getFieldValue(Object obj, String fieldName) {Object result = null;Field field = ReflectUtil.getField(obj, fieldName);if (field != null) {field.setAccessible(true);try {result = field.get(obj);} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return (T)result;}/** * 利用反射获取指定对象里面的指定属性 * @param obj 目标对象 * @param fieldName 目标属性 * @return 目标字段 */private static Field getField(Object obj, String fieldName) {Field field = null;for (Class<?> clazz=obj.getClass(); clazz != Object.class; clazz=clazz.getSuperclass()) {try {field = clazz.getDeclaredField(fieldName);break;} catch (NoSuchFieldException e) {//这里不用做处理,子类没有该字段可能对应的父类有,都没有就返回null。}}return field;}/** * 利用反射设置指定对象的指定属性为指定的值 * @param obj 目标对象 * @param fieldName 目标属性 * @param fieldValue 目标值 */public static void setFieldValue(Object obj, String fieldName,String fieldValue) {Field field = ReflectUtil.getField(obj, fieldName);if (field != null) {try {field.setAccessible(true);field.set(obj, fieldValue);} catch (IllegalArgumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IllegalAccessException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}

<plugins> <plugin interceptor="com.tiantian.mybatis.interceptor.MapInterceptor"/> </plugins>

?

<bean id="sqlSessionFactory" name="code"> <select id="find" resultType="map" parameterType="MapParam"> select code, name from t_city </select>

public interface CityMapper extends SuperMapper { public Map<Object, Object> find(MapParam param); }

@Test public void testMap() { MapParam param = new MapParam("code", "name"); Map<Object, Object> result = cityMapper.find(param); System.out.println(result); }

?????? 在这篇博客中,我只是介绍使用Mybatis拦截器实现Mybatis查询返回Map的这么一种方法,里面的代码考虑是比较粗糙的,想要在使用Mybatis拦截器拦截到ResultSetHandler的handleResultSets方法,对ResultSet做更加严谨的处理的话,推荐参考Mybatis ResultSetHandler接口的实现类FastResultSetHandler关于handleResultSets(Statement stmt)的实现。

1 楼 nichlas_yu 2013-09-16   挺好的,学习了。 2 楼 234390216 2013-09-16   nichlas_yu 写道挺好的,学习了。
之前看到有人问这样的问题,刚好昨天有点空,就弄了下,希望对需要的人有帮助。 3 楼 javajiao 2013-09-16   好文,支持! 4 楼 非法用户 2013-09-16   用mybatis的select(String statement, Object parameter, ResultHandler handler);方法会很简单 5 楼 在世界的中心呼喚愛 2013-09-16   这样的需求很奇怪!!!!!
楼主这种方法不错,通过拦截器拦截符合条件的数据,在进行处理!! 6 楼 234390216 2013-09-17   非法用户 写道用mybatis的select(String statement, Object parameter, ResultHandler handler);方法会很简单
道理是一样的。 7 楼 yangjun82101 2013-10-11  

热点排行