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.