DAO接口方法使用@Param传递参数给Mapper.xml里面的SQL
1、如果使用@Param传递多个参数,则Mapper.xml里面的SQL不能被声明为statementType=”STATEMENT”,否则会抛出一下异常:
### Error querying database. Cause: java.sql.SQLException:
The number of parameter values set or registered does not match the number of parameters.
动态传递数据库或者是表名给SQL应使用${},而不是#{}
<!-- 根据Key统计符合条件的记录数,${envLibMap.Y}为hashmap,里面的键值Y对应的值是数据库名称 -->
<select id="queryCountByKey" resultType="int">
SELECT COUNT(*)
FROM ${envLibMap.Y}.USRINF USRINF
WHERE USRINF.usridk = #{key} <include refid="actiFlag" />
</select>
1、数据库名或者是表名不能用?占位传递后编译成SQL,所以必须使用${}直接传值形式,而不是#{}占位符,否则无法映射过去,抛出一下异常:
### Error querying database. Cause: java.sql.SQLException: [SQL0104] 标记?无效。
有效标记为( NEW FINAL TABLE UNNEST LATERAL XMLTABLE<IDENTIFIER>。
### SQL: SELECT COUNT(*) FROM ?.USRINF USRINF
WHERE USRINF.usridk = ?
and USRINF.usract = ?
### Cause: java.sql.SQLException: [SQL0104] 标记?无效。
有效标记为( NEW FINAL TABLE UNNEST LATERAL XMLTABLE<IDENTIFIER>。
2、Mapper.xml里面的SQL也不需要声明为statementType=”STATEMENT”,和其它情况默认使用即可。
3、有数学运算的参数传值问题
#{对象.xxx} * tableField --√
tableField * ${对象.xxx} --√
tableFiedl * #{对象.xxx} --×
DAO接口与Mapper.xml方法对应不上
调用DAO接口的方法时,抛出如下异常:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):
cn.markwins.yinfor.cas.dao.IUserDao.queryCountByKey
1、首先检查关于Mybatis的Mapper.xml文件位置的配置,这里配置不对,一般在Web启动时就会报错了,但也经常容易忽略此问题的排查
<!-- myBaites sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="configLocation" value="classpath:sqlMapConfig.xml" />
<property name="mapperLocations" value="classpath:cn/markwins/yinfor/*/mapper/*Mapper.xml" />
<property name="dataSource" ref="dyDataSource" />
</bean>
<!-- myBaites Mapper扫描器配置 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.markwins.yinfor.*.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
2、检查Mapper.xml的namespace,是否和对应的DAO接口名称一致,如下
<mapper namespace="cn.markwins.yinfor.cas.dao.IUserDaoX">
3、检查DAO接口里面的方法名和Mapper.xml里面对应的sql id是否一致,且Mapper.xml标准是sql id不能重复。
Mapper.xml里面的动态SQL问题
1、单个字符test判断注意问题点
如下示例:不能写成 test=”relType == ‘P’”,应该写成test=’relType == “S”’,否则会报java.lang.NumberFormatException: For input string: “单字符参数”
<if test="relType != null">
<choose>
<when test='relType == "P"'>
AND ITMRST.csts3 = '1'
</when>
<when test='relType == "R"'>
AND ITMRST.mtrg = '1'
</when>
<otherwise>
AND ITMRST.csts2 = '1'
</otherwise>
</choose>
</if>
2、mapper xml的动态sql test日期、布尔类型 != ‘’,类型不匹配
对于insert、upate的动态sql,我们一般会比较直不为空白才去做相应数据库栏位的值写入,但是经常将日期、布尔与 ”去比较,造成类型不匹配
<!-- 修改 -->
<update id="update">
UPDATE ${envLibMap.Y}.XAENV XAENV
<trim prefix="SET" suffix="WHERE XAENV.envidk = #{voBean.envidk}" suffixOverrides=",">
<if test="voBean.envopn != null and voBean.envopn != ''">XAENV.envopn = #{voBean.envopn},</if>
<if test="voBean.envstk != null and voBean.envstk != ''">XAENV.envstk = #{voBean.envstk},</if>
<if test="voBean.clodte != null and voBean.clodte != ''">XAENV.clodte = #{voBean.clodte},</if> <!-- 日期类型 -->
</trim>
</update>
这里的voBean.clodte是日期类型,voBean.clodte != ”,会抛如下异常:
### Cause: java.lang.IllegalArgumentException: invalid comparison: java.util.Date and java.lang.String
应将 and voBean.clodte != ”去掉,只判断 !=null即可,类似的还有Boolean、Integer与 ”去比较,都会引起此错误。