须要给activiti的query接口新增查询条件,可是activiti内部具体基本都是基于实现类,没法扩展。只好使用nativequery接口写sql。而后就想到直接copy复用activiti内部的sql语句。node
include标签只能本身用方法字符串去拼接,动态逻辑标签仍是能够用mybatis内部实现去解析。另外查询类get的时候会调用到activiti的查询操做,因此在外层还须要加上activiti的壳(使用命令模式,中间加入拦截链,执行操做必须通过拦截链如:日志,事务,上下文,缓存批处理): procEngineCfg.getCommandExecutor().execute(command)
。sql
主要的代码整理出来看成备忘:缓存
String XML_PREFIX="<mapper namespace=\"\"><select id=\"temp\">"; String XML_SUFFIX="</select></mapper>"; //得到mybatis的Configuration Configuration myCfg=procEngineCfg.getMybatisConfiguraton(); //继承HashMap,把xxx:activiti的查询类实例用BeanWrapper包装 ContextMap param=new ContextMap(xxx); //另外查询条件 param.put("yyy","zzz"); //得到sql脚本 String sqlScript=getSelectTaskByQueryCriteria(); //加载sql的xml,解析${},生成XNode(一个Dom API中的Node接口的扩展类) XPathParser parser=new XPathParser(new ByteArrayInputStream((XML_PREFIX+sqlScript+XML_SUFFIX).getBytes()), false); XNode xnode=parser.evalNode("/mapper/select"); //从XNode解析xml中的每一个标签(如trim,if标签),把XNode转成sqlNode,生成SqlSource XMLScriptBuilder builder = new XMLScriptBuilder(myCfg, xnode, Map.class); SqlSource taskByQueryCriteriaSS=builder.parseScriptNode(); //sqlSource里的sqlNode解析逻辑标签后生成BoundSql 带#{}的sql 和 参数 //BoundSql封装mybatis最终产生sql的类,包括sql语句,参数,参数源数据等参数 BoundSql boundSql=taskByQueryCriteriaSS.getBoundSql(param); //获取参数值 Map<String,Object> params=new LinkedHashMap<String, Object>(); Object parameterObject=boundSql.getParameterObject(); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); if (parameterMappings == null) return params; //循环设参数 for (int i = 0; i < parameterMappings.size(); i++) { ParameterMapping parameterMapping = parameterMappings.get(i); if (parameterMapping.getMode() == ParameterMode.OUT) continue; //若是不是OUT,才设进去 Object value; String propertyName = parameterMapping.getProperty(); if (boundSql.hasAdditionalParameter(propertyName)) //如有额外的参数, 设为额外的参数 issue #448 ask first for additional params value = boundSql.getAdditionalParameter(propertyName); else if (parameterObject == null) //若参数为null,直接设null value = null; else if (myCfg.getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass())) //若参数有相应的TypeHandler,直接设object value = parameterObject; else { //除此之外,MetaObject.getValue反射取得值设进去 MetaObject metaObject = myCfg.newMetaObject(parameterObject); value = metaObject.getValue(propertyName); } params.put(String.valueOf(i), value); } class ContextMap extends HashMap<String, Object> { private static final long serialVersionUID = 1L; private BeanWrapper beanWrapper; public ContextMap(Object obj) { beanWrapper= PropertyAccessorFactory.forBeanPropertyAccess(obj); } @Override public Object get(Object key) { String strKey = (String) key; if (super.containsKey(strKey)) return super.get(strKey); if (beanWrapper != null) return beanWrapper.getPropertyValue(strKey); return null; } }