mybatis实现拦截器的方法

来源:互联网 发布:淘宝收益怎么提现 编辑:程序博客网 时间:2024/05/29 11:56

mybatis实现拦截器,有两种方法:
第一种:在application里面用到他的plugins注册:

 <property name="plugins">        <array>            <bean class="com.sinosoft.risk.cross.Interceptor.SQLinterceptor">             <!-- 指定SQL方言:oracle、mssql、mysql-->             <property name="dialect" value="oracle"/>                <!-- 拦截Mapper.xml 中定义的SQL-->                <property name="pageSqlId" value="*"/>             <!-- 指定是否展示调整前后的SQL -->             <property name="showsql"   value="1"/>                </bean>        </array>    </property>

第二种:
在classpath:mybatis/mybatis-config.xml里写:
用到的是plugins —— Mybatis的插件,插件可以修改Mybatis内部的运行规则

@Intercepts({@Signature(method=”handleResultSets”, type=ResultSetHandler.class, args={Statement.class}),@Signature(type=StatementHandler.class, method=”prepare”, args={Connection.class})})
public class SQLinterceptor implements Interceptor{
private String dialect =”“;
private String pageSqlId =”“;
private String showsql =”“;
public Object intercept(Invocation invocation) throws Throwable{
//通过invocation获取代理的目标对象
Object target = invocation.getTarget();
if (target instanceof DefaultResultSetHandler) {
DefaultResultSetHandler resultSetHandler = (DefaultResultSetHandler) target;
//利用反射获取到DefaultResultSetHandler的ParameterHandler属性,从而获取到ParameterObject;
//可以获得mybatis里的ParameterType
ParameterHandler parameterHandler = (ParameterHandler)ReflectUtil.getFieldValue(resultSetHandler, “parameterHandler”);
Object parameterObj = parameterHandler.getParameterObject();
ResultSetHandler resultSetHandler1 = (ResultSetHandler) invocation.getTarget();
//通过java反射获得mappedStatement属性值
//可以获得mybatis里的resultype
MappedStatement ms = (MappedStatement)ReflectUtil.getFieldValue(resultSetHandler1, “mappedStatement”);
List rms = ms.getResultMaps();
ResultMap rm = rms != null && rms.size() > 0 ? rms.get(0) : null;
String type = rm != null && rm.getType() != null ? rm.getType().getName() :”“;
System.out.println(“=====================type”+type);
if(“com.sinosoft.risk.cross.Interceptor.MapParam”.equals(type)){
MapParam mapParam=new MapParam();
if(parameterObj instanceof MapParam){
System.out.println(“========instanceof========mapParam====”+mapParam);

                mapParam = (MapParam) parameterObj;            }            System.out.println("================mapParam===="+mapParam);            System.out.println("============parameterObj========"+parameterObj);            Statement stmt = (Statement) invocation.getArgs()[0];            return handleResultSet(stmt.getResultSet(), mapParam);            }        System.out.println("=======================parameterObj=="+parameterObj);    }    if (target instanceof RoutingStatementHandler) {    RoutingStatementHandler handler=(RoutingStatementHandler)target;    // 通过反射获取到当前RoutingStatementHandler对象的delegate属性    StatementHandler delegate=(StatementHandler)ReflectUtil.getFieldValue(handler,"delegate");    // 获取到当前StatementHandler的    // boundSql,这里不管是调用handler.getBoundSql()还是直接调用delegate.getBoundSql()结果是一样的,因为之前已经说过了    // RoutingStatementHandler实现的所有StatementHandler接口方法里面都是调用的delegate对应的方法。    BoundSql boundSql=delegate.getBoundSql();    // 拿到当前绑定Sql的参数对象,就是我们在调用对应的Mapper映射语句时所传入的参数对象    @SuppressWarnings("unused")    MappedStatement mappedStatement=(MappedStatement)ReflectUtil.getFieldValue(delegate,"mappedStatement");    System.out.println("====================mappedStatement======="+mappedStatement.getId());    String srcsql=boundSql.getSql();    if ("1".equals(showsql)) {        System.out.println("处理前==="+srcsql);    }    if ("oracle".equals(dialect)) {        srcsql=srcsql.replace("dbo.", " ");        srcsql=srcsql.replace("isnull", "nvl");        srcsql=srcsql.replace("ISNULL", "nvl");    }    if ("mssql".equals(dialect)) {    }    if ("mysql".equals(dialect)) {    }    ReflectUtil.setFieldValue(boundSql,"sql",srcsql);    if ("1".equals(showsql)) {        System.out.println("处理后==="+srcsql);    }    }    return invocation.proceed();}private Object handleResultSet(ResultSet resultSet, MapParam mapParam) {    System.out.println("======resultSet======================"+resultSet);    // TODO Auto-generated method stub    if (resultSet != null) {        //拿到Key对应的字段        String keyField = (String) mapParam.get(MapParam.KEY_FIELD);        System.out.println("======keyField======================"+keyField);        //拿到Value对应的字段        String valueField = (String) mapParam.get(MapParam.VALUE_FIELD);        if(valueField==null){            valueField=" ";        }        System.out.println("======valueField======================"+valueField);        //定义用于存放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==null?"":valueField);                map.put(key, value);            }        } catch (SQLException e) {            e.printStackTrace();        } finally {            closeResultSet(resultSet);        }        //把封装好的Map存放到List中并进行返回        resultList.add(map);        return map;    }    return null;}
0 1