mybatis的ResultHandler

723 阅读2分钟

“携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第9天,点击查看活动详情

ResultHandler

结果处理器。做处理完的类型转换的结果,进行后置处理。

ResultHandler接口只有一个方法handleResult,这个方法的作用是: 我们可以在这里添加处理每一条(sql查询返回的每一条数据)数据的逻辑。

package org.apache.ibatis.session;

/**
 * @author Clinton Begin
 */
public interface ResultHandler<T> {

  void handleResult(ResultContext<? extends T> resultContext);

}

ResultContext

结果值上下文,存储结果值、总数等。

package org.apache.ibatis.session;

/**
 * @author Clinton Begin
 */
public interface ResultContext<T> {

  T getResultObject();

  int getResultCount();

  boolean isStopped();

  void stop();

}

ResultHandler对返回的结果进行处理,最终得到自己想要的数据格式或类型,可以自定义返回类型。
下面的例子就是对返回的时间类型的数据进行格式化:

public class LinkedMapHandler implements ResultHandler<LinkedHashMap<String,Object>> {
    private List<LinkedHashMap<String,Object>> resultMapList= new ArrayList<>();

    @Override
    public void handleResult(ResultContext<? extends LinkedHashMap<String, Object>> resultContext) {
        LinkedHashMap<String,Object> map = resultContext.getResultObject();
        if (ObjectUtils.isNotEmpty(map)){
            for (String str : map.keySet()){
                Object data = map.get(str);
                if (data instanceof Date){
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                    String format = sdf.format(data);
                    map.put(str,format);
                }
            }
        }
        resultMapList.add(map);
    }

    public List<LinkedHashMap<String, Object>> getResultMapList() {
        return resultMapList;
    }
}

Dao层代码:

public interface RdrQueryDao {

    @ResultType(LinkedHashMap.class)
    @SelectProvider(type = ParamSqlGen.class, method = "generateParamSql")
    void selectParam(String param,LinkedMapHandler<Object> resultHandler);

调用selectParam方法,返回处理后的结果集:

LinkedMapHandler<Object> resultHandler = new LinkedMapHandler<>();
rdrQueryDao.selectMultiField(param, resultHandler);
List<LinkedHashMap<String, Object>> allList = resultHandler.getResultMapList();

编写sql语句:

public class ParamSqlGen {
    public String generateParamSql(String param) {
        String sqlTemplate = "select * " +
                "from table " +
                "where %s >0;";
        return String.format(sqlTemplate, param);
    }
}

ResultHandler和ResultSetHandler的区别

ResultSetHandler

ResultSetHandler源代码:
其中最主要的是handlerResultSets,它负责查询结果的处理。

package org.apache.ibatis.executor.resultset;

import java.sql.CallableStatement;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import org.apache.ibatis.cursor.Cursor;

/**
 * @author Clinton Begin
 */
public interface ResultSetHandler {

  <E> List<E> handleResultSets(Statement stmt) throws SQLException;

  <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException;

  void handleOutputParameters(CallableStatement cs) throws SQLException;

}

ResultSetHandler是mybatis的关键类之一,用于对jdbc返回的ResultSet进行映射处理,其中包括列前缀处理,逻辑分页,鉴别器(Discriminator,基于值实现动态映射列)处理等等。
ResultHandler,它用来对每行记录映射或处理,典型的比如二次过滤或脱敏处理,都可以在这里处理,当然也可以通过插件,只不过在这里处理从性能上看最佳。