SpringBoot中Mapper.xml的入参方式

在SpringBoot开发过程中,我们使用 ***Mapper.xml+***Mapper.java 来封装对数据库表的 CURD 操作,正常每张表会有一组对应的文件。

一、Mapper常见用法

下面例举一个查询操作:

  • 数据表t_sap_customer,表中有字段id、code、name、create_time、update_time、last_ver、is_valid
  • 现在需要根据idis_valid来查询一条数据

TSapCustomerMapper.java 代码:

java 复制代码
package com.starcharge.repository.db1.product.mapper;

import com.starcharge.repository.db1.product.domain.TSapCustomerDO;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

@Repository
public interface TSapCustomerMapper {
    TSapCustomerDO detail(String id,String isValid);
}

TSapCustomerMapper.xml 代码:

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.abc.repository.db1.product.mapper.TSapCustomerMapper">

    <!-- 创建数据库与实体类字段对应关系 -->
    <resultMap id="BaseResultMap" type="com.abc.repository.db1.product.domain.TSapCustomerDO">
        <result property="id" column="id"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="createTime" column="create_time" jdbcType="VARCHAR"/>
        <result property="updateTime" column="update_time" jdbcType="VARCHAR"/>
        <result property="lastVer" column="last_ver" jdbcType="VARCHAR"/>
        <result property="isValid" column="is_valid" jdbcType="VARCHAR"/>
    </resultMap>

    <!--查询列表-->
    <select id="detail" resultMap="BaseResultMap">
        select
        id,code,name,last_ver,is_valid,create_time,update_time
        from t_sap_customer
        where is_valid = #{isValid} and id = #{id}
    </select>
</mapper>

上面TSapCustomerMapper.javaTSapCustomerMapper.xml就是一组针对数据库表t_sap_customer的实体类操作,*Mapper.java负责定义实体类的对外Api,*Mapper.xml负责实现具体的CURD操作的SQL语句。

两者使用xml文件中的id属性值来做映射对应,具体来说就是TSapCustomerMapper接口中的detail方法,会到xml文件中找到对应的id='detail'来执行。

二、mapper.xml入参方法

这里常见的一个问题是,我们在执行SQL的时候会有各种入参,那么我们要如何将api中的入参传入xml文件中,请看下面介绍。

1、简单传参

TSapCustomerMapper.javaTSapCustomerMapper.xml 之间,默认按照参数名入参

以下的入参都是可以正常运行的:

java 复制代码
//TSapCustomerMapper.java
@Repository
public interface TSapCustomerMapper {
    TSapCustomerDO detail(String id, String isValid);
}

//TSapCustomerMapper.xml
    <select id="detail" resultMap="BaseResultMap">
        select
        id,code,name,last_ver,is_valid,create_time,update_time
        from t_sap_customer
        where is_valid = #{isValid} and id = #{id}
    </select>

2、@Param传参

java 复制代码
//TSapCustomerMapper.java
@Repository
public interface TSapCustomerMapper {
    TSapCustomerDO detail(@Param("id1") String id, @Param("isValid1") String isValid);
}

//TSapCustomerMapper.xml
    <select id="detail" resultMap="BaseResultMap">
        select
        id,code,name,last_ver,is_valid,create_time,update_time
        from t_sap_customer
        where is_valid = #{isValid1} and id = #{id1}
    </select>

3、Map入参

java 复制代码
//SapCustomerImpl.java
@Service
public class SapCustomerImpl implements SapCustomerService {    
	@Override
    public TSapCustomerDO detail(String id) {
        HashMap<String,String> map=new HashMap<String,String>();
        map.put("id",id);
        map.put("isValid","2");
        TSapCustomerDO r = sapCustomerMapper.detail(map);
        return r;
    }
}

//TSapCustomerMapper.java
@Repository
public interface TSapCustomerMapper {
    TSapCustomerDO detail(HashMap query);
}

//TSapCustomerMapper.xml
    <select id="detail" resultMap="BaseResultMap">
        select
        id,code,name,last_ver,is_valid,create_time,update_time
        from t_sap_customer
        where is_valid = #{isValid} and id = #{id}
    </select>

4、param、arg入参

xml文件中默认会传入arg0...argNparam1...paramN两个使用索引的入参。arg从0开始,param从1开始。

java 复制代码
//TSapCustomerMapper.java
@Repository
public interface TSapCustomerMapper {
    TSapCustomerDO detail(String id, String isValid);
}

//TSapCustomerMapper.xml
    <select id="detail" resultMap="BaseResultMap">
        select
        id,code,name,last_ver,is_valid,create_time,update_time
        from t_sap_customer
        where is_valid = #{param2} and id = #{param1}
    </select>

5、简单入参+Map入参

java 复制代码
//SapCustomerImpl.java
@Service
public class SapCustomerImpl implements SapCustomerService {    
	@Override
    public TSapCustomerDO detail(String id) {
        HashMap<String,String> map=new HashMap<String,String>();
        map.put("isValid","2");
        TSapCustomerDO r = sapCustomerMapper.detail(id, map);
        return r;
    }
}

//TSapCustomerMapper.java
@Repository
public interface TSapCustomerMapper {
    TSapCustomerDO detail(String id, HashMap map);
}

//TSapCustomerMapper.xml
    <select id="detail" resultMap="BaseResultMap">
        select
        id,code,name,last_ver,is_valid,create_time,update_time
        from t_sap_customer
        where is_valid = #{map.isValid} and id = #{id}
    </select>

三、#{} 和 ${} 的区别

MyBatis中 #{ }和${ }都可以用来动态传递参数。

1、不同点

#{} 对应底层使用 jdbcPreparedStatementd 对象来执行sql语句,在SQL中相当于一个参数占位符"?",用来补全预编译语句。它补全预编译语句时,可以理解为在此参数值两端统统使用单引号引起来。 #{} 里除了可以写接收参数的名称外,还可以设置javaTypejdbcTypemode等。

${} 对应底层使用 jdbcStatement 对象来执行sql语句,就是单纯的字符串拼接,拼接完成后才会对SQL进行编译、执行,所以性能较低,也无法复用。但是在有些 #{ }无法胜任的地方,还是会需要${ }来完成。

2、结论

#{} 很大程度防止sql注入,提高系统安全,一般能用#的地方就别用$

${} 无法防止Sql注入,如果写的SQL语句的参数内容应该作为SQL的一部分,此时必须使用$,比如:表名称,order by 排序字段,分组 group by 等。

相关推荐
用户83071968408234 分钟前
Spring Boot 中Servlet、Filter、Listener 四种注册方式全解析
java·spring boot
xixingzhe235 分钟前
spring boot druid 10秒超时问题
java·数据库·spring boot
毕业设计-小慧40 分钟前
计算机毕业设计springboot城市休闲垂钓园管理系统 基于Spring Boot的都市休闲垂钓基地数字化运营平台 城市智慧钓场综合服务管理平台
spring boot·后端·课程设计
csdn2015_4 小时前
springboot controller 参数可以是List吗
spring boot·后端·list
xiaohe074 小时前
JAVA系统中Spring Boot 应用程序的配置文件:application.yml
java·开发语言·spring boot
de_wizard4 小时前
DeepSeek API 调用 - Spring Boot 实现
windows·spring boot·后端
Flittly5 小时前
【SpringAIAlibaba新手村系列】(4)流式输出与响应式编程
java·spring boot·spring·ai
Zzxy5 小时前
Spring Security + JWT 简单集成
java·spring boot
※DX3906※5 小时前
SpringBoot之旅4: MyBatis 操作数据库(进阶) 动态SQL+MyBatis-Plus实战,从入门到熟练,再也不踩绑定异常、SQL拼接坑
java·数据库·spring boot·spring·java-ee·maven·mybatis
_院长大人_6 小时前
Spring Boot 3.3 + Atomikos 分布式事务日志路径配置踩坑记录
spring boot·分布式·后端