xxMapper中传入自定义参数查询
1、xxMapper中传入自定义参数查询
EnterpriseBaseMapper
EnterpriseBase selectByPrimaryKey(String enterpriseId);
String selectEnterpriseId(String enterpriseUscc);
对应的xml查询语句EnterpriseBaseMapper.xml
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List"/>
from t_enterprise_base_info
where ENTERPRISE_ID = #{enterpriseId,jdbcType=VARCHAR} AND status=101001
</select>
<select id="selectEnterpriseId" parameterType="java.lang.String" resultType="java.lang.String">
select
ENTERPRISE_ID
from t_enterprise_base_info
where ENTERPRISE_USCC = #{enterpriseUscc,jdbcType=VARCHAR} AND status=101001
</select>
但是下面的selectEnterpriseId方法却查询不到,报了nested exception is org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'enterpriseUscc' in 'class java.lang.String'
错误。经过对比测试,个人认为在<if test="enterpriseUscc!=null">
这一行报错,因为传入的是一个String类型的参数,而java.lang.String类中并没有对enterpriseUscc进行解释。但是如果传入的是一个map类型的参数,因为map是key-value形式,key为enterpriseUscc,value为值,enterpriseUscc在map中相当于定义了,<if test="enterpriseUscc!=null">
这一行代码能认识所以不报错。
<select id="selectEnterpriseId" parameterType="java.lang.String" resultType="java.lang.String">
SELECT
ENTERPRISE_ID
FROM
t_enterprise_base_info
<where>
STATUS = 101001
<if test="enterpriseUscc!=null">
AND ENTERPRISE_USCC = #{enterpriseUscc,jdbcType=VARCHAR}
</if>
</where>
</select>
要想以上的代码不报错,需要稍微修改一下方法,添加@Param("enterpriseUscc")
对enterpriseUscc进行解释即可。
String selectEnterpriseId(@Param("enterpriseUscc") String enterpriseUscc);
2、传入的字段还是原来的字段
如果传入的字段还是原来的字段,但是传入的类型与数据库表中的字段类型对应不上,就不要再加上jdbcType=VARCHAR
限制了(虽然传入的字段名还是原来的,但是意义不一样了,完全可以自定义一个新的参数名代替)。例如如下的orderStatus
字段,如果使用AND V.ORDER_STATUS in (${orderStatus, jdbcType=VARCHAR})
就会报错
<select id="count" parameterType="java.util.Map" resultType="java.lang.Integer">
SELECT COUNT(*)
FROM v_order V
<where>
<if test="operateStartTime!=null">
AND <![CDATA[ V.OPERATE_TIME >= #{operateStartTime, jdbcType=TIMESTAMP}]]>
</if>
<if test="operateEndTime!=null">
AND <![CDATA[ V.OPERATE_TIME <= #{operateEndTime, jdbcType=TIMESTAMP}]]>
</if>
<if test="orderStatus!=null">
AND V.ORDER_STATUS in (${orderStatus})
</if>
<if test="operator!=null">
AND V.OPERATOR LIKE CONCAT('%', #{operator,jdbcType=VARCHAR}, '%')
</if>
<if test="goodsTitle!=null">
AND V.GOODS_TITLE LIKE CONCAT('%', #{goodsTitle,jdbcType=VARCHAR}, '%')
</if>
<if test="orderId!=null">
AND V.ORDER_ID LIKE CONCAT('%', #{orderId,jdbcType=VARCHAR}, '%')
</if>
<if test="shopId!=null">
AND V.SHOP_ID = #{shopId,jdbcType=VARCHAR}
</if>
<if test="checkoutStatus!=null">
AND V.CHECKOUT_STATUS <> #{checkoutStatus,jdbcType=INTEGER} OR V.CHECKOUT_STATUS IS NULL
</if>
<if test="sql!=null">
AND ${sql}
</if>
</where>
</select>
如果需要将参数以美元$的形式传进去,就不能有这种写法AND USER_ID IN (${userId,jdbcType=VARCHAR})
,正确写法应该是AND USER_ID IN (${userId})
3、如果新增加一个参数,
①而这个参数既没有在接口中定义,比如这样
String select(@Param("isAllot") String isAllot);
②也没有在map中定义,比如这样
map.put("isAllot",isAllot);
③也不是数据库表对应的对象属性,比如这样
private String isAllot;
那么在xml中使用就应该用上面任意一种方式定义,然后在xml中使用,确保$或#后面大括号中是相同字段,且$符后面不应该加jdbcType=VARCHAR
正确用法:
<if test="isAllot!=null">
AND USER_ID IN (${isAllot})
</if>
错误用法:
<if test="isAllot!=null">
AND USER_ID IN (${userId})
</if>