一、预编译SQL
预编译SQL是一种在执行SQL查询前将其编译并在数据库中存储的过程。这种方式主要用于提高性能、防止SQL注入攻击,并简化代码编写。
-
提高性能:预编译SQL避免了每次执行时解析和编译SQL的时间,因为这些操作只需要在第一次执行时完成。后续的查询只需传递参数,而无需重新编译。
-
防止SQL注入:预编译语句通常会使用参数占位符(如问号
?
或命名参数),这样用户输入的数据会被安全地作为参数传递,而不是直接拼接到SQL语句中,从而防止恶意用户插入恶意SQL。 -
代码简洁:预编译使代码更易于管理和复用,特别是在需要执行相同结构但参数不同的多次查询时,只需调用一次预编译的语句并多次设置参数即可。
二、依赖注入
SQL注入是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。
原理:攻击者利用应用程序没有正确验证或转义用户提供的数据,将其插入到预期的SQL查询中,可能导致未经授权的数据访问、修改或删除。
这里是一个例子:
如果没有预编译SQL,在登录页面输入密码:'1' or '1' = '1',解析后的代码就是 where password = '1' or '1' = '1'。
三、占位符
#{...}
执行SQL时,会将#{…}替换为?,生成预编译SQL,会自动设置参数值。
使用时机:参数传递,都使用#{…}
${..}
拼接SQL。直接将参数拼接在SQL语句中,底层不是预编译SQL语句,存在SQL注入问题。
使用时机:如果对表名、列表进行动态设置时使用。
在模糊查询时,可以使用 where name like '%${name}%',但是这样存在SQL注入,可以使用where name like concat('%',#{name},'%')
四、XML映射文件
创建XML映射文件的要求
1、XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)。
2、XML映射文件的namespace属性为Mapper接口全限定名一致。
3、XML映射文件中sql语句的id与Mapper 接口中的方法名一致,并保持返回类型一致。
这里只有查询时存在属性resultspace(值为单条记录封装的类型),增删改用不上。
使用XML配置文件步骤
1、下载MybatisX插件
2、粘贴XML配置文件的配置
入门_MyBatis中文网https://mybatis.net.cn/getting-started.html
这里我直接给出来吧:
<?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">
五、动态SQL
1、<if>、<where>
<if>:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。 <where>:where 元素只会在子元素有内容的情况下才插入where子句。而且会自动去除子句的开头的and 或 or(下图中第一个if语句前没有and,如过第一条语句条件不满足,第二局就多个and)。
多用于查询时,可以通过一个或多个条件查询。
<select id="getAllEmp" resultType="project1.mybatis_crud.Pojo.Emp">
select * from emp
<where>
<if test="name != null">
name like concat('%',#{name},'%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between #{begin} and #{end}
</if>
</where>
</select>
2、<set>
可以删除额外的逗号。
<update id="update2">
update emp
<set>
<if test="username != null">username = #{username},</if>
<if test="name != null">name = #{name},</if>
<if test="gender != null">gender = #{gender},</if>
<if test="image != null">image = #{image},</if>
<if test="job != null">job = #{job},</if>
<if test="entrydate != null">entrydate = #{entrydate},</if>
<if test="deptId != null">dept_id = #{deptId},</if>
<if test="updateTime != null">update_time = #{updateTime}</if>
</set>
where id = #{id}
</update>
3、<foreach>
</select>
<!-- 批量删除员工 (18,19,20) -->
<!--
collection: 遍历的集合
item: 遍历出来的元素
separator: 分隔符
open: 遍历开始前拼接的SQL片段
close: 遍历结束后拼接的SQL片段
-->
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")"> #{id} </foreach>
</delete>
4、<sql>、<include>
<sql>:定义可重用的 SQL 片段。
<include>:通过属性refid,指定包含的sql片段。