@Analysis and reason of Param annotation

Keywords: Java SQL

Function: when annotations are used to simplify XML configuration (such as the introduction of sql parameters in Mapper.xml of Mybatis), the @ Param annotation is used to name the parameters. After the parameters are named, the parameter values can be obtained according to the name, and the parameters can be correctly passed into sql statements (generally, ${} will have the problem of sql injection through #{}).
Because Java beans will be used #{} when passing in. In the SQL statement, you can directly reference the properties of the JavaBean, and you can only reference the existing properties of the JavaBean.

Example description:

1. Use @ Param annotation

Mapper interface method:

 public int getUsersDetail(@Param("userid") int userid);

Corresponding Sql Mapper.xml file:

 <select id="getUserDetail" statementType="CALLABLE" resultMap="baseMap">
          Exec WebApi_Get_CustomerList #{userid}
 </select>

explain:

When using @ Param annotation to declare parameters, you can use #{} or ${}. When you do not use @ Param annotation to declare parameters, you must use #{}. It is recommended to pass JavaBean s. If ${} is used, an error will be reported.

2. Do not use @ Param annotation

When the @ Param annotation is not used, it is best to pass Java beans. In SQL statements, you can directly reference the properties of JavaBeans, and only the existing properties of JavaBeans can be referenced.

Mapper interface method:

 public int getUsersDetail(User user);

Corresponding Sql Mapper.xml file:

 <!--Here, you can directly reference the object attribute, and there is no need for the object.Attribute mode--> 
<select id="getUserDetail" statementType="CALLABLE" resultMap="baseMap">
          Exec WebApi_Get_CustomerList #{userid}
</select>

As for why @ Param annotation is used, as the annotation of Dao layer, it is used to pass parameters, so it can correspond to the field name in SQL. Generally, it is best when 2 = < parameter number < = 5.

In the original method, when the method has only one parameter, there is nothing to say. Only one parameter can match a value passed in. When there are multiple parameters, the values passed in cannot be distinguished. At this time, you can consider using Map, such as interface

public List<Role> findRoleByMap(Map<String, Object> parameter);

xml file

<select id="findRoleByMap" parameterType="map" resultType="role">
    SELECT id,name FROM t_role
    WHERE roleName=#{roleName}
    AND note=#{note}
<select>

Test file

RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
Map<String, Object> parameter = new HashMap<>();
parameter.put("roleName", "Lv Bu");
parameter.put("note", "Decisive battle on the top of the Forbidden City");
List<Role> roles = roleMapper.findRolesByMap(parameter);

Obviously, the above disadvantage lies in poor readability. You must read its key every time to understand its role, and you can't limit the data type it transmits. The following is the case of using @ Param. You need to change the interface to

public List<Role> findRoleByAnnotation(@Param("roleName") String roleName, @Param("note") String note);

In this way, we can directly pass in the corresponding value.

Of course, you can also use Java beans to pass multiple parameters and define a POJO

public class RoleParam {
    private String roleName;
    private String note;
    /*getter And setter*/
}

The interface becomes

public List<Role> findRoleByBean(RoleParam role);

The difference between the corresponding xml file and the above xml is that the id and parameterType have changed, and the method and parameterType corresponding to the id name the permission of the corresponding class.

More scenarios may be like this, corresponding to multiple POJO s

public List<Role> findRoleByMix(@Param("roleP") RoleParam role, @Param("permissionP") PermissionParam permission);

In this way, the following mapping can be performed

<select id="findRoleByMix" resultType="role">
    SELECT id,name FROM t_role
    WHERE roleName=#{roleP.roleName}
    AND note=#{rolep.note}
    AND level=#{permissionP.level}
<select>

Posted by ravegti on Wed, 29 Sep 2021 14:46:32 -0700