数据输入
#{}
传递参数
- 使用
#{}
符号传递参数实际上是先编译sql语句,再给占位符传值,此时会将传入的参数当作一个字符串,会自定进行类型转换和防止SQL注入,会在生成的SQL语句中使用占位符?
来代替参数值。底层是PreparedStatement实现
${}
传递参数
- 先进行sql语句拼接,然后再编译sql语句,底层是Statement实现,存在sql注入。在关键字需要拼接时才会用到
- 动态表名
SELECT * FROM ${tableName}
- 批量删除
delete from t_student where id in(${ids})
- 模糊查询
select * from t_student where name like '%${name}%'
究竟选择那种方式传递参数重点在于在slq语句中,所要占位的地方是需要一个字符串还是一个组成部分
单个简单类型参数
单个简单类型参数,在占位符中可以随意命名,通常使用同接口方法的名字,对于参数类型mybatis会自动推断
// mapper层接口
Employee selectEmployee(Integer empId);
<!-- mapper配置文件 -->
<select id="selectEmployee" resultType="com.atli.mybatis.entity.Employee">
select emp_id empId,emp_name empName,emp_salary empSalary from t_emp where emp_id=#{empId}
</select>
实体类类型参数
- Mybatis会根据占位符中传入的数据,加工成get方法,然后通过反射在实体类对象中调用这个方法,从而获取到对应的数据,填充到占位符解析后替换掉占位符。
// 接口方法
int insertEmployee(Employee employee);
<!-- mapper配置文件 -->
<insert id="insertEmployee">
insert into t_emp(emp_name,emp_salary) values(#{empName},#{empSalary})
</insert>
零散的多个简单类型数据
- 对于零散的多个简单类型参数,需要在Mapper接口中抽象方法使用
@Param
声明参数类型和名称 - 框架底层会自动创建一个以(参数名:参数值)的键值对的map集合
- 若在方法中没有指定参数名,则会以默认参数名param0, param1, param2, …或者arg0, arg1, arg2, …作为键值对的key
// 接口方法
int updateEmployee(@Param("empId") Integer empId,@Param("empSalary") Double empSalary);
<!-- mapper配置文件 -->
<update id="updateEmployee">
update t_emp set emp_salary=#{empSalary} where emp_id=#{empId}
</update>
Map类型参数
// 接口方法
int updateEmployeeByMap(Map<String, Object> paramMap);
<!-- mapper配置文件 -->
<update id="updateEmployeeByMap">
update t_emp set emp_salary=#{empSalaryKey} where emp_id=#{empIdKey}
</update>
//测试
private SqlSession session;
//junit5会在每一个@Test方法前执行@BeforeEach方法
@BeforeEach
public void init() throws IOException {
session = new SqlSessionFactoryBuilder()
.build(
Resources.getResourceAsStream("mybatis-config.xml"))
.openSession();
}
@Test
public void testUpdateEmpNameByMap() {
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("empSalaryKey", 999.99);
paramMap.put("empIdKey", 5);
int result = mapper.updateEmployeeByMap(paramMap);
log.info("result = " + result);
}
//junit5会在每一个@Test方法后执行@@AfterEach方法
@AfterEach
public void clear() {
session.commit();
session.close();
}