Как правильно использовать аннотацию @Param Mybatis - PullRequest
0 голосов
/ 09 января 2020

Сначала я не использовал аннотацию @Param, это мой картограф. java

public void changeUserAuth(Integer userId,int identity);

, а это мой картограф. 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>

тогда это работает правильно! Я продолжаю писать так, как показано ниже:

//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>

однако, это выдало ошибку, сообщение:

Нет объекта для свойства с именем 'userId' в 'class. java .lang.Integer'

Я могу понять, что mybatis не может анализировать Integer, но почему это не ошибка, как при первом использовании, просто потому, что у меня есть Параметр типа int? Во втором методе я должен использовать аннотацию @Param

1 Ответ

2 голосов
/ 19 января 2020

Вот как вы ссылаетесь на параметры в инструкциях MyBatis.

Я буду использовать этот POJO в следующем объяснении.

public class User {
  private Integer id;
  private String name;
  //...
}

Когда используется @Param

Если вы добавите аннотацию @Param на параметр, вы можете использовать указанное имя для ссылки на параметр. Это простейший случай.

Несколько примеров:

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>

Без @Param

Если нет @Param, это зависит от нескольких условия.

Когда метод отображения принимает только один параметр [1] и ...

  1. ... единственный параметр присваивается java.util.List, вы можете ссылаться на параметр как list.

    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>
    
  2. ... единственный параметр назначается на java.util.Collection, вы можете ссылаться на параметр как collection.

    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>
    
  3. ... есть обработчик типа, сопоставленный с единственным параметром (т. Е. Параметр String, Integer, et c.).

    • В MyBatis 3.5.2 и более поздних версиях вы можете ссылаться на параметр, используя любое имя (хотя вы должны использовать разумные имена по понятным причинам). например,

      List<User> select(Integer id);
      
      <select id="select" resultType="User">
        select * from users
        <where>
          <if test="x != null">and id = #{y}</if>
        </where>
      </select>
      
    • С MyBatis 3.5.1

      • вы можете ссылаться на параметр с любым именем в #{}.
      • Вы должны ссылаться на параметр как _parameter в ${}, test атрибуте <if /> и <when /> и value атрибуте <bind />. Вот почему ваш второй пример выдает исключение.

      List<User> select(Integer id);
      
      <select id="select" resultType="User">
        select * from users
        <where>
          <if test="_parameter != null">and id = #{z}</if>
        </where>
      </select>
      
  4. ... нет обработчика типа сопоставленный с единственным параметром (т. е. параметром является POJO или Map<String, ?>), можно напрямую связать свойства параметра с их именами (или ключами, если параметр является Map).

    void insert(User user);
    
    <insert id="insert">
      insert into users (id, name) values
        (#{id}, #{name})
    </insert>
    

Когда метод mapper принимает несколько параметров

  1. Если проект компилируется с параметром компилятора '-parameters * , вы можете ссылаться на него параметры, использующие их имена, объявленные в сигнатуре метода. Это ваш первый пример.

    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>
    
  2. В противном случае вы можете ссылаться на параметры, используя имена, неявно назначенные MyBatis, например arg0, arg1, ... (Я бы не рекомендовал это, поскольку это fr agile и подвержен ошибкам).

    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 и ResultHandler делает не в счет.

...