Mybatis常用的动态SQL标签讲解

先让我们看看mybatis常用动态SQL的标签有哪一些

在这里插入图片描述

如果mybatis和SSM整合环境不会搭建请看这篇

https://blog.csdn.net/weixin_44012722/article/details/105242601

我的数据库建表sql语句
create table student(
id int auto_increment PRIMARY KEY ,
name varchar(20) not null ,
department varchar(20) not null ,
sex varchar(10) not null ,
age int check(age>0) 
);

create table `group`(
id int auto_increment PRIMARY KEY ,
name varchar(255) not null
);

create table student2group(
id int auto_increment PRIMARY KEY ,
stuid int not null,
groupid int not null
);

create table evaluate(
id int auto_increment PRIMARY KEY,
stuid int not null,
score int not null 
);

1.insert,delete,update,select

这四个标签不用我多说了定义SQL语句的
	注意这几个属性意思:
		id:
		resultType:输出结果类型
		resultMap:输出结果结果映射
		parameterType:输入接收参数类型
		parameterMap:输入接收结果映射(一般很少用只有不写对象用Map接收参数的时候用,但是一般不写对象接收参数很难维护的 不能见名知意 可能会给队友后面的接盘侠 喷死)

2.reusltMap ,sql

结果集的一个映射
先简单看一下我的一个例子(这个常用在 结果集的映射和嵌套结果查询后面会讲)
mapper文件
<resultMap id="BaseResultMap" type="com.example.pojo.Student">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="department" jdbcType="VARCHAR" property="department" />
    <result column="sex" jdbcType="VARCHAR" property="sex" />
    <result column="age" jdbcType="INTEGER" property="age" />
  </resultMap>
  
  <sql id="Base_Column_List">
    id, `name`, department, sex, age
  </sql>
  
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from student
    where id = #{id,jdbcType=INTEGER}
  </select>
  <!--
		①resultMap:
				id:映射对象的主键
				result  -> column:数据库字段 
						->jdbcType:数据库类型
						->property:映射对象的字段变量名
		②sql:
			通常是写复用的sql语句,如果有大量相同的sql语句出现可用它装起来
			在需要此sql语句段地方用<include refid="sql标签的id" />引用即可
	-->
测试类
	@Test
    public void test6(){
        //使用元素查询特定id的部分学生信息
        System.out.println("使用元素查询特定id的部分学生信息 :" + studentService.selectByPrimaryKey(3));
    }
控制台结果

在这里插入图片描述

3.foreach

mapper文件
<select id="selectIDInScope" parameterType="java.util.List" resultType="com.example.pojo.Student">
    select * from student where id in
    <foreach collection="idScope" item="i" open="(" separator="," close=")">
        ${i}
    </foreach>
  </select>
  <!-- 
  		collection:是接收参数的变量名,这个变量可以是一个集合或者数组
		item:遍历集合或者数组的元素
  		open:开始内容
  		separator:间隔之间的内容
  		close:结束的内容
	 -->
测试类
	@Test
    public void test6_1(){
        //使用元素查询特定id的部分学生信息
        System.out.println("使用元素查询特定id的部分学生信息 :");
        studentService.selectIDInScope(Arrays.asList(new Integer [] {1,2,3})).forEach(System.out::println);
    }
控制台结果

在这里插入图片描述

4.if , trim

mapper文件
<insert id="insertSelective" parameterType="com.example.pojo.Student">
    insert into student
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="name != null">
        `name`,
      </if>
      <if test="department != null">
        department,
      </if>
      <if test="sex != null">
        sex,
      </if>
      <if test="age != null">
        age,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=INTEGER},
      </if>
      <if test="name != null">
        #{name,jdbcType=VARCHAR},
      </if>
      <if test="department != null">
        #{department,jdbcType=VARCHAR},
      </if>
      <if test="sex != null">
        #{sex,jdbcType=VARCHAR},
      </if>
      <if test="age != null">
        #{age,jdbcType=INTEGER},
      </if>
    </trim>
  </insert>

	<!--
		① if: test 判断语句(条件) 满足条件则加入if标签内的内容
		② trim:在trim标签内的内容去除空格
				prefix:开始的内容
				suffix:结束的内容
				suffixOverrides:结束内容前要去掉的内容
	-->
测试类
	@Test
    public void test10(){
        System.out.println("插入学生");
        Student student = new Student();
        student.setName("树懒");
        student.setDepartment("计算机系");
        student.setSex("男");
        student.setAge(22);
        System.out.println(studentService.insertSelective(student));
    }
结果

在这里插入图片描述

5.choose,when,otherwise

<select id="selectActivityAnd" resultType="com.example.pojo.Student">
    select
    <include refid="Base_Column_List" />
    from student where 1 = 1
    <choose>
      <when test="id != null ">
        and id = #{id}
      </when>
      <when test="name != null and name != ''">
        and name = #{name}
      </when>
      <when test="department != null and department != ''">
        and department = #{department}
      </when>
      <when test="sex != null and sex != ''">
        and sex = #{sex}
      </when>
      <otherwise>
        and age > 20
      </otherwise>
    </choose>
  </select>
	<!--
		choose和when以及otherwise要配合使用
		when: test:判断语句(条件)满足条件则加入when标签内的内容
		otherwise:choose内的when标签条件都不满足才加入otherwise标签内的内容
		和 switch case default很像
		注意:when 和 otherwise 标签内的内容都有一个and 所以要在choose标签的前面加上一个条件 1=1
	-->

6.where,bind

mapper文件
<select id="selectByNameDim" resultType="com.example.pojo.Student">
    <bind name="nameBind" value="'%'+name+'%'"/>
    select
    <include refid="Base_Column_List" />
    from student
    <where>
      <if test="name != null and name != ''">
        name LIKE #{nameBind}
      </if>
    </where>
  </select>
  <!--
  bind标签作用:
  	在进行模糊查询时,如果使用“${}”拼接字符串,则无法防止 SQL 注入问题
  	。如果使用字符串拼接函数或连接符号,但不同数据库的拼接函数或连接
  	符号不同。例如 MySQL 的 concat 函数、Oracle 的连接符号“||”,这样 
  	SQL 映射文件就需要根据不同的数据库提供不同的实现,显然比较麻烦,且不利
  	于代码的移植。幸运的是,MyBatis 提供了 <bind> 元素来解决这一问题。
  	bind -> name:绑定变量名
  		 -> value:绑定的值 里面的name是我接收参数的变量名
  		 是要在想用到的地方#{绑定的变量名}即可
	where : 相当于给标签内部的内容前面加一个where关键字

  -->
测试类
	@Test
    public void test7(){
        //使用元素模糊查询学生信息
        List<Student> students5 = studentService.selectByNameDim("大");
        students5.forEach(System.out::println);
    }
控制台结果

在这里插入图片描述

7.set

<update id="updateByPrimaryKeySelective" parameterType="com.example.pojo.Student">
    update student
    <set>
      <if test="name != null">
        `name` = #{name,jdbcType=VARCHAR},
      </if>
      <if test="department != null">
        department = #{department,jdbcType=VARCHAR},
      </if>
      <if test="sex != null">
        sex = #{sex,jdbcType=VARCHAR},
      </if>
      <if test="age != null">
        age = #{age,jdbcType=INTEGER},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
  <!--
	set:给set标签内的内容前面加上一个set关键字,where标签作用一样	
	-->
测试类

···java
@Test
public void test5(){
//使用元素实现学生信息的更新
Student condition4 = new Student();
System.out.println(“原本数据 :” + studentService.selectByPrimaryKey(1));
condition4.setId(1);
condition4.setName(“树懒”);
studentService.updateByPrimaryKeySelective(condition4);
System.out.println(“更新后数据 :” + studentService.selectByPrimaryKey(1));
}
···

控制台结果

在这里插入图片描述

8.association(用于一对一关系例如一个学生对应一个评估)

8.1嵌套查询
Student类添加一个evaluate成员变量

在这里插入图片描述

Student的mapper文件
<select id="selectStudentAndEvaluate" resultMap="studentEvalateMap">
        select id, name, department, sex, age  from student where id = #{id}
    </select>
    <resultMap id="studentEvalateMap" type="com.example.pojo.Student">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="department" property="department"/>
        <result column="sex" property="sex"/>
        <result column="age" property="age"/>
        <association property="evaluate" column="id" javaType="com.example.pojo.Evaluate" select="com.example.dao.EvaluateDao.selectByStuid" />
    </resultMap>
    <!--
    	association :
    		property:映射对象的成员变量的变量名
    		column:传给select查询语句的值
    		javaType:此关联查询对象的java类型
    		select:关联查询
	-->
Evaluate的mapper文件
	<select id="selectByStuid" resultType="com.example.pojo.Evaluate">
      select id, score, stuid from evaluate where stuid = #{stuid}
    </select>
测试类
    @Test
    public void test11(){
        System.out.println("association 嵌套查询");
        System.out.println(studentService.selectStudentAndEvaluate(1));
    }
控制台结果

在这里插入图片描述

8.2嵌套结果
Student的mapper文件
<select id="selectStudentAndEvaluate2" resultMap="studentEvalateMap2">
        select s.id,name,department,sex,age,e.id as eid,stuid,score from student s inner join evaluate e on s.id = e.stuid where s.id = #{id}
    </select>
    <resultMap id="studentEvalateMap2" type="com.example.pojo.Student">
        <id column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="department" property="department"/>
        <result column="sex" property="sex"/>
        <result column="age" property="age"/>
        <association property="evaluate" javaType="com.example.pojo.Evaluate">
            <id column="eid" property="id"/>
            <result column="stuid" property="stuid"/>
            <result column="score" property="score"/>
        </association>
    </resultMap>
    <!--
    	association :
    		property:映射对象的成员变量的变量名
    		javaType:此关联查询对象的java类型
	-->
测试类
	@Test
    public void test12(){
        System.out.println("association 嵌套结果");
        System.out.println(studentService.selectStudentAndEvaluate2(1));
    }
控制台的结果

在这里插入图片描述

9.collection(用于一对多关系例如一个学生对应多个群组)

9.1嵌套查询
Student类添加一个groups成员变量

在这里插入图片描述

Student的mapper文件
<select id="selectStudentAndGroup" resultMap="findGroupResult">
        select id,name,department,sex,age from student where id = #{id};
    </select>
    <resultMap id="findGroupResult" type="com.example.pojo.Student">
        <id column="id" property="id" />
        <result column="name" property="name" />
        <result column="department" property="department" />
        <result column="sex" property="sex" />
        <result column="age" property="age" />
        <collection property="groups" ofType="com.example.pojo.Group" column="id" select="com.example.dao.GroupDao.findGroup"/>
    </resultMap>
    <!--
    	collection:
    		property:映射对象的成员变量的变量名
    		column:传给select查询语句的值
    		ofType:此关联查询对象的java类型
    		select:关联查询
    -->
Group的mapper文件
<select id="findGroup" resultType="com.example.pojo.Group">
      select id,name from `group` where id in ( select groupid from student2group where stuid = #{id} )
   </select>
测试类
	@Test
    public void test8(){
        System.out.println("collection 嵌套查询");
        System.out.println(studentService.selectStudentAndGroup(1));
    }
控制台的结果

在这里插入图片描述

9.2嵌套结果
Student的mapper文件
<select id="selectStudentAndGroup2" resultMap="studentMap">
    select s.id,s.`name`,department,sex,age,g.id as gid,g.`name` as gname from student s inner join student2group ss on s.id = ss.stuid inner join `group` g on ss.groupid = g.id where s.id = #{id}
  </select>
    <resultMap id="studentMap" type="com.example.pojo.Student">
    <id column="id" property="id" />
    <result column="name" property="name" />
    <result column="department" property="department" />
    <result column="sex" property="sex" />
    <result column="age" property="age" />
        <collection property="groups" ofType="com.example.pojo.Group">
            <id column="gid" property="id" />
            <result column="gname" property="name" /> 
        </collection>
  </resultMap>
  <!--
    	collection:
    		property:映射对象的成员变量的变量名
    		ofType:此关联查询对象的java类型
    -->
测试类
	@Test
    public void test9(){
        System.out.println("collection 嵌套结果");
        System.out.println(studentService.selectStudentAndGroup2(1));
    }
控制台结果

在这里插入图片描述

总结

association是对一对一关系的关联查询
collection是对一对多关系的关联查询
他们用法属性相似 区别就在association的一个属性是javaType而collection的是ofType
对于多对多关系 Mybatis把它当做一对多来处理 所以不要过于追究。
关联查询又分为 嵌套结果 和 嵌套查询
从上面的例子可以看出 嵌套查询 是 拿着第一个SQL语句查询到的 字段 去作为查询条件执行第二个SQL语句 所以它是要经过两次SQL语句查询的
而 嵌套结果 是通过一个 连接表查询的SQL语句 把查询的结果字段 根据映射关系映射的结果集所以只用经过一个SQL语句查询
所以 嵌套查询 如果是数据库数据量大的不推荐使用 会拉低访问性能

10.插入数据返回主键

在这里插入图片描述使用这三个属性,插入完成后将主键放入对象中






一键查询淘宝/拼多多内部优惠券,每日大额外卖红包,购物省钱的宝藏工具
在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值