Mybatis详解动态SQL以及单表多表查询的应用

目录
  • 单表查询操作
    • 参数占位符#{}和${}
    • SQL 注入
    • like模糊查询
  • 多表查询操作
    • 一对一多表查询
    • 一对多多表查询
  • 动态SQL使用
    • if标签
    • trim标签
    • where标签
    • set标签
    • foreach标签

单表查询操作

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

  • #{}:相当于JDBC里面替换占位符的操作方式(#{}->“”).相当于预编译处理(预编译处理可以防止SQL注入问题)
  • ${}:相当于直接替换(desc这种关键字),但这种不能预防SQL注入
select * from userinfo where username='${name}'

${} VS #{}

  • ${}是直接替换,#{}是预执行;
  • ${} 会存在SQL 注入问题,#{}不存在SQL注入问题

SQL 注入

UserInfo userInfo = userMapper.login("admin","' or 1='1");

mysql> select * from userinfo where username = 'admin' and password ='' or 1='1';
+----+----------+----------+-------+---------------------+---------------------+-------+
| id | username | password | photo | createtime          | updatetime          | state |
+----+----------+----------+-------+---------------------+---------------------+-------+
|  1 | admin    | admin    |       | 2021-12-06 17:10:48 | 2021-12-06 17:10:48 |     1 |
+----+----------+----------+-------+---------------------+---------------------+-------+
1 row in set (0.00 sec)

like模糊查询

用concat进行字符串拼接

   <select id="findListByName" resultMap="BaseMap">
        select * from userinfo where username like concat('%',#{name},'%')
    </select>

多表查询操作

一对一多表查询

一对一的多表查询:需要设置resultMap中有个association标签,property对应实体类的属性名,resultMap是关联属性的字典映射(必须要设置),columnPrefix是设置前缀,当多表查询中有相同的字段的话,就会报错

<?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.demo.mapper.ArticleInfoMapper">
    <resultMap id="BaseMap" type="com.example.demo.model.ArticleInfo">
        <!--主键-->
        <id property="id" column="id"></id>
        <!--普通属性-->
        <result property="updatetime" column="updatetime"></result>
        <result property="title" column="title"></result>
        <result property="content" column="content"></result>
        <result property="createtime" column="createtime"></result>
        <result property="rcount" column="rcount"></result>
        <!--自定义对象属性-->
        <association property="user"
                     resultMap="com.example.demo.mapper.UserMapper.BaseMap"
                     columnPrefix="u_">
        </association>
    </resultMap>
    <select id="getAll" resultType="com.example.demo.model.ArticleInfo">
        select a.*,u.id from articleinfo as a left join userinfo as u on a.uid = u.id;
    </select>
    <select id="getAll2" resultMap="BaseMap">
        select a.*,u.id as u_id ,u.username as u_username,u.password as u_password from articleinfo as a left join userinfo as u on a.uid = u.id;
    </select>
</mapper>

一对多多表查询

collection标签,用法同association

 <resultMap id="BaseMapper2" type="com.example.demo.model.UserInfo">
        <!--映射主键的)(表中主键和程序实体类中的主键)-->
        <id column="id" property="id"></id>
        <!--普通列的映射-->
        <result column="username" property="name"></result>
        <result column="password" property="password"></result>
        <result column="photo" property="photo"></result>
        <result column="createtime" property="createtime"></result>
        <result column="updatetime" property="updatetime"></result>
        <!--外部关联-->
        <collection property="artlist" resultMap="com.example.demo.mapper.ArticleInfoMapper.BaseMap"
                    columnPrefix="a_"></collection>
    </resultMap>
 <select id="getAll3" resultMap="BaseMapper2">
        select u.*,a.id a_id,a.title a_title from userinfo u left join articleinfo a on u.id=a.uid
 </select>

动态SQL使用

if标签

注册分为必填和选填,如果在添加用户的时候有不确定的字段传入,就需要使用动态标签if来判断

//p是传递过来的参数名,并不是表的字段名
 <insert id="add3">
        insert into userinfo(username,password,
        <if test="p!=null">
         photo,
        </if>
         state)
        values(#{username},#{password},
        <if test="p!=null">
            #{p},
        </if>
       #{state})
 </insert>

trim标签

trim标签的属性

  • prefix:表示整个语句块,以prefix的值作为前缀
  • suffix:表示整个语句块,以suffix的值作为后缀
  • prefixOverrides:去掉最前面的符合条件的字符
  • suffixOverrides:去掉最后面的符合条件的字符
 <insert id="add4">
        insert into userinfo
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="username!=null">
                username,
            </if>
            <if test="password!=null">
                password,
            </if>
            <if test="p!=null">
                photo,
            </if>
            <if test="state!=null">
                state,
            </if>
        </trim>
        values
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="username!=null">
                #{username},
            </if>
            <if test="password!=null">
                #{password},
            </if>
            <if test="p!=null">
                #{p},
            </if>
            <if test="state!=null">
                #{state},
            </if>
        </trim>
    </insert>

where标签

where标签首先可以帮助我们生成where,如果有查询条件,那么就生成where,如果没有查询条件,就会忽略where

其次where标签可以判断第一个查询条件前面有没有and,如果有则会删除

  <select id="login2" resultType="com.example.demo.model.UserInfo">
        select * from userinfo
        <where>
        <if test="username!=null">
            username=#{username}
        </if>
        <if test="password!=null">
            and password=#{password}
        </if>
        </where>
    </select>

set标签

和where的使用基本一样

可以自动帮助你处理最后一个逗号,并且自动写set

    <update id="update" parameterType="map">
        update blog
        <set>
            <if test="newTitle != null">
                title=#{newTitle},
            </if>
            <if test="newAuthor != null">
                author=#{newAuthor},
            </if>
            <if test="newViews != null">
                views = #{newViews}
            </if>
        </set>
        <where>
            <if test="id != null">
                id=#{id}
            </if>
            <if test="title != null">
                and title=#{title}
            </if>
            <if test="author != null">
                and author=#{author}
            </if>
            <if test="views != null">
                and views = #{views}
            </if>
        </where>
    </update>

foreach标签

  • foreach属性:
  • collection:参数集合的名字
  • item:给接下来要遍历的集合起的名字
  • open:加的前缀是什么
  • close:加的后缀是什么
  • separator:每次遍历之间间隔的字符串
 <delete id="dels">
        delete from userinfo where id in
        <foreach collection="list" item="item" open="(" close=")" separator="," >
            #{item}
        </foreach>
 </delete>

到此这篇关于Mybatis详解动态SQL以及单表多表查询的应用的文章就介绍到这了,更多相关Mybatis动态SQL内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Mybatis超级强大的动态SQL语句大全

    目录 1. If 语句 2. Where语句 2.1 和 where 元素等价的自定义 trim 元素 3. Set语句 3.1 与 set 元素等价的自定义 trim 元素 4. Choose语句 5. Foreach语句 6. SQL片段 7. Bind元素 附:MyBatis配置动态SQL语句 总结 1. If 语句 需求:根据作者名字和博客名字来查询博客!如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询 <!--需求1: 根据作者名字和博客名字来查询博客! 如果作者名字

  • MyBatis动态SQL如何实现前端指定返回字段

    目录 动态SQL实现前端指定返回字段 问题描述 解决方案 MyBatis如何返回部分字段 .xml文件中resultMap的type改为 第二种很笨的方法 动态SQL实现前端指定返回字段 问题描述 在使用ClickHouse时,遇到需要根据业务需求,动态返回指定字段,从而充分利用ClickHouse列式存储的优势. 解决方案 可用MyBatis的动态SQL进行数据返回:故可在业务层将指定返回的列传入数据层,利用foreach标签进行遍历返回数据. 代码实现 1.请求参数 @Data public

  • MyBatis 超详细讲解动态SQL的实现

    目录 情景: 概述: SQL元素: <if>: <choose>: <where>: <trim>: <set>: <foreach>: <bind>: 情景: 我们在使用JDBC或者其他类似的框架开发进行数据库开发时,通常要根据需求动手组装SQL,不用想都觉得是件很痛苦的事情了,而Mybatis框架提供的对SQL语句动态组装的功能,能很好地解决这个麻烦. 概述: 动态SQL是MyBatis框架的一个强大特性,MyBati

  • MyBatis连接池的深入和动态SQL详解

    目录 一,Mybatis 连接池与事务深入 1.1 Mybatis 的连接池技术 1.1.1 Mybatis 连接池的分类 1.1.2 Mybatis 中数据源的配置 1.2 Mybatis 的事务控制 1.2.1 JDBC 中事务的回顾 1.2.2 Mybatis 中事务提交方式 1.2.3 Mybatis 自动提交事务的设置 二.Mybatis 的动态 SQL 语句 2.1 动态 SQL 之标签 2.1.1 持久层 Dao 接口 2.1.2 持久层 Dao 映射配置 2.1.3 测试 2.2

  • MyBatis深入解读动态SQL的实现

    目录 if和where trim Choose Set foreach mybatis最强大的功能之一便是它的动态sql能力 借用官方文档的一段话 : 如果您以前有使用JDBC或者类似框架的 经历,您就会明白把SQL语句条件连接在一起是多么的痛苦,要确保不能忘记空格或者不要在 columns列后面省略一个逗号等.动态语句能够完全解决掉这些痛苦. 那么如果没有这种功能到底有多痛苦呢 ? 我们来举例说明 这是一张表 , 试想如果我们通过 name 和 age来查询表信息时 , sql语句中肯定会存在

  • Mybatis在注解上如何实现动态SQL

    目录 在注解上实现动态SQL 注解的动态语句支持以下 注解方式动态sql写法和注意事项 判断字符串为空串 用单引号 大于等于用 小于等于用 在注解上实现动态SQL 使用Mybatis注解实现sql语句,但是有些时候有些字段是空的,这时候这个空的字段就要从条件查询语句中删除,这个时候就需要用到动态Sql. 注解的动态语句支持以下 trim where set foreach if choose when otherwise bind @Select({"<script> "

  • 一篇文章带你了解mybatis的动态SQL

    目录 1.动态SQL:if 语句 3.动态SQL:if+set 语句 4.动态SQL:choose(when,otherwise) 语句 5.动态SQL:trim 语句 6.动态SQL: SQL 片段 7.动态SQL: foreach 语句 8.总结 1.动态SQL:if 语句 根据 username 和 sex 来查询数据.如果username为空,那么将只根据sex来查询:反之只根据username来查询 首先不使用 动态SQL 来书写 <select id="selectUserBy

  • mybatis的动态SQL以及连接池详解

    目录 mybatis动态SQL及连接池 mybatis中的范围查询,in 连接池 动态sql与多表的连接查询 动态sql 多表的连接查询 小结 mybatis动态SQL及连接池 mybatis根据传入参数的不同来查询. <select id="findByCondition" parameterType="com.domain.User" resultType="com.domain.User">         select * f

  • 关于mybatis遇到Integer类型的参数时动态sql需要注意条件

    目录 mybatisInteger类型参数动态sql注意条件 例如以下拼接的动态sql mybatis的坑——Integer类型参数解析问题 有时候我们使用实体类传递参数时 因为mybatis在解析Integer类型数据时 mybatis Integer类型参数动态sql注意条件 例如以下拼接的动态sql <if test="work_status !=null  and work_status !='' ">  and T.status=#{work_status,jdb

  • Mybatis详解动态SQL以及单表多表查询的应用

    目录 单表查询操作 参数占位符#{}和${} SQL 注入 like模糊查询 多表查询操作 一对一多表查询 一对多多表查询 动态SQL使用 if标签 trim标签 where标签 set标签 foreach标签 单表查询操作 参数占位符#{}和${} #{}:相当于JDBC里面替换占位符的操作方式(#{}->“”).相当于预编译处理(预编译处理可以防止SQL注入问题) ${}:相当于直接替换(desc这种关键字),但这种不能预防SQL注入 select * from userinfo where

  • Mybatis详解在注解sql时报错的解决方法

    目录 错误: 文件结构 BookMapper.java BookMapperSQL .java Mybatis的配置文件 分析: 错误: 在做Mybatis用注解方式来注入sql的练习时,报了这样子的错误. 遇到错误很正常,然后我又从学了一遍今天刚刚学的内容,温故而知新嘛. 错误问题如下: 文件结构 BookMapper.java public interface BookMapper { @SelectProvider(type = BookMapperSQL.class,method = "

  • MyBatis实践之动态SQL及关联查询

    序言 MyBatis,大家都知道,半自动的ORM框架,原来叫ibatis,后来好像是10年apache软件基金组织把它托管给了goole code,就重新命名了MyBatis,功能相对以前更强大了.它相对全自动的持久层框架Hibernate,更加灵活,更轻量级,这点我还是深有体会的. MyBatis的一个强大特性之一就是动态SQL能力了,能省去我们很多串联判断拼接SQL的痛苦,根据项目而定,在一定的场合下使用,能大大减少程序的代码量和复杂程度,不过还是不是过度太过复杂的使用,以免不利于后期的维护

  • 详解通过SQL进行分布式死锁的检测与消除

    概述 分布式数仓应用场景中,我们经常遇到数据库系统 hang 住的问题,所谓 hang 是指虽然数据库系统还在运行,但部分或全部业务无法正常执行.hang 问题的原因有很多,其中以分布式死锁最为常见,本次主要分享在碰到死锁时,如何快速地解决死锁问题. GaussDB(DWS) 作为分布式数仓,通过锁机制来实行并发控制,因此也存在产生分布式死锁的可能.虽然分布式死锁无法避免,但幸运的是其提供了多种系统视图,能够保证在分布式死锁发生之后,快速地对死锁进行定位. 本文主要介绍了在 GaussDB(DW

  • MyBatis详解如何实现Dao层接口

    目录 传统开发方式 编写UserDao接口 编写UserDaompl实现 传统测试方法 代理开发方法 代理开发方式介绍 编写UserMapper接口 测试代理方法 传统开发方式 编写UserDao接口 public interface UserMapper { public List<User> findAll() throws IOException; } 编写UserDaompl实现 public class UserMapperImp implements UserMapper { @O

  • 详解Unique SQL原理和应用

    1.什么是Unique SQL 用户执行SQL语句时,每一个SQL语句文本都会进入解析器(Parser),生成"解析树"(parse tree).遍历解析树中各个结点,忽略其中的常数值,以一定的算法结合树中的各结点,计算出来一个整数值,用来唯一标识这一类SQL,这个整数值被称为Unique SQL ID,Unique SQL ID相同的SQL语句属于同一个"Unique SQL". 例如,用户先后输入如下两条SQL语句: select * from t1 where

  • MyBatis 详细讲解动态 SQL的使用

    目录 MyBatis 框架动态 SQL 环境准备 动态 SQL 之 if 动态 SQL 之 where 动态 SQL 之 foreach 动态 SQL 之代码片段 MyBatis 框架动态 SQL 动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句.这里的条件判断使用的表达式为 OGNL 表达式.常用的动态 SQL 标签有<if>.<where>.<choose/>.<foreach>等. MyBatis 的动态 S

  • MyBatis 详细讲解动态 SQL的使用

    目录 MyBatis 框架动态 SQL 环境准备 动态 SQL 之 if 动态 SQL 之 where 动态 SQL 之 foreach 动态 SQL 之代码片段 MyBatis 框架动态 SQL 动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句.这里的条件判断使用的表达式为 OGNL 表达式.常用的动态 SQL 标签有<if>.<where>.<choose/>.<foreach>等. MyBatis 的动态 S

  • 一文详解嵌入式SQL

    目录 嵌入式SQL概述 使用嵌入式SQL的注意事项 区分SQL语句与主语言语句 数据库工作单元和程序工作单元之间的通信 协调两种不同的处理方式 嵌入式SQL程序的组成 程序首都 程序体 在嵌入式SQL中使用游标检索多个元组 游标定义语句 游标打开语句 游标推进语句 游标关闭语句 嵌入式SQL程序实例 嵌入式SQL概述 嵌入式SQL(Embedded SQL) 是应用系统使用编程方式来访问和管理数据库中数据的主要方式之一. SQL语言有两种使用方式:一种是作为独立语言,以交互式方式使用,在这种方式

随机推荐