问题
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
_parameter
in${}
,test
attribute of<if />
and<when />
andvalue
attribute 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