[Mybatis plus] Use paging query, error Parameter 'xxx' not found. Available parameters are xxx


I encountered an error encountered in Mybatis plus paging query at work today, indicating that the parameter is not bound, so record it now. The following data are all MOCK information

0 gives the error scenario first

java entity entity class

用 user 代替实体类信息

@Data
class User {
    
    
	private Long id;
	private String name;
	private String agx;
	private Integer age;
}

用 condition 代替查询信息

@Data
class Condition {
    
    
	private Long id;
	private String name;
	private String agx;
	private Integer age;
}

java mapper interface methods

List<User> queryByCondition(Condition condition);
IPage<User> queryByCondition(Page<?> page, Condition condition);

The mapper.xml information corresponding to the Java mapper

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="please ignore">
    <resultMap id="Base_Column_result_map"
               type="User">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="agx" property="agx"/>
        <result column="age" property="age"/>
    </resultMap>

    <sql id="Base_Column_select_map">
        id, name, agx, age
    </sql>

    <select id="queryByCondition"
            parameterType="Condition"
            resultMap="Base_Column_result_map">
        SELECT
        <include refid="Base_Column_select_map"/>
        FROM
        t_wms_inv_inventory_asset
        <where>
            <if test="id != null">
                AND id = #{id}
            </if>
            <if test="name != null">
                AND name = #{name}
            </if>
            <if test="agx != null">
                AND agx = #{agx}
            </if>
            <if test="age != null">
                AND age = #{age}
            </if>
        </where>
    </select>
</mapper>

exception information

invoke method = queryByCondition exception
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
	at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:78)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:440)
	at com.sun.proxy.$Proxy105.selectList(Unknown Source)
	at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:223)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.executeForIPage(MybatisMapperMethod.java:122)
	at com.baomidou.mybatisplus.core.override.MybatisMapperMethod.execute(MybatisMapperMethod.java:86)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy$PlainMethodInvoker.invoke(MybatisMapperProxy.java:148)
	at com.baomidou.mybatisplus.core.override.MybatisMapperProxy.invoke(MybatisMapperProxy.java:89)
	at com.sun.proxy.$Proxy154.queryInventoryAssets(Unknown Source)
	... 省略部分冗余信息
Caused by: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg0, param1, param2]
	at org.apache.ibatis.binding.MapperMethod$ParamMap.get(MapperMethod.java:212)
	at org.apache.ibatis.scripting.xmltags.DynamicContext$ContextAccessor.getProperty(DynamicContext.java:120)
	at org.apache.ibatis.ognl.OgnlRuntime.getProperty(OgnlRuntime.java:2719)
	at org.apache.ibatis.ognl.ASTProperty.getValueBody(ASTProperty.java:114)
	at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
	at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
	at org.apache.ibatis.ognl.ASTNotEq.getValueBody(ASTNotEq.java:50)
	at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
	at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
	at org.apache.ibatis.ognl.ASTAnd.getValueBody(ASTAnd.java:61)
	at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
	at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
	at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:493)
	at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:457)
	at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:46)
	at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateBoolean(ExpressionEvaluator.java:32)
	at org.apache.ibatis.scripting.xmltags.IfSqlNode.apply(IfSqlNode.java:34)
	at org.apache.ibatis.scripting.xmltags.MixedSqlNode.lambda$apply$0(MixedSqlNode.java:32)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:32)
	at org.apache.ibatis.scripting.xmltags.TrimSqlNode.apply(TrimSqlNode.java:55)
	at org.apache.ibatis.scripting.xmltags.MixedSqlNode.lambda$apply$0(MixedSqlNode.java:32)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:32)
	at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:39)
	at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:297)
	at com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor.intercept(MybatisPlusInterceptor.java:69)
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61)
	at com.sun.proxy.$Proxy434.query(Unknown Source)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:147)
	at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:140)
	at sun.reflect.GeneratedMethodAccessor351.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426)
	... 76 common frames omitted

1 solution

step1: Add named parameters to the mapper interface method, as follows:

List<User> queryByCondition(@Param("condition") Condition condition);
IPage<User> queryByCondition(Page<?> page,@Param("condition") Condition condition);

tip: Page 参数不要加 具名 指示

step2: Modify the query information of mapper.xml, and add named restrictions

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="please ignore">
    <resultMap id="Base_Column_result_map"
               type="User">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="agx" property="agx"/>
        <result column="age" property="age"/>
    </resultMap>

    <sql id="Base_Column_select_map">
        id, name, agx, age
    </sql>

    <select id="queryByCondition"
            parameterType="Condition"
            resultMap="Base_Column_result_map">
        SELECT
        <include refid="Base_Column_select_map"/>
        FROM
        t_wms_inv_inventory_asset
        <where>
            <if test="condition.id != null">
                AND id = #{condition.id}
            </if>
            <if test="condition.name != null">
                AND name = #{condition.name}
            </if>
            <if test="condition.agx != null">
                AND agx = #{condition.agx}
            </if>
            <if test="condition.age != null">
                AND age = #{condition.age}
            </if>
        </where>
    </select>
</mapper>

So far, the above error reporting problem has been completely solved, but out of 记录者qualified status, the reason why the error is reported is tracked and displayed, and interested friends can take a look.


2 abnormal cause

mybatis plus [or mybtais] will generate a proxy class object for each mapper interface, and use the proxy class object to realize call recognition and assemble SQL, as shown in the figure below: Then
Proxy class acquisition
call the proxy class proxy interface to find a suitable executor, So as to parse and analyze SQL statements and xml conditional statements, as follows: The SQL parsing
key code inside the executor is shown in the figure:
get executor
if the form of Page + mapper is used as the parameter of the execution method, then it will eventually be located here:
positioning actuator
enter the inside of executeForPage , you will find the following code:
Paging execution
In fact, the execution of paging, the underlying call is the selectList method of sqlSession [This also shows from the side, you cannot rewrite the selectList method of BaseMapper provided by mybatis plus, because there will be errors here]. Among them commnad.getName(), the method obtains the interface method 全限定类名和路径, paramwhich is the execution parameter of the method, that is, pageand condition.
In the end, there will be an interceptor that intercepts the execution of the proxy method. This is the step for identifying and parsing parameters. Enter the selectList method, Debug into and you can find it. When you come here: step by step, you will eventually find out that when you come here
interceptor
, That is, where the conditional node
node resolution
is parsed : If node. To limit the class name, the param in the context does not recognize the id information, but only the poge and condition information.
insert image description here

insert image description here

insert image description here

Guess you like

Origin blog.csdn.net/qq_44503987/article/details/130430066