动态SQL,模糊查询,关联查询

2023-11-03

一.#{}和${}的区别

  • 相同点:这两个都是占位符,用来指定传入sql的参数
  • 不同点:
    • #{}这个是预编译的,不会发生sql注入,如果需要使用拼接的话可以使用sql的内置函数contact()
    • ${}这个是将其中的变量通过字符串拼接的方式插入到sql语句中的,容易发生sql注入,尽量避免使用

二.参数

1.多个参数

当我涉及到多个参数传参的时候,这个时候,我们直接使用变量名会发现控制台有错误提示
 Parameter ‘XXX’ not found. Available parameters are [arg1, arg0, param1, param2]
这一行报错的意思是XXX变量没有生命,我们可以用的变量名为arg1,arg0,param1,param2
当我们有多个变量的时候,我们就需要通过arg0,arg1来获取对应的变量了

// 接口方法
int updateNickname( int id,String nickname);
<update id="updateNickname">
  # 读取第二个变量nickname和第一个变量id
  update t_user set nickname = #{arg1} where id = #{arg0}
</update>

这种方式不是特别直观,当我们调整顺序之后,相应的xml里的顺序也需要调整,故我们一般会通过第二种方式来解决这个问题。通过注解的方式

// 接口方法
 int updateNickname( @Param("id") int id,@Param("nickname")String nickname);
    <update id="updateNickname">
        update t_user set nickname = #{nickname} where id = #{id}
    </update>

2.包装类型单个参数

java有八个基本数据类型,我们在使用这些基本数据类型,可以直接取到对应的value,比如我们上次课程中涉及到的int类型。
但是当我们的参数是包装类型时,比如String或者是User的实体类,这时mybatis就或读取包装类型中的属性,比如我们在使用User实体类时,直接使用实体类中的#{id}属性。但是String类型并没有对应的属性,我们希望的是直接获取String中的值,那么我们在取值的时候,就会出现这个错误。
 There is no getter for property named ‘xxx’ in ‘class java.lang.String’
这个报错的意思就是从String类型中获取不到xxx属性
这个使用我们也需要通过@Param的注解来解决这个问题

// 接口方法
List<User> selectList(@Param("orderBy") String orderBy);
<select id="selectList" parameterType="String" resultType="User">
    select * from t_user ${orderBy}
</select>

3.实体类参数与基本类型参数混用

直接看例子就明白了

// 接口方法
List<User> selectList(@Param("orderBy") String orderBy,@Param("user") User user);
<select id="selectList" resultType="User">
    select * from t_user where username = #{user.username} ${orderBy} 
</select>

三.paramerterType , resultType , resultMap

1.paramerterType

参数的类型

单个基本类型可以不写
参数有多种类型的时候不写
实体类必须写

2.resultType

返回值类型
除了查询,其他的都可以不写,因为其他的返回值都是int(默认影响的行数)

3.resultMap

返回值map
使用场景:
实体类与数据库表字段不一致,例如表中的字段是user_id,实体中的是userId,那么就需要进行一下映射,方法如下

<resultMap id = "mapName" type="User" autoMapping="ture">
<result column="user_id" property="userId">
</resultMap>

type映射实体的类型,比如user表映射的是User实体类
autoMapping="true"会自动的将同名的字段映射
result标签中的column对应的数据表的字段名,property对应的是实体类中的属性

四.动态SQL

直接上代码

1.StudentMapper接口

package com.tl.mybatis02.mapper;

import com.tl.mybatis02.model.Student;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author Antg
 * @date 2021/8/39:59
 */
public interface StudentMapper {

    /***************************** 动态sql ***********************************/
    //使用if语句
    public List<Student> find(Student student);

    //使用choose when otherwise
    public List<Student> useChoose(Student student);

    //where
    public List<Student> useWhere(Student student);

    //set
    public int useSet(Student student);

    //foreach 循环插入
    public int useForEach01(@Param("list01") List<Student> studentList);

    //foreach 循环in
    public List<Student> useForEach02(@Param("idList") Integer[] idList);

    //根据id查询
    public Student findStuById(@Param("id") Integer id);

    
}

2.StudentMapper.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.tl.mybatis02.mapper.StudentMapper">

    <resultMap id="stuResult" type="Student">
        <id column="id" property="id"/>
        <result column="username" property="username"></result>
        <result column="nickname" property="nickname"></result>
    </resultMap>

    <!-- ############################### 动态sql #################################  -->

    <!--动态sql 使用if-->
    <select id="find" parameterType="Student" resultMap="stuResult">
        select * from student_info where true
        <if test="username != null and username != ''">
            and username =
            #{username}
        </if>
        <if test="nickname != null and nickname != ''">
            and nickname like concat('%',
            #{nickname},
            '%'
            )
        </if>
    </select>

    <!--动态sql 使用choose-->
    <select id="useChoose" parameterType="Student" resultType="Student">
        select * from student_info where 1=1
        <choose>
            <when test="id != null">
                and id = #{id}
            </when>
            <when test="username != null and username != ''">
                and username = #{username}
            </when>
            <otherwise>
                and nickname = #{nickname}
            </otherwise>
        </choose>

    </select>

    <!--动态sql 使用where-->
    <select id="useWhere" parameterType="Student" resultMap="stuResult">
        select * from student_info
        <where>
            <if test="username != null and username != ''">
                and username =
                #{username}
            </if>
            <if test="nickname != null and nickname != ''">
                and nickname like concat('%',
                #{nickname},
                '%'
                )
            </if>
        </where>
    </select>

    <!--动态sql 使用set-->
    <update id="useSet">
        update student_info
        <set>
            <if test="username != null and username != ''">
                username =
                #{username},
            </if>
            <if test="nickname != null and nickname != ''">
                nickname =
                #{nickname},
            </if>
        </set>
        where id = #{id}
    </update>

    <!--动态sql 使用forEach循环插入-->
    <insert id="useForEach01">
        insert into student_info(username, password, nickname, age, birthday) values
        <foreach collection="list01" item="item" separator=",">
            (#{item.username}, #{item.password}, #{item.nickname}, #{item.age}, #{item.birthday})
        </foreach>
    </insert>

    <!--动态sql 使用forEach in查询-->
    <select id="useForEach02" resultType="Student">
        select * from student_info where id in
        <foreach collection="idList" item="item" separator="," open="(" close=")">
            #{item}
        </foreach>
    </select>


</mapper>

五.联查

1.一对一

接口

package com.tl.mybatis02.mapper;

import com.tl.mybatis02.model.Address;

public interface AddressMapper {
    /***************************** 一对一 ***********************************/
    public Address findAddressById(Integer id);

    public Address findAddressById2(Integer id);

    public Address findAddressById3(Integer id);

    /***************************** 一对多 ***********************************/
    public Address findById(Integer id);

}

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.tl.mybatis02.mapper.AddressMapper">

    <!-- ############################### 联查之一对一 #################################  -->

    <!-- 方法一: 使用select引入其他mapper中的方法-->
    <resultMap id="addressMap" type="Address" autoMapping="true">
        <!--        &lt;!&ndash;因为实体类和数据库中的字段不一样,所以要在这里映射一下&ndash;&gt;-->
        <result column="stu_id" property="stuId"></result>
        <association property="student" column="stu_id" javaType="Student"
                     select="com.tl.mybatis02.mapper.StudentMapper.findStuById"></association>
    </resultMap>
    <!--这里一定要写resultMap,切记不要写成resultType了,否则就不会找到上面写的Map-->
    <select id="findAddressById" parameterType="Integer" resultMap="addressMap">
        select *
        from address
        where id = #{id}
    </select>

    <!--方法二:直接进行联查-->
    <!--  可以使用resultMap配置映射字段,即数据库和javaBean中的对应字段,需要转换的字符可以在association中进行配置  -->
    <!-- 这里设置autoMapping可以进行自动封装-->
    <resultMap id="addressMap2" type="Address" autoMapping="true">
        <result column="id" property="id"/>
        <association property="student" column="stu_id" javaType="Student" autoMapping="true">
            <id column="stu_id" property="id"></id>
            <!-- 这里的id必须加,因为在进行联查的时候将Student的id是stu_id,而在实体类中是id,所以得进行一下转换,否则就将address中的id映射到了student中了 -->
        </association>
    </resultMap>
    <select id="findAddressById2" resultMap="addressMap2">
        select *
        from address a
                 inner join student_info s on a.stu_id = s.id
        where a.id = #{id}
    </select>

    <!--方法三:嵌套的resultType-->
    <resultMap id="addressMap3" type="Address" autoMapping="true">
        <association property="student" column="stu_id" resultMap="stuMap"></association>
    </resultMap>
    <resultMap id="stuMap" type="Student" autoMapping="true">
        <id column="stu_id" property="id"></id>
    </resultMap>
    <select id="findAddressById3" parameterType="Integer" resultMap="addressMap3">
        select a.id,
               stu_id,
               address,
               phone,
               consignee,
               username,
               password,
               nickname,
               age,
               birthday,
               del_state,
               create_time,
               update_time
        from address a
                 inner join student_info s on a.stu_id = s.id
        where a.id = #{id}
    </select>

</mapper>

2.一对多

接口

package com.tl.mybatis02.mapper;

import com.tl.mybatis02.model.Student;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * @author Antg
 * @date 2021/8/39:59
 */
public interface StudentMapper {

    /***************************** 一对多联查 ***********************************/
    //方法一:调用别的mapper中的方法
    public Student findoneToMany1(Integer id);

    //方法二:直接进行联查,在association中进行转换
    public Student findoneToMany2(Integer id);

    //方法三:嵌套resultMap
    public Student findoneToMany3(Integer id);
    
}

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.tl.mybatis02.mapper.StudentMapper">

    <!-- ############################### 一对多联查#################################  -->

    <!--  方法一:调用别的mapper中的方法  -->
    <resultMap id="studentMap1" type="Student" autoMapping="true">
        <id column="id" property="id"></id><!--这里的id有合并的作用,去掉后会查询出多条记录,就不对了-->
        <collection property="addressList" column="id" autoMapping="true"
                    select="com.tl.mybatis02.mapper.AddressMapper.findById"></collection>
    </resultMap>
    <select id="findoneToMany1" parameterType="Integer" resultMap="studentMap1">
        select *
        from student_info
        where id = #{id}
    </select>

    <!--  方法二:直接进行联查,在collection中进行转换  -->
    <resultMap id="studentMap2" type="Student" autoMapping="true">
        <id column="id" property="id"></id><!--这里的id有合并的作用,去掉后会查询出多条记录,就不对了-->
        <collection property="addressList" ofType="Address" autoMapping="true">
            <id column="address_id" property="id"></id>
        </collection>
    </resultMap>
    <select id="findoneToMany2" parameterType="Integer" resultMap="studentMap2">
        select s.id as id,
               username,
               password,
               nickname,
               age,
               birthday,
               a.id as address_id,
               stu_id,
               address,
               phone,
               consignee
        from student_info s
                 left join address a
                           on s.id = a.stu_id
        where s.id = #{id}
    </select>
    <resultMap id="findoneToMany3" type="Student" autoMapping="true">
        <id column="id" property="id"></id><!--这里的id有合并的作用,去掉后会查询出多条记录,就不对了-->
        <collection property="addressList" column="id" ofType="Address" resultMap="addressMap3"></collection>
    </resultMap>
    <resultMap id="addressMap3" type="Address">
        <id column="address_id" property="id"></id>
    </resultMap>
    <!--  方法三:嵌套resultMap  -->
    <select id="findoneToMany3" parameterType="Integer" resultMap="findoneToMany3">
        select s.id as id,
               username,
               password,
               nickname,
               age,
               birthday,
               a.id as address_id,
               stu_id,
               address,
               phone,
               consignee
        from student_info s
                 left join address a
                           on s.id = a.stu_id
        where s.id = #{id}
    </select>
</mapper>


 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态SQL,模糊查询,关联查询 的相关文章

随机推荐

  • 【python】 定义一个Person类,它包含数据成员age, name和gender。从Person中派生一个类Employee,在新类中添加一个数据成员,存储个人的number.等等

    定义一个Person类 它包含数据成员age name和gender a 从Person中派生一个类Employee 在新类中添加一个数据成员 存储个人的number 再从Employee中派生一个类Executive 每个派生类都应该定义
  • 商业智能BI专题报告(精选九篇)

    BI Business Intelligence 即商业智能 它是一套完整的解决方案 把企业的运营数据转化为信息或知识 辅助企业做出明智的业务经营决策的工具 将无序 零散 孤立的数据转换成整合的 规律的 有价值的数据资产 将其以直观 形象的
  • linux磁盘性能测试

    linux磁盘性能测试 1 测试磁盘写能力 time dd if dev zero of test db bs 8k count 1000000 oflag direct 因为 dev zero是一个伪设备 不产生IO 所以主要都集中在te
  • 传感器学习——DS18B20

    DS18B20 DS18B20是Dallas公司生产的数字温度传感器 具有体积小 适用电压宽 经济灵活的特点 它内部使用了onboard专利技术 全部传感元件及转换电路集成在一个形如三极管的集成电路内 DS18B20有电源线 地线及数据线3
  • 微信小程序线上加载使用iconfont问题

    1 在微信小程序根目录下创建style文件夹 里面再创建iconfont文件夹 用于放置iconfont图标文件和iconfont样式文件 2 给iconfont wxss写样式 也可以下载iconfont代码 拷贝iconfont css
  • PowerShell入门教程

    PowerShell基础语句 1 进入Powershell环境 开始 运行 powershell 开始 运行 cmd powershell 不同系统内置的powershell系统版本是不一样的 查看版本 psversiontable 2 p
  • 第十一篇 绘图matplotlib.pyplot的使用

    文章目录 摘要 安装方法 入门案例 使用plt绘图 使用ax绘图 plt figure参数 plot参数 案例一 绘制红色实心的点状图 案例二 绘制红色的破折线图 案例三 绘制两条线 颜色总结 设置标题 轴名称 图例 使用plt实现绘图 使
  • lua元表与面向对象

    lua元表 扩展普通表的行为 setmetatable tab mematable 如果元表中存在 mematable setmematable会失效 mematable可以保护元表 禁止访问或修改元表中的成员 getmetatable t
  • 原型对象和原型链的理解

    大家都应该知道构造函数很好用 但是构造函数也存在浪费内存的问题 function Star uname age this uname uname this age age this sing function console log 我会唱
  • 网御ACM上网行为管理系统存在SQL注入漏洞【小龙检测工具已更公开】

    网御ACM上网行为管理系统bottomframe cgi接口存在SQL注入漏洞 一 系统简介 二 漏洞描述 三 影响版本 四 fofa查询语句 五 漏洞复现 执行md5 1 函数 执行user 六 POC EXP 七 修复建议 免责声明 请
  • vscode 更新报错,中止以后软件打不开的修复方式

    前言 今天打开 vscode 正准备敲代码的时候 发现 vscode 提示升级 于是想也不想的点了升级 当然 你也可以在这里手动检查程序是否升级了 然后悲剧就发生了 升级到一半的时候 提示进行不下去了 问我是否要重试 或者终止 当时没截图
  • Qt天气预报

    目录 环境 weather pro main cpp weather h weather cpp weatherdata h 今天 未来6天数据体 weathertool h 获取城市编码工具类 ui weather h UI设计器生成的头
  • 【批处理DOS-CMD命令-汇总和小结】-利用cmd命令生成随机数、生成指定范围的随机数

    零 转载链接 bat脚本的基本命令语法 整合侠 博客园 一 cmd命令的随机数取值范围 RANDOM 系统变量只能返回 0 到 32767 之间的任意十进制数字 2的15次方等于32768 上面的0 32767实际就是15位二进制数的范围
  • git----pathspec ‘ ‘ did not match any file(s) known to git

    一 问题描述 场景 在前辈刚刚提交了自己的分支之后 我想切换过去 却发生了如下错误 在这之前你得确认你本地的代码提交且push 如果你的分支上没有代码改动的话 按如下操作解决 二 问题解决 首先查看分支情况 如果没有你想切换的分支名字 先获
  • OLED拼接屏,从选购到安装,手把手教您

    OLED拼接屏是一种高端的显示屏 它由多个OLED屏幕拼接而成 可以实现更大尺寸的显示效果 在使用OLED拼接屏时 需要注意一些细节 下面是OLED拼接屏的教程 1 选择合适的OLED屏幕 在选择OLED屏幕时 需要考虑屏幕的尺寸 分辨率
  • 嘉立创元器件及封装导入AD20

    第一步 建一个集成库 在集成库里添加原理图库和PCB元件库 第二步 在嘉立创软件或者网页里找到你要导入AD的元件 第三歩 将元件的原理图和封装分别以AD的格式导出 第四步 将导出的原理图和封装导入AD 第五步 将原理图生成原理图库 复制后粘
  • android studio第三方框架总结

    第三方框架gradle添加 UI Material design和Support library控件 compile com android support appcompat v7 25 3 1 compile com android s
  • 搭建一个Fabric网络

    生成相关证书文件 首先Fabric提供了一些工具用于生成所需的文件 cryptogen模块会根据提供的配置文件生成后续模块运行过程中需要的证书和数据文件 cryptogen常用命令 generate用于根据配置文件生成证书 showtemp
  • DS18B20使用说明

    DS18B20 温湿度监测模块 芯片介绍 基础介绍 引脚介绍 DS18B20是单总线协议的典型代表 同时也是单总线协议最广泛的应用场景 是常用的数字温度传感器 其输出的是数字信号 具有体积小 硬件开销低 抗干扰能力强 精度高的特点 DS18
  • 动态SQL,模糊查询,关联查询

    一 和 的区别 相同点 这两个都是占位符 用来指定传入sql的参数 不同点 这个是预编译的 不会发生sql注入 如果需要使用拼接的话可以使用sql的内置函数contact 这个是将其中的变量通过字符串拼接的方式插入到sql语句中的 容易发生