MyBatis学习笔记 —— MyBatis获取参数值的两种方式

Posted 程序猿杰哥

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis学习笔记 —— MyBatis获取参数值的两种方式相关的知识,希望对你有一定的参考价值。

5、MyBatis获取参数值的两种方式

MyBatis获取参数值的两种方式:$ 和 #
$ 的本质就是字符串拼接, # 的本质就是占位符赋值
$ 使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;
但是#使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号

5.1、单个字面量类型的参数

若mapper接口中的方法参数为单个的字面量类型,

此时可以使用 $ 和

# 以任意的名称获取参数的值,注意$ 需要手动加单引号

UserMapper.java

package com.fan.mybatis.mapper;

import com.fan.mybatis.pojo.User;
/**
 * MyBatis获取参数值的两种方式:# 和 $
 * #的本质是占位符,$的本质是字符串拼接
 * 1、若mapper接口方法的参数为单个的字面量类型
 * 此时可以通过# 和 $以任意的内容获取参数值,一定要注意$的单引号问题
*/

public interface UserMapper 

    /**
     * 根据用户名查询用户信息
     * @param username
     * @return
     */
    User getUserByUsername(String username);

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">
    
    <select id="getUserByUsername" resultType="User">
        select * from t_user where username = #username
    </select>
</mapper>

ParameterTest.java

package com.fan.mybatis;

import com.fan.mybatis.mapper.UserMapper;
import com.fan.mybatis.pojo.User;
import com.fan.mybatis.utils.SqlSessionUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

public class ParameterTest 

    @Test
    public void testGetUserByUsername()
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.getUserByUsername("admin");
        System.out.println(user);
    

运行,控制台打印输出如下

DEBUG 02-24 17:35:24,407==> Preparing: select * from t_user where username = ? (BaseJdbcLogger.java:137)

DEBUG 02-24 17:35:24,426==> Parameters: admin(String) (BaseJdbcLogger.java:137)

DEBUG 02-24 17:35:24,442<== Total: 1 (BaseJdbcLogger.java:137)

Userid=1, username=‘admin’, password=‘123456’, age=23, gender=‘男’, email=‘12345@qq.com’

可以看到映射文件中的 # 变为? ,# 被当做占位符。传过来的参数是admin,查询出来1条数据。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">
    
    <select id="getUserByUsername" resultType="User">
        select * from t_user where username = #name
    </select>
</mapper>

将#usenrame变为#name , 运行可以看到查询出来的结果。

在mybatis传递参数的过程,不知道传递的参数叫什么名字,只知道传递的值是 admin,所以传递参数值跟#里的参数名字没有关系。

建议#里的参数名字和传递的参数名一样。

$测试

错误写法:$username

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">

  <select id="getUserByUsername" resultType="User">
    <!--select * from t_user where username = #username-->
    select * from t_user where username = $username
  </select>
</mapper>

可以看到 admin是一个字符串,传入sql中没有加引号。不加单引号会被当做字段来解析,

Unknown column ‘admin’ in ‘where clause’

where字句中有一个不认识的列/字段 admin

#执行sql的时候,占用的是?; $ 执行sql的时候,是直接拼接在sql中的。

正确写法:‘$usenrame’

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">
    
    <select id="getUserByUsername" resultType="User">
        <!--select * from t_user where username = #username-->
        select * from t_user where username = '$username'
    </select>
</mapper>

$里不能写数值,纯数字是可以运算的。

5.2、多个字面量类型的参数

若mapper接口中的方法参数为多个时,

此时MyBatis会自动将这些参数放在一个map集合中,以arg0, arg1…为键,以参数为值;以param1, param2 … 为键,以参数为值;因此只需要通过$ 和

# 访问map集合的键就可以获取相应的值,注意$ 需要手动加单引号

UserMapper.java

package com.fan.mybatis.mapper;

import com.fan.mybatis.pojo.User;

/**
 * @Date: 2023/02/24
 * @Author: fan
 * @Description:
 * MyBatis获取参数值的两种方式:# 和 $
 * #的本质是占位符,$的本质是字符串拼接
 * 1、若mapper接口方法的参数为单个的字面量类型
 * 此时可以通过# 和 $以任意的内容获取参数值,一定要注意$的单引号问题
 * 2、若mapper接口的方法的参数为多个的字面量类型
 * 此时MyBatis会将参数放在map集合中,以两种方式存储数据
 * a> 以arg0,arg1,...为键,以参数为值
 * b> 以param1,param2,...为键,以参数为值
 * 因此,只需要通过#和$访问map集合的键,就可以获取相对应的值,一定要注意$的单引号问题
 */
public interface UserMapper 
    /**
     * 验证登录
     * @param username
     * @param password
     * @return
     */
    User checkLogin(String username,String password);

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">
    <select id="checkLogin" resultType="User">
        select * from t_user where username = #username and password = #password
    </select>
</mapper>

ParameterTest.java

@Test
    public void testCheckLogin()
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = mapper.checkLogin("admin","123456");
    System.out.println(user);

运行,控制台报错:

org.apache.ibatis.exceptions.PersistenceException:

### Error querying database. Cause: org.apache.ibatis.binding.BindingException: Parameter ‘username’ not found. Available parameters are [arg1, arg0, param1, param2]

### Cause: org.apache.ibatis.binding.BindingException: Parameter ‘username’ not found. Available parameters are [arg1, arg0, param1, param2]

可以看到sql语句没有输出,PersistenceException是配置文件解析错误,BindingException是绑定参数时出现的异常。

Parameter ‘username’ not found. 参数username没有找到。

Available parameters are [arg1, arg0, param1, param2] 可用的参数时arg1, arg0, param1, param2。可参照此方案进行修改。

正确的写法:

方式一

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">
  <select id="checkLogin" resultType="User">
    select * from t_user where username = #arg0 and password = #arg1
  </select>
</mapper>

运行可以正常输出信息,查询到用户信息。

方式二:

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">
    <select id="checkLogin" resultType="User">
        <!--select * from t_user where username = #arg0 and password = #arg1-->
        select * from t_user where username = #param1 and password = #param2
    </select>
</mapper>

运行可以正常输出信息,查询到用户信息。

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">
  
    <select id="checkLogin" resultType="User">
        <!--select * from t_user where username = #arg0 and password = #arg1-->
        <!--select * from t_user where username = #param1 and password = #param2-->
        <!--select * from t_user where username = '$arg0' and password = '$arg0'-->
        select * from t_user where username = '$param1' and password = '$param2'
    </select>
</mapper>

如果当前参数有两个时,mybatis会自动把这两个参数放在一个map集合中的。放在map集合中,会以两种方式来存储数据。

第一种方式:以arg0,arg1为键,以参数值为值

第二种方式:以parma1,param2为键,以参数值为值。

相当于从map集合中访问存储的数据。通过map中的键访问对应的值。

5.3、map集合类型的参数

若mapper解耦中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中

UserMapper接口

package com.fan.mybatis.mapper;

import com.fan.mybatis.pojo.User;

/**
 * 3、若mapper接口方法的参数为map集合类型的参数
 * 只需要通过#和$访问map集合的键,就可以获取相对应的值,一定要注意$的单引号问题
 */
public interface UserMapper 

    /**
     * 添加用户信息
     * @param user
     */
    void insertUser(User user);

ParameterTest.java

@Test
public void testCheckLoginByMap()
    SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	UserMapper mapper = sqlSession.getMapper(UserMapper.class);
	Map<String,Object> map = new HashMap<>();
	map.put("username","admin");
	map.put("password","123456");
	User user = mapper.checkLoginByMap(map);
	System.out.println(user);

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">
  
    <select id="checkLoginByMap" resultType="User">
        select * from t_user where username = #username and password = #password
    </select>
</mapper>

运行测试类

5.4、实体类类型的参数

添加用户信息

UserMapper接口

package com.fan.mybatis.mapper;

import com.fan.mybatis.pojo.User;

/**
 * 4、若mapper接口方法的参数为实体类类型的参数
 * 只需要通过#和$访问是实体类中的属性名,就可以获取相对应的属性值,一定要注意$的单引号问题
 * 属性名只跟getXxx和setXXX的方法名有关系,把set和get去掉,剩余的字母首字母小写,就是当前的属性名
 */
public interface UserMapper 

    /**
     * 添加用户信息
     * @param user
     */
    void insertUser(User user);

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">

    <insert id="insertUser">
        insert into t_user values(null,#username,#password,#age,#gender,#email)
    </insert>
  
</mapper>

ParameterTest.java

@Test
public void testInsertUser()
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User user = new User(null,"root","123456",33,"女","123@qq.com");
    mapper.insertUser(user);

运行测试

5.5、使用@Param注解标识参数

可以通过@Param注解标识mapper接口中的方法参数,

此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;以param1,param2…为键,以参数为值;只需要通过$

$需要手动加单引号。

User checkLoginByParam(@Param("username") String username, @Param("password") String password);

加上@Param(“username”)后,mybatis仍然会将两个参数放进map中,放进map中的键就是@Param括号中的username和password

UserMapper接口

package com.fan.mybatis.mapper;

import com.fan.mybatis.pojo.User;
import org.apache.ibatis.annotations.Param;

/**
 * 5、可以在mapper接口方法的参数上设置@Param注解
 * 此时MyBatis会将这些参数放在map中,以两种方式进行存储
 * a> 以@Param注解的value属性值为键,以参数为值
 * b> 以param1,param2...为键,以参数为值
 * 只需要通过#和$访问map集合的键,就可以获取相对应的值,一定要注意$的单引号问题。
 */
public interface UserMapper 
    /**
     * 验证登录(使用@Param)
     * @param username
     * @param password
     * @return
     */
    User checkLoginByParam(@Param("username") String username, @Param("password") String password);

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fan.mybatis.mapper.UserMapper">

    <!-- User checkLoginByParam(@Param("username") String username, @Param("password") String password); -->
    <select id="checkLoginByParam" resultType="User">
        select * from t_user where username = #username and password = #password
    </select>
  
</mapper>

ParameterTest.java

@Test
public void testCheckLoginByParam()
	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
	UserMapper mapper = sqlSession.getMapper(UserMapper.class);
	User user = mapper.checkLoginByParam("admin","123456");
	System.out.println(user);

运行

以上是关于MyBatis学习笔记 —— MyBatis获取参数值的两种方式的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis学习笔记11:解决字段名和属性的映射关系

MyBatis学习笔记

MyBatis学习笔记

MyBatis学习笔记

Mybatis 学习笔记总结

MyBatis框架学习笔记