(5) Mybatis from entry to soil-analysis of multiple ways of parameter transfer in the Mapper interface

This is the fifth article in mybatis series. If you haven't read the previous suggestions, first go to the [Java Tsukuba Fox] public account to view the previous text, which is convenient for understanding and grasping.

After all, the common form of parameter passing in Mybatis is nothing more than passing a parameter, a Map, a Java object, or multiple parameters. These are explained and explained separately below.

Pass a parameter

Passing a parameter is relatively simple

usage

There is only one parameter in the Mapper interface method, such as:

UserModel getByName(String name);

Mapper xml references this name parameter:

#{任意合法名称}

For example: #{name}, #{val}, ${x}, etc. can all refer to the value of the name parameter above. image.gifIt is quite convenient and simple to use directly

Pass a Map parameter

usage

If we need to pass a lot of parameters and the number of parameters is dynamic, then we can put these parameters in a map, where the key is the parameter name, and the value is the value of the parameter. At work, this is arguably the most common. Can be used in most cases

This can be defined in the Mapper interface, such as:

List<UserModel> getByMap(Map<String,Object> map);

If we pass:

Map<String, Object> map = new HashMap<>();
            map.put("id", 1L);
            map.put("name", "冢狐");

In the corresponding mapper xml, you can obtain the value of the key in the map as a parameter through #{key in the map}, such as:

SELECT * FROM t_user WHERE id=#{id} OR name = #{name}

Pass a java object parameter

When there are many parameters, but we are sure how many parameters there are, we can put these parameters in a javabean object. This is also conducive to understanding, knowing which parameters need to be passed, and not very clear about the passed parameters like map.

If we want to query through userId and userName, we can define a dto object and add corresponding get and set methods to the attributes, such as:

@Getter
@Setter
@ToString
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserFindDto {
    private Long userId;
    private String userName;
}

The way of passing java objects is clearer than the way of map. We can know the specific parameters. When passing map, we don’t know which parameters are needed in this map. Map has no constraints on parameters. Parameters can be passed at will. , It is recommended to choose to pass parameters through java objects in case of multiple parameters.

Pass multiple parameters

What we introduced above is to pass one parameter, so can we pass multiple parameters? Let's try it.

Processing of multi-parameter mybatis

When mybatis processes multiple parameters, it encapsulates multiple parameters into a map. The key of the map is the name of the parameter. Java can obtain the name of the method parameter through reflection. This method is as follows:

UserModel getByIdOrName(Long id, String name);

After compilation, the name of the method parameter obtained through reflection is not id, name, but arg0, arg1, that is to say, after compilation, the real parameter name of the method will be lost, and it will become the format of arg+parameter subscript.

So the parameters passed above are equivalent to passing a map like the following:

Map<String,Object> map = new HashMap<>();
map.put("arg0",id);
map.put("arg1",name);

So the real parameter names of our method will be lost. If you want to use the real parameter names, you need to take the -parameters parameter when you compile the java code and use the javac command, and add this parameter when you compile the code. The actual name will be compiled into the class bytecode file. When the method name is obtained through reflection, the format is not arg0, arg1, but the real parameter names: id, name.

Let's modify the maven configuration to add this parameter when maven compiles the code, modify the build element in pom.xml, and add the following code to this element:

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.3</version>
        <configuration>
            <compilerArgs>
                <arg>-parameters</arg>
            </compilerArgs>
        </configuration>
    </plugin>
</plugins>

Add this parameter to the compiled code in idea. The operation is as follows:

Click File->Settings->Build,Execution,Deployment->Java Compiler, as shown below:

image.gif image

Below we modify the sql corresponding to getByIdOrName in xml to the following:

SELECT * FROM t_user WHERE id=#{arg0} OR name = #{arg1} LIMIT 1

Use the maven command to recompile the code of chat01, and execute the following command in the directory where mybatis-demo/pom.xml is located in the cmd command:

mvn clean compile -pl :chat01

The parameter name has become the real name, but there are still param1, param2, no matter how the method parameter name changes, how the compilation method changes, param1, param2 are always here, this param1, param2 is to cope with different compilation methods leading to parameter names However, in mybatis, in addition to putting the parameters into the map according to the name -> value, some values ​​are also put in the order of the parameters. The key of these values ​​is the param + parameter position, and this position starts from 1, so id is the first parameter, the corresponding key is param1, the key corresponding to name is param2, and the value corresponds to the value of the parameter, so the processing of the parameter by mybatis is equivalent to the following process:

Map<String,Object> map = new HashMap<>();
map.put("反射获取的参数id的名称",id);
map.put("反射获取的参数name的名称",name);
map.put("param1",id);
map.put("param2",name);

Use attention

  • The way of using parameter names has a strong dependence on the compilation environment. If the -parametersparameters are added in the compilation , the actual names of the parameters can be used directly. If they are not added, the parameter names will become arg下标the format, which is easy to make mistakes.
  • SQL uses param1、param2、paramNthis method to reference multiple parameters, which is particularly dependent on the order of the parameters. If someone adjusts the order of the parameters or adjusts the number of parameters, the consequences will be catastrophic, so this method is not recommended for everyone to use .

Use @param to specify the parameter name in multiple parameters

I just talked about the use of multi-parameter transmission. It has a strong dependence on the parameter name and order, which can easily lead to some serious errors.

Mybatis also considers this situation for us. We can let us specify the name of the parameter ourselves, and assign the name to the parameter through @param("parameter name").

/**
 * 通过id或者name查询
 *
 * @param id
 * @param name
 * @return
 */
UserModel getByIdOrName(@Param("userId") Long id, @Param("userName") String name);

Above, we have clearly specified the names of the two parameters through the @Param annotation, which are userId and userName. The corresponding user.xml has also been adjusted as follows:

<!-- 通过id或者name查询 -->
<select id="getByIdOrName" resultType="zhonghu.mybatis.chat01.UserModel">
    <![CDATA[
    SELECT * FROM user WHERE id=#{userId} OR name = #{userName} LIMIT 1
    ]]>
</select>

ResultHandler as a parameter

usage

When the number of queries is relatively large, the memory occupied by returning a List collection is still relatively large. For example, if we want to export a lot of data, in fact, if we traverse the next method of ResultSet through jdbc, we will process them one by one, instead of processing them. Save it to the List collection and then fetch it for processing.

Mybatis also supports us to do this. You can use the ResultHandler object. As its name suggests, this interface is used to process the results. Let’s take a look at its definition first:

public interface ResultHandler<T> {
  void handleResult(ResultContext<? extends T> resultContext);
}

There is 1 method, the parameter of the method is of type ResultContext, this is also an interface, look at the source code:

public interface ResultContext<T> {
  T getResultObject();
  int getResultCount();
  boolean isStopped();
  void stop();
}

4 methods:

  • getResultObject: Get the result of the current row
  • getResultCount: Get the current result to the first few lines
  • isStopped: Determine whether you need to stop traversing the result set
  • stop: stop traversing the result set

The ResultContext interface has an implementation class org.apache.ibatis.executor.result.DefaultResultContext, which is used by default in mybatis.

At last

  • If you feel that you are rewarded after reading it, I hope to pay attention to it. By the way, give me a thumbs up. This will be the biggest motivation for my update. Thank you for your support.
  • Welcome everyone to pay attention to my public account [Java Fox], focusing on the basic knowledge of java and computer, I promise to let you get something after reading it, if you don’t believe me, hit me
  • Seek one-click triple connection: like, forward, and watching.
  • If you have different opinions or suggestions after reading, please comment and share with us. Thank you for your support and love.

——I am Chuhu, and I love programming as much as you.

Welcome to follow the public account "Java Fox" for the latest news

Guess you like

Origin blog.csdn.net/issunmingzhi/article/details/113793746