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.

Reply via email to