Olá,
Estou usando iBATIS pela primeira vez num projeto e estou tendo um problema.
No banco de dados os valores booleanos são “S” para true e “N” para false, sendo o campo do tipo CHA(1).
Como isso foge do padrão JDBC, criei um BooleanTypeHandler, que faz a conversão desse valores para o tipo boolean.
Coloquei este typeHandler no SqlMapConfig para que fosse um handler global.
O problema é que o iBATIS não está fazendo a con=versão usando o BooleanTypeHandler automaticamente. Ele só usa esse handler quando eu especifico o atributo typeHandler = BooleanTypeHandler no resultMap ou quando
eu especifico o javaType=boolean.
Estou usando:
-JavaSE 6
-iBATIS 2.3.0.677
-MySQL com o driver mysql-connector-java-5.0.4
-Apache Commons DBCP
Segue os códigos que uso pra ficar mais claro a dúvida:
O TypeHandler que criei:
package persistence;
import java.sql.SQLException;
import com.ibatis.sqlmap.client.extensions.ParameterSetter;
import com.ibatis.sqlmap.client.extensions.ResultGetter;
import com.ibatis.sqlmap.client.extensions.TypeHandlerCallback;
public class BooleanTypeHandler implements TypeHandlerCallback {
private static final String TRUE = "S";
private static final String FALSE = "N";
@Override
public Object getResult(ResultGetter getter) throws SQLException {
String s = getter.getString();
if (TRUE.equalsIgnoreCase(s)) {
return new Boolean (true);
} else if (FALSE.equalsIgnoreCase(s)) {
return new Boolean (false);
} else {
throw new SQLException ("Unexpected value " + s + " found where " + TRUE + " or " + FALSE + " was expected.");
}
}
@Override
public void setParameter(ParameterSetter setter, Object parameter) throws SQLException {
if ((Boolean)parameter) {
setter.setString(TRUE);
} else {
setter.setString(FALSE);
}
}
@Override
public Object valueOf(String s) {
if (TRUE.equalsIgnoreCase(s)) {
return new Boolean (true);
} else {
return new Boolean (false);
}
}
}
Um exemplo de bean que usa o BooleanTypeHandler
package beans;
public class MeuBean {
private Integer id;
private boolean valorBooleanoPrimitivo;
private Boolean valorBooleanoWrapper;
public boolean getValorBooleanoPrimitivo() {
return this.valorBooleanoPrimitivo;
}
public void setValorBooleanoPrimitivo(boolean valor) {
this.valorBooleanoPrimitivo = valor;
}
public Boolean getValorBooleanoWrapper() {
return this.valorBooleanoWrapper;
}
public void setValorBooleanoWrapper(Boolean valor) {
this.valorBooleanoWrapper = valor;
}
}
Parte do SqlMapConfig onde declaro o handler.
*Note que como na declaração do TypeHendler eu especifiquei apenas o javaType, entao esse handler deveria ser aplicado em todo atributo de bean que fosse do tipo boolean (primitivo) ou java.lang.Boolean
<!-- Type Aliases -->
<typeAlias
alias="BooleanTypeHandler"
type="persistence.BooleanTypeHandler"/>
<!-- Type Handlers -->
<typeHandler
callback="BooleanTypeHandler"
javaType="boolean"/>
<sqlMap resource="persistence/MeuBean.xml"/>
Assim funciona, ou seja, o iBATIS usou o BooleanTypeHandler:
*Veja que declarei o typeHandler no resultMap
<sqlMap namespace="MeuBean">
<typeAlias alias="MeuBean" type="beans.MeuBean" />
<resultMap id="getByIdResult" class="MeuBean">
<result property="id" column="idbean"/>
<result property="valorBooleanoPrimitivo" column="valor_primitivo" typeHandler="BooleanTypeHandler"/>
<result property="valorBooleanoWrapper" column="valor_wrapper" typeHandler="BooleanTypeHandler"/>
</resultMap>
<select
id="getById"
parameterClass="int"
resultMap="getByIdResult"
>
SELECT * FROM beans WHERE idbean = #value#
</select>
Assim funciona, ou seja, o iBATIS usou o BooleanTypeHandler:
*Veja que declarei o javaType no resultMap
<sqlMap namespace="MeuBean">
<typeAlias alias="MeuBean" type="beans.MeuBean" />
<resultMap id="getByIdResult" class="MeuBean">
<result property="id" column="idbean"/>
<result property="valorBooleanoPrimitivo" column="valor_primitivo" javaType="boolean"/>
<result property="valorBooleanoWrapper" column="valor_wrapper" javaType="boolean"/>
</resultMap>
<select
id="getById"
parameterClass="int"
resultMap="getByIdResult"
>
SELECT * FROM beans WHERE idbean = #value#
</select>
[color=red]Assim NÃO funciona, ou seja, o iBATIS NÃO usou o BooleanTypeHandler:[/color]
<sqlMap namespace="MeuBean">
<typeAlias alias="MeuBean" type="beans.MeuBean" />
<resultMap id="getByIdResult" class="MeuBean">
<result property="id" column="idbean"/>
<result property="valorBooleanoPrimitivo" column="valor_primitivo"/>
<result property="valorBooleanoWrapper" column="valor_wrapper"/>
</resultMap>
<select
id="getById"
parameterClass="int"
resultMap="getByIdResult"
>
SELECT * FROM beans WHERE idbean = #value#
</select>