support the parameter('#') in the replace string('$') and the result column of result map(class) not existed in select statement. ---------------------------------------------------------------------------------------------------------------------------------
Key: IBATIS-480 URL: https://issues.apache.org/jira/browse/IBATIS-480 Project: iBatis for Java Issue Type: Improvement Components: SQL Maps Affects Versions: 2.3.0 Environment: iBatis 2.3.0 Reporter: KwonKee Lim Priority: Minor 1. support the parameter('#') in the replace string('$') in the following sqlmap <typeAlias alias="Test" type="...model.impl.TestImpl"/> <resultMap id="TestResult" class="Test"> <result column="COL1" jdbcType="VARCHAR" property="COL1" javaType="String"/> <result column="COL2" jdbcType="VARCHAR" property="COL2" javaType="String"/> <result column="COL3" jdbcType="DECIMAL" property="COL3" javaType="long" nullValue="0"/> <result column="COL4" jdbcType="DECIMAL" property="COL4" javaType="long" nullValue="0"/> </resultMap> <select id="getTestsBySQL" parameterClass="Map" resultMap="TestResult"> SELECT COL1,COL2,COL3 FROM Test WHERE $SQL$ <isPropertyAvailable property="COL2" prepend="AND ">COL2 = #COL2#</isPropertyAvailable> </select> if the replace string '$SQL$' is 'COL1=#COL1#', the result sql string is '... WHERE COL1=#COL1#' .. ' . The sql exception occured , because the '#COL1#' in 'COL1=#COL1#' not replaced to '?'. That is, the parameter('#') is not supperted in dynamic sql('$'). My idea is that modify the "com.ibatis.sqlmap.engine.mapping.sql.dynamic.DynamicSql" class 's processBodyChildren method for dynamic sql('$'). private void processBodyChildren(RequestScope request, SqlTagContext ctx, Object parameterObject, Iterator localChildren, PrintWriter out) { while (localChildren.hasNext()) { SqlChild child = (SqlChild) localChildren.next(); if (child instanceof SqlText) { SqlText sqlText = (SqlText) child; String sqlStatement = sqlText.getText(); // CUSTOMIZE for support '#' in '$' by kklim 2007-12-26 <== here // if the '$' is included , parsing one more. if (SimpleDynamicSql.isSimpleDynamicSql(sqlStatement)) { sqlStatement = new SimpleDynamicSql(delegate, sqlStatement).getSql(request, parameterObject); sqlText.setPostParseRequired(true); } // CUSTOMIZE end ... What do you think about this idea? 2. support the result column of result map(class) not existed in select statement. In the above sql map, the select statement's column is missing the column 'COL4', but the result map present the column 'COL4'. In case, The select statement 's columns in runtime is defined. a column presented by the result map is able to be missed. My idea is that modify the "com.ibatis.sqlmap.engine.mapping.result.BasicResultMap" class. 1) define the member variable for cached the resultsetmetadata's column(s) // CUSTOMIZE does not exist column in resultmap for result set private ThreadLocal rsmd = new ThreadLocal(); 2) to initialize the the resultsetmetadata's column(s), modify the "getResults" method // CUSTOMIZE initialize the columns of the resultset if(rsmd.get() == null){ ResultSetMetaData md = rs.getMetaData(); int count = md.getColumnCount(); Map columnNameMap = new HashMap(count); for(int i=0; i<count; i++){ String columnName = md.getColumnName(i+1); columnNameMap.put(columnName, (i+1)); } rsmd.set(columnNameMap); } // CUSTOMIZE END 3) to get the result's column , if the result map(class)'s columns does not exists, skip the getting the result colum in getNestedSelectMappingValue method // CUSTOMIZE if not exist the column(s) of query, skip the column of the result map(class) Map columnNameMap = (Map)rsmd.get(); if( columnNameMap == null || columnNameMap.containsKey(mapping.getColumnName())){ result = ResultLoader.loadResult(client, statementName, parameterObject, targetType); } // CUSTOMIZE END and in getPrimitiveResultMappingValue method protected Object getPrimitiveResultMappingValue(ResultSet rs, BasicResultMapping mapping) throws SQLException { Object value = null; // CUSTOMIZE if not exist the column(s) of query, skip the column of the result map(class) Map columnNameMap = (Map)rsmd.get(); if( columnNameMap != null && !columnNameMap.containsKey(mapping.getColumnName())){ return value; } ... What do you think about this idea? -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online.