Mybatis 动态SQL

Mybatis 动态SQLMybatis动态SQL一.动态SQL数组array使用foreach标签<!–mybatis的集合操作知识点:如果遇到集合参数传递,需要将集合遍历标签:foreach循环遍历集合标签属性说明:1.collection表示遍历的集合类型1.1数组关键字array1.2List集合关键字lis

大家好,又见面了,我是你们的朋友全栈君。

Mybatis 动态SQL

一 .动态SQL

数组 array 使用foreach 标签

 <!-- mybatis的集合操作
        知识点: 如果遇到集合参数传递,需要将集合遍历
        标签: foreach 循环遍历集合
        标签属性说明:
            1.collection 表示遍历的集合类型
                1.1 数组      关键字 array
                1.2 List集合  关键字 list
                1.3 Map集合   关键字 Map中的key
            2. open  循环开始标签
               close 循环结束标签  包裹循环体
            3. separator 分割符
            4. item  当前循环遍历的数据的变量


      -->
    <select id="findIn" resultType="User">
        select * from demo_user where id in
            <foreach collection="array" open="(" close=")"
                separator="," item="id">
                #{id}
            </foreach>
    </select>


集合 collection 使用foreach 标签

 <select id="findInList" resultType="User">
        select * from demo_user where id in
        <foreach collection="list" open="(" close=")"
                 separator="," item="id">
            #{id}
        </foreach>
    </select>


Map集合操作

/**
     *  需求:
     *      查询id=1,3,5,6,7 并且sex="男"的用户
     *  Sql:
     *      select * from demo_user where id in (1,3....)
     *      and sex = "男"
     */



Mybatis 动态SQL

动态 sql-where-if

业务需求

说明: 用户传递了一个user对象, 要求根据user中不为null的属性查询数据.

<!-- 动态Sql语句
        核心思想: 自动判断是否为null,
                如果为null,该字段不参与sql
        动态Sql规则:
            1.  <if test="写判断条件,可以直接获取属性值"></if>
                    true: 会拼接 字段条件
                    false: 不会拼接字段条件
            2. 多余的关键字
                由于动态sql拼接必然会导致多余的and 或者 or
            3. where标签说明 可以去除 where后边多余的and 或者 or
    -->
    <select id="findSqlWhere" resultType="User">
        select * from demo_user
            <where>
                <if test="id != null"> id = #{id}</if>
                <if test="name != null">and name = #{name}</if>
                <if test="age != null ">and age  = #{age}</if>
                <if test="sex != null ">and sex  = #{sex}</if>
            </where>
    </select>

sql-set-if

业务需求

需求: 实现用户数据修改, 根据对象中不为null的数据完成修改操作

<!--
        set标签用法: 去除set条件中多余的,号
    -->
    <update id="updateSqlSet">
        update demo_user
            <set>
                <if test="name !=null"> name=#{name}, </if>
                <if test="age !=null">  age = #{age}, </if>
                <if test="sex !=null">  sex = #{sex} </if>
            </set>
            where id = #{id}
    </update>

动态 sql-分支结构语法

业务需求

需求: 根据属性查询数据, 如果name有值 按照name查询,否则按照年龄查询,如果name,age都没有 按照sex查询

需求分析:

	if(name !=null ){
		 name = #{name}
	}else if( age !=null){
		 age  = #{age}
	}else{
		 sex = #{sex}
	}

<!--
        如果只需要一个条件有效,则使用分支结构用法.
    -->
    <select id="findChoose" resultType="User">
        select * from demo_user
        <where>
            <choose>
                <when test="name !=null">
                    name = #{name}
                </when>
                <when test="age !=null">
                    age = #{age}
                </when>
                <otherwise>
                    sex = #{sex}
                </otherwise>
            </choose>
        </where>
    </select>

二. Mybatis关联查询

创建新项目

选择项目

Mybatis 动态SQL

编辑POM.xml文件

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>


        <!--引入插件lombok 自动的set/get/构造方法插件  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>


        <!--mybatis依赖包-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>


        <!--jdbc依赖包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>


    </dependencies>

复制配置文件

Mybatis 动态SQL

创建表

创建员工表

emp_id int 主键自增

emp_name varchar(40)

dept_id int

表数据结构

Mybatis 动态SQL

添加内容

Mybatis 动态SQL

创建部门表

dept部门表

dept_id int 主键自增

dept_name varchar(40)

表数据结构

Mybatis 动态SQL

表数据

Mybatis 动态SQL

创建POJO对象

Emp

package com.jt.pojo;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;


import java.io.Serializable;


@AllArgsConstructor
@NoArgsConstructor
@Data
@Accessors(chain = true)
public class Emp implements Serializable {
    private Integer empId;
    private String  empName;
    //关联关系 1: 一个员工对应一个部门
    private Dept dept;
}

Dept

package com.jt.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import java.io.Serializable;
import java.util.List;


@Data
@Accessors(chain = true)
@NoArgsConstructor
@AllArgsConstructor
public class Dept implements Serializable {
    private Integer deptId;
    private String deptName;
    //一个部门对应多个员工
    private List<Emp> emps;
}

完成一对一封装

<?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.jt.mapper.EmpMapper">


    <!-- 一对一关联查询 -->
    <select id="findAll" resultMap="empRM">
        select e.emp_id,e.emp_name,
               d.dept_id,d.dept_name
	    from emp e,dept d
	    where e.dept_id = d.dept_id
    </select>


    <!--3.完成一对一封装
        固定用法:
            1.association: 将结果集封装为单独的对象 dept
            2.property 需要封装的属性名称
            3.javaType 固定写法: 属性的类型
    -->
    <resultMap id="empRM" type="Emp">
        <!--1.主键字段 -->
        <id property="empId" column="emp_id"></id>
        <!--2.映射其它属性字段-->
        <result property="empName" column="emp_name"></result>
        <association property="dept" javaType="Dept">
            <!--3.完成dept对象的封装-->
            <id property="deptId" column="dept_id"/>
            <result property="deptName" column="dept_name"/>
        </association>
    </resultMap>


</mapper>

一对多

业务场景

说明: 一个部门有多个员工

0d6c54a92a942b804134191c97335893.png

/*内连接的另外的一种表现形式.*/
SELECT d.dept_id,d.dept_name,e.emp_id,e.emp_name
	FROM dept d,emp e
	WHERE e.dept_id = d.dept_id

完成一对多封装

<?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.jt.mapper.DeptMapper">
    
    <select id="findAll" resultMap="deptRM">
        select d.dept_id,d.dept_name,e.emp_id,e.emp_name
	from dept d,emp e
	where e.dept_id = d.dept_id
    </select>


    <!--Mybatis的映射,一般都是一级封装 -->
    <resultMap id="deptRM" type="Dept">
        <!--指定主键-->
        <id column="dept_id" property="deptId"/>
        <!--封装其它的属性字段-->
        <result column="dept_name" property="deptName"/>
        <!--封装集合 属于同一个部门下的员工,封装到一个集合中 -->
        <collection property="emps" ofType="Emp">
            <id column="emp_id" property="empId"/>
            <result column="emp_name" property="empName"/>
        </collection>
    </resultMap>
</mapper>

 接口文档说明

  • 请求路径 /rights/getRightsList

  • 请求类型 GET

  • 请求参数 无

  • 响应数据 SysResult对象

status

状态信息

200表示服务器请求成功 201表示服务器异常

msg

服务器返回的提示信息

可以为null

data

服务器返回的业务数据

返回权限List集合

参数名称

参数说明

备注

响应数据如图所示

Mybatis 动态SQL

 父子关系封装/Sql语句写法

要求: 查询所有一级菜单和一级菜单所对应的二级菜单 要求关联查询

SELECT p.id,p.name,p.parent_id,p.path,p.level,p.created,p.updated,
       c.id c_id,c.name c_name,c.parent_id c_parent_id,c.path c_path,
       c.level c_level,c.created c_created,c.updated c_updated
	FROM 
rights p 
	LEFT JOIN	
rights c
	ON 
	 c.parent_id = p.id
WHERE p.parent_id = 0

编辑RightsController

@RestController
@CrossOrigin
@RequestMapping("/rights")
public class RightsController {


    @Autowired
    private RightsService rightsService;


    /**
     * 查询一级二级数据
     * URL: /rights/getRightsList
     * 参数: 无
     * 返回值: SysResult(List<Rights>)
     */
    @GetMapping("/getRightsList")
    public SysResult getRightsList(){


        List<Rights> rights = rightsService.getRightsList();
        return SysResult.success(rights);
    }
}

sql

<mapper namespace="com.jt.mapper.RightsMapper">


    <select id="getRightsList" resultMap="rightsRM">
       select p.id,p.name,p.parent_id,p.path,p.level,p.created,p.updated,
       c.id c_id,c.name c_name,c.parent_id c_parent_id,c.path c_path,
       c.level c_level,c.created c_created,c.updated c_updated
	    from
            rights p
	    left join
            rights c
	    on
	        c.parent_id = p.id
        where p.parent_id = 0
    </select>


    <resultMap id="rightsRM" type="Rights" autoMapping="true">
        <id column="id" property="id"/>
        <!--一对一封装子级菜单List集合-->
        <collection property="children" ofType="Rights">
            <!--封装主键ID-->
            <id column="c_id" property="id"/>
            <result column="c_name" property="name"/>
            <result column="c_parent_id" property="parentId"/>
            <result column="c_path" property="path"/>
            <result column="c_level" property="level"/>
            <result column="c_created" property="created"/>
            <result column="c_updated" property="updated"/>
        </collection>
    </resultMap>
</mapper>

编辑RightsService

Mybatis的子查询

子查询原理

矛盾点:

1. 如果想简化Sql,则映射文件肯定复杂.

2. 如果想简化映射文件, 则Sql语句复杂.

案例说明: 需求 简化Sql, 那么映射文件复杂.

62c3894740f7f02781f20e715d19e531.png

 <!--
        子查询本质特点: 将多表关联查询, 转化个多个单表查询.
    -->
    <select id="selectChildren" resultMap="cRM">
        select * from dept
    </select>


    <!--子查询:
        1.标签: select  进行二次查询
        2.关联字段信息:  column="dept_id" 将字段的值作为参数 传递给子查询
    -->
    <resultMap id="cRM" type="Dept">
        <id column="dept_id" property="deptId"/>
        <result column="dept_name" property="deptName"/>
        <!--数据集合封装-->
        <collection property="emps" ofType="Emp" select="findEmp" column="dept_id">
        </collection>
    </resultMap>


    <select id="findEmp" resultMap="empRM">
        select * from emp where dept_id = #{dept_id}
    </select>


    <resultMap id="empRM" type="Emp">
        <id column="emp_id" property="empId"/>
        <result column="emp_name" property="empName"/>
    </resultMap>


驼峰映射

 <!--查询用户信息  开启驼峰映射规则
        resultType:
                1.适用与单表查询,同时要求属性名称与字段相同.
                2.如果属性与字段满足驼峰命名规则,开启驼峰映射之后,
                  可以使用resultType
        resultMap:
                1.如果字段不一致时使用
                2.多表关联查询时使用.
                3.如果开启了驼峰映射规则, 则自动映射的属性可以省略,最好标识主键
                4.如果使用驼峰规则映射时,需要映射封装对象时(一对一/一对多),默认条件下.驼峰规则失效.
                  可以使用: autoMapping="true" 要求开启驼峰映射.
                5.默认条件下 一对一,一对多不会自动完成驼峰规则映射.
                  需要配置 autoMapping="true"才能自动映射
     -->
    <select id="getAll" resultMap="getEmpMap">
        select e.emp_id,e.emp_name,
               d.dept_id,d.dept_name
	    from emp e,dept d
	    where e.dept_id = d.dept_id
    </select>
    <resultMap id="getEmpMap" type="Emp" autoMapping="true">
        <id column="emp_id" property="empId"/>
        <!--其它属性自动映射-->
        <!--实现部门映射-->
        <association property="dept" javaType="Dept" autoMapping="true">
            <id column="dept_id" property="deptId"/>
        </association>
    </resultMap>

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/152515.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • origin柱状图显示具体数据值

    origin柱状图显示具体数据值1.双击需要显示数据的那一列比如双击蓝色这一列,所有的这一列数据都会选中2.打开绘图细节-绘图属性,选中标签3.点击启用4.选择标签形式’Y’5.选择数值显示格式*3*即可显示,然后调整位置即可…

  • centos 镜像源_孩子镜像问题怎么解决

    centos 镜像源_孩子镜像问题怎么解决CentOS8阿里新镜像源【旧的已经弃用】欢迎使用Markdown编辑器你好!这是你第一次使用Markdown编辑器所展示的欢迎页。如果你想学习如何使用Markdown编辑器,可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。新的改变我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客:全新的界面设计,将会带来全新的写作体验;在创作中心设置你喜爱的代码高亮样式,Markdown将代码片

  • 基于深度学习的人脸识别考勤系统设计

    基于深度学习的人脸识别考勤系统设计基于深度学习的人脸识别考勤系统

    2022年10月23日
  • Linux文件系统类型介绍[通俗易懂]

    Linux文件系统类型介绍[通俗易懂]Linux把设备都当作文件一样来进行操作,这样就大大方便了用户的使用(在后面的Linux编程中可以更为明显地看出)。在Linux下与设备相关的文件一般都在/dev目录下,它包括两种,一种是块设备文件,另一种是字符设备文件。这就涉及到文件系统,以下介绍以下Linux文件系统。 1.ext2和ext3 ext3是现在Linux(包括RedHat,Mandrake下…

  • Step by Step WCF—Transactions

    Step by Step WCF—Transactions

  • C#多线程编程_wpf和winform的区别

    C#多线程编程_wpf和winform的区别目录1.多线程描述2.线程生命周期3.线程的常用属性与方法4.线程操作(1)创建线程(2)管理线程(3)销毁线程1.多线程描述线程被定义为程序的执行路径。每个线程都定义了一个独特的控制流。在多线程之下可以通过分配线程,同时处理多个任务。2.线程生命周期线程生命周期开始于System.Threading.Thread类的对象被创建时,结束于线程被终止或完成执行时。下面列出了线程生命周期中的各种状态:未启动状态:当线程实例被创建但Start方法未被调用时的状况。就绪状

    2022年10月21日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号