MyBatis查询数据装配成键值对
jackhb1999 人气:0描述:
MyBatis 直接查询出的格式是 List 套 Map 的结构,当然利用 Stream 流进行转换也非常便捷,但如果这样的操作很多的话,不如利用 MyBatis 提供的 ResultHandler 接口进行实现,做成工具类使用。
此外,如果用 MyBatis 提供的 @MapKey ,也只是对应值有冗余,因为 MapKey取一个字段为键,取出的所有字段为值。
操作:
1. 实现 ResultHandler 接口
/** * 用于MyBatis查询库表中两列映射为键值对 */ @Component public class MapResultHandler implements ResultHandler { private final HashMap mapResults = new HashMap<String,String>(); private String key; private String value; @Override public void handleResult(ResultContext resultContext) { HashMap map = (HashMap)resultContext.getResultObject(); mapResults.put(map.get("key"), map.get("value")); } /** * 返回映射 * @return 结果 */ public HashMap getMapResults() { return mapResults; } /** * @param key key * @param value value */ public MapResultHandler(String key, String value) { this.key = key; this.value = value; } /** * 空构造 */ public MapResultHandler() { } }
2. 对应 DAO 层
对应 mapper 查询接口中,在查询的方法里将 ResultHandler 实现类(MapResultHandler)以参数形式传入。
由于使用实现类拿取装配好的Map,此处的返回类型为 void 。
/** * 提取<图片名,创建时间>的Map,对应创建时间进行处理 * @param imageLength 上传图片的个数 * @return */ void selectImageNameAndCreatetime(MapResultHandler mapResultHandler, int imageLength);
对应 xml 文件中,定义返回类型为 map 。
其中注意给我们需要的键值取别名,对应别名与 ResultHandler 实现类(MapResultHandler)中定义的相对应,这样在ResultHandler 实现类(MapResultHandler)中 map.get() 才能取到。
<select id="selectImageNameAndCreatetime" resultType="map"> select name as 'key',time as 'value' from house_pic_info order by id desc limit #{imageLength} </select>
3. 使用
先实例化 ResultHandler 实现类(MapResultHandler),作为参数传入。
取 Map 时依然从 ResultHandler 实现类(MapResultHandler)中取。
MapResultHandler handler = new MapResultHandler(); housePicInfoMapper.selectImageNameAndCreatetime(handler, length); Map imageMap = handler.getMapResults();
思考:对应 ResultHandler 接口只需实现一个 handleResult 方法,在 MyBatis 中 @MapKey 的实现也应该是有对应实现。
/** * MyBatis 中 DefaultMapResultHandler 实现 * @author Clinton Begin */ public class DefaultMapResultHandler<K, V> implements ResultHandler<V> { private final Map<K, V> mappedResults; private final String mapKey; private final ObjectFactory objectFactory; private final ObjectWrapperFactory objectWrapperFactory; private final ReflectorFactory reflectorFactory; @SuppressWarnings("unchecked") public DefaultMapResultHandler(String mapKey, ObjectFactory objectFactory, ObjectWrapperFactory objectWrapperFactory, ReflectorFactory reflectorFactory) { this.objectFactory = objectFactory; this.objectWrapperFactory = objectWrapperFactory; this.reflectorFactory = reflectorFactory; this.mappedResults = objectFactory.create(Map.class); this.mapKey = mapKey; } @Override public void handleResult(ResultContext<? extends V> context) { final V value = context.getResultObject(); final MetaObject mo = MetaObject.forObject(value, objectFactory, objectWrapperFactory, reflectorFactory); // TODO is that assignment always true? final K key = (K) mo.getValue(mapKey); mappedResults.put(key, value); } public Map<K, V> getMappedResults() { return mappedResults; } }
加载全部内容