MyBatis进行单表多表查询以及其中的${}涉及的SQL注入

目录

回顾:

参数占位符#{}和${} 

 ${}唯一使用地方

使用${}造成的SQL注入漏洞

like查询

mapper中接收结果的参数 

resultType和resultMap​编辑

多表查询


回顾:

参数占位符#{}和${} 

  •  `#{}` 占位符语法通常用于模板引擎或动态查询语句中。它是一种更加安全的占位符,被设计用来防止SQL注入攻击。在大多数情况下,`#{}` 会把传递给它的值作为参数进行处理,并进行适当的转义(预处理)。(加' ')

例如,在使用数据库框架时,可以将查询参数通过 `#{}` 进行占位,如 `SELECT * FROM table WHERE id = #{param}`。这样可以有效地防止 SQL 注入攻击。

  • 2. `${}` 占位符语法通常用于配置文件或属性文件中的占位符直接替换在SQL注入的问题。
  • 其实  '${}'  和  #{}等价

那我们神魔时候使用${}

/**   参数占位符 #{} 和 ${} :
 * #{}:预编译处理;
 * ${}: 字符直接替换;
 *
 * Mybatis在处理#{}时,会把SQL中的#{}替换成?,使用PaeparedStatement的set方法来复制,直接替换:Mybatis在处理${},是把${}替换成变量的值;
 * $的应用场景:使用Java中的关键字的时候!
 * ${sort}可以实现排序查询,而是用#{sort}就不能实现排序查询了,因为当使用#{sort}查询的时候,如果查询的值是String,则会加单引号,就会导致sql错误;
 *
 * **/

 ${}唯一使用地方

现在我们要进行升序/降序查询表中信息,

//mapper中的接口

import com.example.demo1014.entity.UserInfo;
import lombok.Data;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.*;
@Mapper
public interface UserMapper {
    List<UserInfo> getListByOrder(@Param("order") String order);

}

配置xml——因为我们想有那种查询就用那种查询so,order by id${order}

<?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.example.demo1014.mapper.UserMapper">
   
    <select id="getListByOrder" resultType="com.example.demo1014.entity.UserInfo">
        select* from userinfo order by id ${order}
    </select>

</mapper>
<!--namsespace是xml实现接口的全路径(包名+接口名) id是实现的方法名  resultType是返回的类型 ${}是标签,用来传递参数-->

此时在UserMapper接口中右键generate,选择test,我们就可以

接下来进行SpringBoot单元测试,在Test包中

想要查看日志信息:在application.yml文件中配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/java2023?characterEncoding=utf8&useSSL=false       
# MySQL数据库的URL,根据实际情况修改
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver  # MySQL的JDBC驱动类名,根据实际情况修改

mybatis:
  mapper-locations: classpath:mybatis/*Mapper.xml
# 开启mybatis sql 日志打印;
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

# 配置打印MyBatis执行的sql;
logging:
  level:
    com:
      example:
        demo1014: debug

点击运行就可以看到排序好了

但是当我们把${}改成#{},就不行了,会给asc/desc加上单引号。

使用${}造成的SQL注入漏洞

 当我们在用姓名和邮箱号作为查询用户信息的时候,有一个不对我们都不能让他查询到,

前面我们说了'${}'等价于#{},当我们在mapper中的接口进行.xml(resourse包下的)配置时如果使用

<?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.example.demo1014.mapper.UserMapper">
    <select id="login" resultType="com.example.demo1014.entity.UserInfo">
        select* from userinfo where name='${name}' and email =#{email}
    </select>
</mapper>
<!--namsespace是xml实现接口的全路径(包名+接口名) id是实现的方法名  resultType是返回的类型 ${}是标签,用来传递参数-->

回到mapper中的接口:进行单元测试

 

我们想查询的用户

+----+------+------+-------------+
| id | name | age  | email       |
+----+------+------+-------------+
|  2 | mike |   30 | 1111@qq.com |
+----+------+------+-------------+

但是我们使用名字  ' or 1='1  ,并不是真正的名字,单元测试进行运行的时候却发现

就类似于在mysql中的这种效果,

这就是sql注入,当我们把UserMapper.xml中的文件改成#{},就没有这个顾虑了。

like查询

<select id="getListByName"  resultType="com.example.demo1014.entity.UserInfo">
    select* from userinfo where name like LIKE CONCAT('%', #{name}, '%')
</select>

 这里使用concat函数,不能使用'%#{name}%'——>相当于

mysql> select* from userinfo where name like '%m%';
+----+-------+------+------------------+
| id | name  | age  | email            |
+----+-------+------+------------------+
|  2 | mike  |   30 | 1111@qq.com      |
|  7 | smith |  888 | 792738927@qq.com |
+----+-------+------+------------------+
2 rows in set (0.00 sec)

mysql> select* from userinfo where name like '%'m'%';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'm'%'' at line 1

mapper中接收结果的参数 

resultType和resultMap

resultType 适用于简单的映射场景,而 resultMap 更加灵活、可定制化,可以实现更高级的映射需求 .不过resultMap使用前要先声明。

resultMap的使用场景: 字段名和属性名不一样(也可以使用as别名)

我们程序中写的字段如username,而mysql表中是name。

这样就不能用resultType,

    <resultMap id="baseMap" type="com.example.demo1014.entity.UserInfo">
        <id column="id" property="id"></id>
        <result column ="name" property="username"></result>
        <result column ="age" property="age"></result>
        <result column="email" property="email"></result>
    </resultMap>
    <select id="getAll" resultMap="baseMap">
        select* from userinfo;
    </select>

更简单的解决——>as

 select id,name as username ,age,email from userinfo

多表查询

使用left join

<select id="getUserListWithOrders" resultMap="userWithOrdersMap">
  SELECT u.*, o.*
  FROM users u LEFT JOIN orders o ON u.id = o.user_id
</select>
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sqyaa.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值