MyBatis获取参数值的两种方式#{}和${} 以及 获取参数值的各种情况

一、参数值的两种方式#{}和${}

在 MyBatis 中,可以使用两种方式来获取参数值:#{} 和 ${}。

  1. #{}:这是 MyBatis 推荐使用的方式。在 SQL 语句中使用 #{},MyBatis 会自动将参数值进行预编译处理,防止 SQL 注入攻击,并且可以处理各种类型的参数(如字符串、数字、日期等)。例如:

    复制代码
     <select id="getUserById" resultType="User">
       SELECT * FROM user WHERE id = #{id}
     </select>

在这个例子中,#{id} 表示一个参数占位符,MyBatis 会将它替换为具体的参数值。

  1. {}:这种方式会直接将参数值拼接到 SQL 语句中,不做预编译处理。这种方式适用于在 SQL 语句中引用列名、表名等无法使用 #{} 替换的情况。但需要注意的是,使用 {} 可能会导致 SQL 注入攻击的风险,因此需要谨慎使用。例如:

    复制代码
     <select id="getUserByName" resultType="User">
       SELECT * FROM user WHERE name = '${name}'
     </select>

在这个例子中,#{id} 表示一个参数占位符,MyBatis 会将它替换为具体的参数值。

MyBatis获取参数值的两种方式:{}和#{} {}的本质就是字符串拼接,#{}的本质就是占位符赋值

${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号

二、获取参数值的各种情况

2.1 单个字面量类型的参数

  • 若mapper接口中的方法参数为单个的字面量类型,此时可以使用{}和#{}以任意的名称(最好见名识意)获取参数的值,注意{}需要手动加单引号

    复制代码
      <!--User getUserByUsername(String username);-->
      <select id="getUserByUsername" resultType="User">
          select * from t_user where username = #{username}
      </select>
    
      <!--User getUserByUsername(String username);-->
      <select id="getUserByUsername" resultType="User">  
          select * from t_user where username = '${username}'  
      </select>

2.2 多个字面量类型的参数

若mapper接口中的方法参数为多个时,此时MyBatis会自动将这些参数放在一个map集合中。

① 以arg0,arg1...为键,以参数为值;

② 以param1,param2...为键,以参数为值;

因此只需要通过{}和#{}访问map集合的键就可以获取相对应的值,注意{}需要手动加单引号。

使用arg或者param都行,要注意的是,arg是从arg0开始的,param是从param1开始的

复制代码
    <!--User checkLogin(String username,String password);-->
    <select id="checkLogin" resultType="User">  
    	select * from t_user where username = #{arg0} and password = #{arg1}  
    </select>

    <!--User checkLogin(String username,String password);-->
    <select id="checkLogin" resultType="User">
	    select * from t_user where username = '${param1}' and password = '${param2}'
    </select>

2.3 map集合类型的参数

  • 若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中只需要通过{}和#{}访问map集合的键就可以获取相对应的值,注意{}需要手动加单引号

    复制代码
      <!--User checkLoginByMap(Map<String,Object> map);-->
      <select id="checkLoginByMap" resultType="User">
          select * from t_user where username = #{username} and password = #{password}
      </select>
    
      @Test
      public void checkLoginByMap() {
          SqlSession sqlSession = SqlSessionUtils.getSqlSession();
          ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
          Map<String,Object> map = new HashMap<>();
          map.put("usermane","admin");
          map.put("password","123456");
          User user = mapper.checkLoginByMap(map);
          System.out.println(user);
      }

2.4 实体类类型的参数

  • 若mapper接口中的方法参数为实体类对象时此时可以使用{}和#{},通过访问实体类对象中的属性名获取属性值,注意{}需要手动加单引号

    复制代码
      <!--int insertUser(User user);-->
      <insert id="insertUser">
          insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
      </insert>
    
      @Test
      public void insertUser() {
      	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
      	ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
          User user = new User(null,"Tom","123456",12,"男","[email protected]");
          mapper.insertUser(user);
      }

2.5 使用@Param标识参数

可以通过@Param注解标识mapper接口中的方法参数,此时,会将这些参数放在map集合中

  1. 以@Param注解的value属性值为键,以参数为值;
  2. 以param1,param2...为键,以参数为值;
  • 只需要通过{}和#{}访问map集合的键就可以获取相对应的值,注意{}需要手动加单引号

    复制代码
      <select id="CheckLoginByParam" resultType="User">
          select * from t_user where username = #{username} and password = #{password}
      </select>
    
      @Test
      public void checkLoginByParam() {
      	SqlSession sqlSession = SqlSessionUtils.getSqlSession();
          ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
          mapper.CheckLoginByParam("admin","123456");
      }

三、总结

  • 建议分成两种情况进行处理
    1. 实体类类型的参数
    2. 使用@Param标识参数

四、补贴知识点:以map集合接收作为返回值类型

4.1 查询一条数据为map集合

复制代码
/**  
 * 根据用户id查询用户信息为map集合  
 * @param id  
 * @return  
 */  
Map<String, Object> getUserToMap(@Param("id") int id);

<!--Map<String, Object> getUserToMap(@Param("id") int id);-->
<select id="getUserToMap" resultType="map">
	select * from t_user where id = #{id}
</select>
<!--结果:{password=123456, sex=男, id=1, age=23, username=admin}-->

4.2 查询多条数据为map集合

4.2.1 方法一

复制代码
/**  
 * 查询所有用户信息为map集合  
 * @return  
 * 将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,此时可以将这些map放在一个list集合中获取  
 */  
List<Map<String, Object>> getAllUserToMap();

<!--Map<String, Object> getAllUserToMap();-->  
<select id="getAllUserToMap" resultType="map">  
	select * from t_user  
</select>
<!--
	结果:
	[{password=123456, sex=男, id=1, age=23, username=admin},
	{password=123456, sex=男, id=2, age=23, username=张三},
	{password=123456, sex=男, id=3, age=23, username=张三}]
-->

4.2.2 方法二

复制代码
/**
 * 查询所有用户信息为map集合
 * @return
 * 将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,并且最终要以一个map的方式返回数据,此时需要通过@MapKey注解设置map集合的键,值是每条数据所对应的map集合
 */
@MapKey("id")
Map<String, Object> getAllUserToMap();

<!--Map<String, Object> getAllUserToMap();-->
<select id="getAllUserToMap" resultType="map">
	select * from t_user
</select>
<!--
	结果:
	{
	1={password=123456, sex=男, id=1, age=23, username=admin},
	2={password=123456, sex=男, id=2, age=23, username=张三},
	3={password=123456, sex=男, id=3, age=23, username=张三}
	}
-->
相关推荐
面朝大海,春不暖,花不开几秒前
自定义Spring Boot Starter的全面指南
java·spring boot·后端
得过且过的勇者y几秒前
Java安全点safepoint
java
夜晚回家35 分钟前
「Java基本语法」代码格式与注释规范
java·开发语言
斯普信云原生组1 小时前
Docker构建自定义的镜像
java·spring cloud·docker
wangjinjin1801 小时前
使用 IntelliJ IDEA 安装通义灵码(TONGYI Lingma)插件,进行后端 Java Spring Boot 项目的用户用例生成及常见问题处理
java·spring boot·intellij-idea
wtg44521 小时前
使用 Rest-Assured 和 TestNG 进行购物车功能的 API 自动化测试
java
白宇横流学长1 小时前
基于SpringBoot实现的大创管理系统设计与实现【源码+文档】
java·spring boot·后端
fat house cat_2 小时前
【redis】线程IO模型
java·redis
stein_java3 小时前
springMVC-10验证及国际化
java·spring
敖云岚3 小时前
【Redis】分布式锁的介绍与演进之路
数据库·redis·分布式