Explain the parameter passing problem of Mybatis in detail

Compilation software: IntelliJ IDEA 2019.2.4 x64
Operating system: win10 x64-bit Home Edition
Maven version: apache-maven-3.6.3
Mybatis version: 3.5.6



1. Parameter passing problem in Mybatis

1.1 Passing a single common parameter

For a single common parameter, as long as its data type is a Java basic data type, wrapper type, string type, etc. Please feel free to use it boldly to pass, because MyBatis can use this parameter directly without any processing. And it is not restricted by the parameter name , that is, you can name it arbitrarily, but generally follow the principle of seeing the name and knowing the meaning.

The sample code is as follows:

<select id="selectUsers" resultType="User">
  select id, username, password
  from users
  where id = #{id}
</select>

In the above code, the id in "#{id}" can be named arbitrarily, and the parameter passed to id in the program, as long as its data type conforms to (Java basic data type, packaging type, string type) among them First, MyBatis can directly use this parameter to pass into the SQL statement.

1.2 Passing multiple common parameters

For any number of parameters, it will be repackaged by MyBatis into a Map. The key of Map is param1, param2, or arg0, arg1. The corresponding value is the value of the parameter.

Usage case: Find the corresponding employee information in the database according to the employee name and salary

① First define the method of finding the corresponding employee information based on the employee name and salary in the Mapper interface

The code example is as follows:

//根据员工姓名与员工薪资来查查找相应的员工
public Employee selectEmployeeByNameandSalary(String lastName,double salary);

② Define related sql in the mapping file

<select id="selectEmployeeByNameandSalary" resultType="mybatis.pojo.Employee">
    select
        id,
        last_name ,
        email,
        salary
    from
        tbl_employee
    where last_name=#{param1}
          and
          salary=#{param2}
</select>

③ test

@Test
public void test2(){
    
    
    try {
    
    
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过SqlSessionFactory对象调用openSession();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取EmployeeMapper的代理对象
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

        Employee employee = employeeMapper.selectEmployeeByNameandSalary("李四", 9000);
        System.out.println(employee);

    } catch (IOException e) {
    
    
        e.printStackTrace();
    }
}

insert image description here

1.3 Named parameters

grammar:

@Param(value="参数名")
@Param("参数名")

Location:

Declared before the formal parameters of the method in the XXXMapper interface

Notice:

  • Its underlying package is the Map structure
  • Named parameters support parameters [param1, param2, ...], but not [arg0, arg1 ...]

Sample code:

①Mapper interface corresponding code writing

//根据员工姓名与员工薪资来查查找相应的员工
public List<Employee> showEmpByName(@Param("lName") String lastName,@Param("salary") double salary);

② SQL written in the mapping file corresponding to the interface

Version 1 (the parameters do not use param1, param2):

<select id="showEmpByName" resultType="mybatis.pojo.Employee">
    select
    id,
        last_name ,
        email,
        salary
    from
        tbl_employee
    //#{lName}里是Mapepr接口中对应方法形参中@Param("lName")里的值    
    where 
    	last_name=#{lName}
    and
        salary=#{salary}
</select>

Version 2 (use param1, param2 as parameters):

 <select id="showEmpByName" resultType="mybatis.pojo.Employee">
        select
            id,
            last_name ,
            email,
            salary
        from
            tbl_employee
        where
            last_name=#{param1}
        and
            salary=#{param2}
    </select>

Version 3 (parameters use arg0, arg1)

 <select id="showEmpByName" resultType="mybatis.pojo.Employee">
        select
        id,
            last_name ,
            email,
            salary
        from
            tbl_employee
        where
            last_name=#{arg0}
        and
            salary=#{arg1}
    </select>

③ test

	@Test
    public void test4(){
    
    
        try {
    
    
            //从当前类下寻找并加载mybatis-config.xml(核心配置文件)
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            //通过SqlSessionFactory对象调用openSession()获取sqlsession对象
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //sqlsession对象使用getMapper(),传入EmployeeMapper的反射对象以获取代理对象
            EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

            //使用其代理对象调用showEmpByName()通过员工姓名与薪资去查找相应的员工
            List<Employee> jack = employeeMapper.showEmpByName("jack", 9000);
            System.out.println(jack);

        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }

insert image description here
insert image description here

insert image description here

1.4 POJO (java Bean) parameter passing

Mybatis supports POJO [Java Bean] input parameters, and the parameter key is an attribute in POjO

Usage case: Based on the usage case in the 1.2 summary, modify the formal parameter of the method in the Mapper interface to the Employee type, and only modify the corresponding sql and test code in the mapping file

① Modify the formal parameter type of the method in the Mapper interface to Employee

The code example is as follows:

//根据员工姓名与员工薪资来查查找相应的员工
public Employee selectEmployeeByNameandSalary(Employee employee);

② Modify the corresponding sql in the mapping file

<select id="selectEmployeeByNameandSalary" resultType="mybatis.pojo.Employee">
    select
        id,
        last_name ,
        email,
        salary
    from
    	tbl_employee
    where 
    	last_name=#{lastName}
   and
    	salary=#{salary}
</select>

③ test

@Test
public void test3(){
    
    
    try {
    
    
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过SqlSessionFactory对象调用openSession();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取EmployeeMapper的代理对象
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

        Employee employee=new Employee();
        employee.setSalary(5600.0);
        employee.setLastName("jack");

        Employee jack = employeeMapper.selectEmployeeByNameandSalary(employee);

        System.out.println(jack);

    } catch (IOException e) {
    
    
        e.printStackTrace();
    }
}

insert image description here

1.5 Map parameter passing

Mybatis supports direct entry of elements of the Map collection type, and the key of the map is the key of the parameter

Notice:

Mybatis does not support method overloading, because if there is sql with the same method in the mapping file corresponding to the xxxMapper interface in Mybatis, its id value cannot remain unique and conflicts will occur

Usage example: Based on the case in Section 1.2, this time use the Map collection as a formal parameter, write the corresponding sql in the corresponding mapping file and test it

The code example is as follows:

① Use the Map collection as a formal parameter to pass in

//根据员工姓名与员工薪资来查查找相应的员工
public List<Employee> showEmpByMap(Map<String,Object> map);

② Write the corresponding sql in the corresponding mapping file

<select id="showEmpByMap" resultType="mybatis.pojo.Employee">
    select
        id,
        last_name ,
        email,
        salary
    from
    tbl_employee
    where last_name=#{lastName} and  salary=#{salary}
</select>

③ test

@Test
public void test5() {
    
    
    try {
    
    
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        //通过SqlSessionFactory对象调用openSession();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取EmployeeMapper的代理对象
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

        Map<String,Object> map=new HashMap<>();
        map.put("lastName","jack");
        map.put("salary",5600);

        List<Employee> jack = employeeMapper.showEmpByMap(map);
        System.out.println(jack);

    } catch (IOException e) {
    
    
        e.printStackTrace();
    }
}

insert image description here

1.6 Collection, List & Array and other parameter passing

When the input parameter data type is Collection, List or Array, etc., you can directly use the built-in custom type alias (collection, list, array) corresponding to mybatis in the corresponding sql part of the corresponding mapping file, or you can use named parameters to customize Define the name.

Usage case: Obtain employee information through multiple ids [EmpIds: a collection of employee ids]

The code example is as follows:

a. Define the corresponding method in the EmployeeMapper interface

/**
 * 通过多个id获取员工的信息 【EmpIds:员工id的集合】
 * @param EmpIds
 * @return
 */
public List<Employee> selectEmpByIds(@Param("ids") List<Integer> EmpIds);

b. Define the corresponding sql in the mapping file corresponding to the EmployeeMapper interface

 <select id="selectEmpByIds" resultType="employee">
        SELECT
            `id`,
            `last_name`,
            `email`,
            `salary`,
            `dept_id`
        FROM
            `tbl_employee`
        <where>
            `id` in
            (
            <foreach collection="ids" item="id" separator=",">
                #{id}
            </foreach>
            )
        </where>
    </select>

c. test

@Test
public void test04(){
    
    
    try {
    
    
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        //通过SqlSessionFactory对象调用openSession();
        SqlSession sqlSession = sqlSessionFactory.openSession();

        //获取EmployeeMapper的代理对象
        EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);

        List<Employee> employees = employeeMapper.selectEmpByOneOpr(1);
        System.out.println(employees);

    } catch (IOException e) {
    
    
        e.printStackTrace();
    }
}

insert image description here


2. The use of # and $ in Mybatis parameter passing

2.1 The difference between # and $

  • #: The object that executes SQL statements at the bottom layer uses PreparedStatementd to precompile SQL to prevent SQL injection security risks, which is relatively safe.
  • $: The underlying SQL statement execution object uses the Statementi object, which does not solve the security risk of SQL injection and is relatively unsafe.

2.2 Usage scenarios of # and $

Take query SQL as an example:

select col,col2 from table1 where col=? and col2=group by? order bylimit?,?

scenes to be used:

  • “#”Usage scenario: all placeholder positions in the above Sql can be used#
  • “$”Usage scenario: #Unsolved parameter passing problems can be handed over to $handle [such as form dynamic form]

The sample code is as follows:

public List<Employee> selectEmpByDynamitTable(@Param("tblName")String tblName);
<select id="selectEmpByDynamitTable" resultType="employee">
	SELECT
        id,
        last_name,
        email,
        salary
	FROM
		${tb1Name}
</select>

Note:

In Mybatis, the $ symbol is also a symbol used to access the values ​​and information of various parameters, variables, etc., and is mainly used in scenarios such as dynamic SQL construction and parameter passing , for example:

  • ${variable}: The dynamic statement part used to insert variables or table names/column names, etc.
  • #{parameter}: prepared statement for placeholder parameters
  • $方法名(): used to call the method defined in the SQL fragment and return the result

Why is it said that ${variable} is mainly used to insert dynamic statements?

parsed differently:

  • ${variable}: It displays the incoming parameter value directly in the original sql statement without any quotation marks

    For example select * from users where id= variable, pass in {variable}, pass inv a r iab l e , pass in {1} => id=1

    The code example is as follows:

     <select id="showEmpByMap" resultType="mybatis.pojo.Employee">
            select
                id,
                last_name ,
                email,
                salary
            from
            tbl_employee
            where last_name=${lastName} and  salary=${salary}
        </select>
    
    

    insert image description here
    insert image description here

  • #{variable}: is to treat the incoming parameter value as a string and display it with double quotes

    For example select * from users where id= variable, pass in {variable}, pass inv a r iab l e , pass in {1} => id="1"

    The code example is as follows:

     <select id="showEmpByMap" resultType="mybatis.pojo.Employee">
            select
                id,
                last_name ,
                email,
                salary
            from
            tbl_employee
            where last_name=#{lastName} and  salary=#{salary}
        </select>
    

    insert image description here

Guess you like

Origin blog.csdn.net/siaok/article/details/130479856