framwork学习笔记day03---动态sql操作

这篇博客详细介绍了MyBatis中的动态SQL操作,包括如何给SQL传参、输入映射(简单类型、零散简单类型、实体类型、Map)、输出映射(简单类型、实体类型、Map、List、ResultMap)、插入主键返回,以及动态SQL的各种标签(if、where、trim、set、choose、foreach)的使用,并给出了实际代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给SQL传参

  • 概述
    • Mybatis会在运行过程中,把配置文件中的SQL语句里面的#{}转换为“?”占位符,发送给 数据库执行。
  • 需求
    • 根据账户模糊查询
  • 代码实现
<select id="selectUserLikeName1" parameterType="string" resultType="user">
    select *
    from tb_user
    where user_name like "%"#{userName}"%"
</select>

<select id="selectUserLikeName2" parameterType="string" resultType="user">
    select *
    from tb_user
    where user_name like "%${userName}%"
</select>

总结

  • #{}
    • 不能直接写到字符串中
    • 可以防止SQL注入漏洞
    • 不可以传入表名
  • ${}
    • 能直接写到字符串中
    • 不可以防止SQL注入漏洞
    • 可以传入表名

输入映射

概述

  • 输入映射,是在映射文件中通过parameterType指定输入参数的类型。从而将用户输入的内容赋值到SQL语句的占位符中。
  • 简单类型 : 包含一个值
    • 基本数据类型
    • 包装类
    • String
  • 复杂类型 : 包含多个值
    • javabean实体类
    • 集合
    • 数组

输入映射之简单类型

  • 概述
    • 输入一个简单类型的值
  • 需求
    • 根据id查询记录
  • 代码实现
<select id="selectUserById1" parameterType="int" resultType="user">
    select *
    from tb_user
    where user_id = #{userId}
</select>

<select id="selectUserById2"  resultType="user">
    select *
    from tb_user
    where user_id = #{userId}
</select>

输入映射之零散简单类型

  • 概述
    • 输入多个简单类型的值
  • 需求
    • 根据账户和密码查询记录
  • 代码实现
<select id="selectUserByNameAndPwd1" resultType="user">
    select *
    from tb_user
    where user_name = #{param1}
      and user_pwd = #{param2}
</select>


<select id="selectUserByNameAndPwd2" resultType="user">
    select *
    from tb_user
    where user_name = #{userName}
      and user_pwd = #{userPwd}
</select>
User selectUserByNameAndPwd1(String userName , String userPwd) throws Exception;


User selectUserByNameAndPwd2(@Param("userName") String userName , @Param("userPwd") String userPwd) throws Exception;

输入映射之实体类型

  • 概述
    • Mybatis会根据#{}中传入的数据,加工成getXxx()方法,通过反射在实体类对象中调用这个 方法,从而获取到对应的数据。填充到#{}这个位置。
  • 需求
<select id="selectUserByNameAndPwd3" parameterType="user" resultType="user">
    select *
    from tb_user
    where user_name = #{userName}
      and user_pwd = #{userPwd}
</select>

<select id="selectUserByNameAndPwd4"  resultType="user">
    select *
    from tb_user
    where user_name = #{userName}
      and user_pwd = #{userPwd}
</select>
  • 注意事项
    • #{userName}应该和getUserName()方法名一致
    • parameterType="user"可以省略

输入映射之Map

  • 概述
    • 如果要输入多个简单类型的值,同时也找不到合适的javabean来进行封装,使用零散简单类 型(@Param)又太过复杂,此时就可以使用map封装,然后进行输入映射。
  • 代码实现
<select id="selectUserByMap" parameterType="map"  resultType="user">
    select *
    from tb_user
    where user_name = #{userName}
      and user_pwd = #{userPwd}
</select>


<select id="selectUserByMap2"   resultType="user">
    select *
    from tb_user
    where user_name = #{userName}
      and user_pwd = #{userPwd}
</select>
  • 注意事项
    • #{userName}和map的key一致
    • parameterType="map"可以省略

输出映射

概述

  • 输出映射,是在映射文件中通过resultType指定输出结果的类型。类型可以是简单类型、复 杂类型
  • 简单类型 : 包含一个值
    • 基本数据类型
    • 包装类
    • String
  • 复杂类型 : 包含多个值
    • javabean实体类
    • 集合
    • 数组

输出映射之简单类型

  • 概述
    • 输出一个简单类型的结果
  • 需求
    • 查询总记录数
  • 代码实现
<select id="selectTotalCount" resultType="long">
    select count(*)
    from tb_user
</select>

输出映射之实体类型

代码实现

<select id="selectUserById3" resultType="user">
    select user_id userId, user_name userName, user_pwd userPwd
    from tb_user
    where user_id = #{userId}
</select>

注意事项

  • SQL中的字段名称必须和javabean实体类的setXxx方法名一致

输出映射之Map

  • 概述
    • 适用于SQL查询返回的各个字段综合起来并不和任何一个现有的实体类对应,没法封装到实 体类对象中。能够封装成实体类类型的,就不使用Map类型。
    • map的键存储的是字段的名,map的值存储的是字段的值
  • 代码实现
<select id="selectUserById4" resultType="map">
    select *
    from tb_user
    where user_id = #{userId}
</select>

输出映射之List

  • 概述
    • 查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回。此时不需要任 何特殊处理,在resultType属性中还是设置实体类类型即可。
  • 代码实现
<select id="selectUserList" resultType="user">
    select *
    from tb_user
</select>

输出映射之ResultMap

  • 概述
    • 如果数据库中的字段名称(a_column)和实体类中的属性名称(aColumn)不一致,会导致输出映射不成功!
    • 可以通过设置别名、mapUnderscoreToCamelCase=true、resultMap来解决。
    • resultMap自定义映射规则来达到输出映射的目的
  • 代码实现
<!--自定义输出映射规则-->
<resultMap id="userMap" type="user">
    <id column="user_id" property="userId" javaType="Integer"></id>
    <result column="user_name" property="userName" javaType="String"></result>
    <result column="user_pwd" property="userPwd" javaType="String"></result>
    <result column="money" property="money" javaType="Double"></result>
</resultMap>

<select id="selectUserListByResultMap" resultMap="userMap">
    select *
    from tb_user
</select>

注意事项

  • 如果表中的字段名和类中的属性名一致,就不需要在resultMap中自定义映射规则,可以自动输出映射。

insert实现主键返回

  • 概述
    • 添加记录后,获取已添加的记录的自增长的主键值。
  • 分类
    • ①使用useGeneratedKeys属性
    • ②使用selectKey标签
  • ①使用useGeneratedKeys属性
<insert id="addUser1" useGeneratedKeys="true" keyColumn="user_id" keyProperty="userId">
    insert into tb_user
    values (null, #{userName}, #{userPwd}, #{money})
</insert>

②使用selectKey标签

动态sql

动态SQL之sql片段

  • 概述
    • 在开发中,SQL的拼接很常见,有很多的sql具有重复性高的特点,这时最好把重复的sql抽 取出来,作为公用的sql片段。
  • 代码实现
<!--定义SQL片段-->
<sql id="queryArgs">
    user_name , user_pwd
</sql>

<select id="selectUserLikeName1" parameterType="string" resultType="user">
    select
    /*使用SQL片段*/
    <include refid="queryArgs"></include>
    from tb_user
    where user_name like "%"#{userName}"%"
</select>

动态SQL之if标签

  • 概述
    • if标签可以根据条件动态地生成SQL语句
  • 需求
    • 如果账户和密码都没有就查询所有用户记录;
    • 如果只有账户,就根据账户查询用户记录;
    • 如果只有密码,就根据密码查询用户记录;
    • 如果账户和密码都有,就根据账户和密码查询用户记录。
  • 代码实现
<!--存在问题,SQL语句一成不变,无法达到需求-->
<select id="selectUserListByNameAndPwd" resultType="user">
    select *
    from tb_user
    where user_name = #{userName}
    and user_pwd = #{userPwd}
</select>
<select id="selectUserListByNameAndPwd2" resultType="user">
    select *
    from tb_user
    where 1 = 1
    <if test="userName!=null and userName!=''">
        and user_name = #{userName}
    </if>
    <if test="userPwd!=null and userPwd!=''">
        and user_Pwd = #{userPwd}
    </if>
</select>

存在问题

  • 不够优雅~~~

动态SQL之where标签

  • 概述
    • where标签会自动去掉标签体内前面多余的and/or
  • 代码实现
<select id="selectUserListByWhere" resultType="user">
    select *
    from tb_user
    <where>
        <if test="userName!=null and userName!=''">
            and user_name = #{userName}
        </if>
        <if test="userPwd!=null and userPwd!=''">
            and user_Pwd = #{userPwd}
        </if>
    </where>

</select>

动态SQL之trim标签

常用属性

属性说明
prefix如果条件成立,生成指定前缀
prefixOverrides如果条件成立,移除指定前缀
suffix如果条件成立,生成指定后缀
suffixOverrides如果条件成立,移除指定后缀

代码实现

<select id="selectUserListByTrim" resultType="user">
    select *
    from tb_user
    /*
        根据条件,动态地生成where关键字,动态地移除and或or,相当于where标签
    */
    <trim prefix="where" prefixOverrides="and|or">
        <if test="userName!=null and userName!=''">
            and user_name = #{userName}
        </if>
        <if test="userPwd!=null and userPwd!=''">
            and user_Pwd = #{userPwd}
        </if>
    </trim>

</select>

动态SQL之set标签

  • 概述
    • 动态地生成set关键字,会自动去掉标签体内后面多余的逗号
  • 需求
    • 根据id修改用户信息
  • 代码实现
<update id="updateUserById">
    update tb_user
    set
    <if test="userName!=null and userName!=''">
        user_name = #{userName},
    </if>
    <if test="userPwd!=null and userPwd!=''">
        user_pwd = #{userPwd},
    </if>
    where user_id = #{userId}
</update>
<update id="updateUserById">
    update tb_user
    <set>
        <if test="userName!=null and userName!=''">
            user_name = #{userName},
        </if>
        <if test="userPwd!=null and userPwd!=''">
            user_pwd = #{userPwd},
        </if>
    </set>

    where user_id = #{userId}
</update>

动态SQL之choose标签

  • 概述
    • 在多个分支条件中,仅执行一个,而后面的条件匹配都会被忽略
  • 代码实现
<select id="selectUserListByChoose" resultType="user">
    select * from tb_user
    <where>
        <choose>
            <when test="userName!=null and userName!=''">
                user_name = #{userName}
            </when>
            <when test="userPwd!=null and userPwd!=''">
                user_pwd = #{userPwd}
            </when>
        </choose>
    </where>
</select>

动态SQL之批量操作(foreach标签)

动态SQL之批量查询

  • 需求
    • 根据一组id查询多条用户记录
  • 代码实现
<!--
    方式一:select * from tb_user where user_id in(1,2,3)
-->
<select id="selectUserListByIds" resultType="user">
    select * from tb_user
    <where>
        user_id in
        <foreach collection="list" open="(" separator="," close=")" item="id">
            #{id}
        </foreach>
    </where>
</select>


<!--
    方式二:select * from tb_user where user_id = 1 or user_id = 2 or user_id = 3
-->
<select id="selectUserListByIds2" resultType="user">
    select * from tb_user
    <where>
        <foreach collection="list" separator="or" item="id">
            user_id = #{id}
        </foreach>
    </where>
</select>

动态SQL之批量添加

  • 加粗样式需求
    • 批量添加用户记录
  • 代码实现
<insert id="addUsers">
    insert into tb_user values
    <foreach collection="list" separator="," item="user">
        (null,#{user.userName},#{user.userPwd},#{user.money})
    </foreach>
</insert>

动态SQL之批量修改

  • 需求
    • 批量修改用户记录
  • 代码实现
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb1?allowMultiQueries=true
username=root
password=root
<update id="updateUsers">
    <foreach collection="list" separator=";" item="user">
        update tb_user set user_name = #{user.userName} where user_id = #{user.userId}
    </foreach>
</update>

动态SQL之批量删除

collection:传递来的参数,可以是list,array(数组),还可以是map的key,可以是pojo中的属性
item:循环中的当前元素
index:当前元素的下标
open:循环的开始
close:循环的结束
separator:分隔符


<delete id="deleteByIds" parameterType="list">
	delete from user where id in
	<foreach collection="list" item="id" open="(" close=")" separator=",">
		#{id}
	</foreach>
</delete>

多表关系设计回顾

  • 一对一 : 表A中的一条记录确定表B中的一条记录,表B中的一条确定表A中的一条记录
    • 比如:公司和注册地址
    • 一对一查询
  • 一对多:表A中的一条记录确定表B中的多条记录,表B中的一条记录确定表A中的一条记录
    • 比如:部门和员工
    • 一对一查询
    • 一对多查询
  • 多对多:表A中的一条记录确定表B中的多条记录,表B中的一条记录确定表A中的多条记录
    • 比如:老师和学生
    • 一对多查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值