问题
I didn't use @Param annotation at first, this is my mapper.java
public void changeUserAuth(Integer userId,int identity);
, and this is my mapper.xml
<update id="changeUserAuth">
update user
<set>
<if test="identity != 0">identity = #{identity}</if>
</set>
<where>
<if test="userId != 0">userId = #{userId}</if>
</where>
</update>
then it works correctly!I continue to write like this, as follows:
//this's mapper.java
public void updateUserStatus(Integer userId);
<!--this is mapper.xml>
<update id="changeUserAuth">
update user
set deleteFlag= true
<where>
<if test="userId != 0">userId = #{userId}</if>
</where>
</update>
however,it gave an error,the message is
There is no getter for property named 'userId' in 'class.java.lang.Integer'
I can understand that mybatis cannot parse the Integer, but why it is not an error like my first use, just because I have an int type Parameter? In the second method, I have to use @Param annotation
回答1:
Here is how you reference parameters in MyBatis statements.
I'll use this POJO in the following explanation.
public class User {
private Integer id;
private String name;
//...
}
When @Param is used
If you add @Param annotation on a parameter, you can use the specified name to reference the parameter. This is the simplest case.
A few examples:
List<USer> select(@Param("id") Integer userId, @Param("name") String userName);
void insert(@Param("record") User user);
<select id="select" resultType="User">
select * from users
<where>
<if test="id != null">and id = #{id}</if>
<if test="name != null">and name = #{name}</if>
</where>
</select>
<insert id="insert">
insert into users (id, name) values
(#{record.id}, #{record.name})
</insert>
Without @Param
If there is no @Param, it depends on several conditions.
When the mapper method takes only one parameter [1] and ...
... the sole parameter is assignable to
java.util.List, you can reference the parameter aslist.List<User> selectByIds(List<Integer> ids);<select id="select" resultType="User"> select * from users where id in ( <foreach item="x" collection="list" separator=","> #{x} </foreach> ) </select>... the sole parameter is assignable to
java.util.Collection, you can reference the parameter ascollection.List<User> selectByIds(Set<Integer> ids);<select id="select" resultType="User"> select * from users where id in ( <foreach item="x" collection="collection" separator=","> #{x} </foreach> ) </select>... there is a type handler mapped to the sole parameter (i.e. the parameter is
String,Integer, etc.).With MyBatis 3.5.2 and later, you can reference the parameter using any name (you should use sensible names for obvious reasons, though). e.g.
List<User> select(Integer id);<select id="select" resultType="User"> select * from users <where> <if test="x != null">and id = #{y}</if> </where> </select>With MyBatis 3.5.1
- you can reference the parameter with any name in
#{}. - you must reference the parameter as
_parameterin${},testattribute of<if />and<when />andvalueattribute of<bind />. This is why your second example throws exception.
List<User> select(Integer id);<select id="select" resultType="User"> select * from users <where> <if test="_parameter != null">and id = #{z}</if> </where> </select>- you can reference the parameter with any name in
... there is no type handler mapped to the sole parameter (i.e. the parameter is POJO or
Map<String, ?>), you can reference the parameter properties directly with their names (or the keys if the parameter is aMap).void insert(User user);<insert id="insert"> insert into users (id, name) values (#{id}, #{name}) </insert>
When the mapper method takes multiple parameters
If the project is compiled with '-parameters' compiler option, you can reference the parameters using their names declared in the method signature. This is your first example.
List<USer> select(Integer userId, String userName);<select id="select" resultType="User"> select * from users <where> <if test="id != null">and id = #{id}</if> <if test="name != null">and name = #{name}</if> </where> </select>Otherwise, you can reference the parameters using the names implicitly assigned by MyBatis i.e.
arg0,arg1, ... (I would not recommend this as it's fragile and error-prone).List<USer> select(Integer userId, String userName);<select id="select" resultType="User"> select * from users <where> <if test="arg0 != null">and id = #{arg0}</if> <if test="arg1 != null">and name = #{arg1}</if> </where> </select>
[1] RowBounds and ResultHandler does not count.
来源:https://stackoverflow.com/questions/59668117/how-to-properly-use-the-param-annotation-of-mybatis