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>

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ❤️设计模式肝完了,还挺全!腾讯和阿里的offer已拿!❤️

    ❤️设计模式肝完了,还挺全!腾讯和阿里的offer已拿!❤️设计模式肝完了,还挺全!腾讯和阿里的offer已拿!金九银十已经来了,挺近大厂最好的机会已经来了!如果你是要找工作的,一定要抓住这个机会!前面已经整理了很多的面试资料:1,❤️爆肝!整理了一周的Spring面试大全【含答案】,吊打Java面试官【建议收藏】!❤️2,❤️肝完了,一天掌握数据结构和算法面试题,吊打面试官,建议收藏❤️3,❤️集合很简单?开什么玩笑?肝了一周,全是精华,万字讲解!面试再不怕集合问题了!!!❤️4,肝完了,总结了SpringBoot与缓存的知识点,快速掌

    2022年6月10日
    23
  • POJ3623:Best Cow Line, Gold(后缀数组)

    POJ3623:Best Cow Line, Gold(后缀数组)

    2022年1月13日
    35
  • Mysql8.0以上重置初始密码的方法[通俗易懂]

    Mysql8.0以上重置初始密码的方法[通俗易懂]Mysql8.0以上忘记初始密码时重置的方法摘要第一步:关闭Mysql服务第二步:跳过Mysql密码验证第三步:无密码方式进入Mysql第四步:将登陆密码设置为空第五步:更改自己的登陆密码最后一步:验证密码是否修改成功摘要网上大部分的方法都是通过在My.ini或是My_default.ini中添加–skip-grant-tables的方法来实现跳过Mysql密码来连接数据库,并更改密码。我花…

    2022年5月31日
    33
  • sql语句面试经典50题_sql基础知识面试题

    sql语句面试经典50题_sql基础知识面试题目录​SQL基础知识整理:常见的SQL面试题:经典50题三、50道面试题2.汇总统计分组分析3.复杂查询sql面试题:topN问题4.多表查询【面试题类型总结】这类题目属于行列如何互换,解题思路如下:其他面试题:SQL基础知识整理:select查询结果如:[学号,平均成绩:组函数avg(成绩)]from从哪张表中查找数…

    2022年4月20日
    47
  • YUI Compressor

    YUI Compressor简介根据雅虎卓越性能团队的说法,40%到60%的雅虎用户拥有空闲缓存体验,所有页面浏览量中约有20%是使用空缓存完成的(请参阅TenniTheurer在YUIBlog上的这篇文章)有关浏览器缓存使

    2022年7月1日
    22
  • excel宏 java,Microsoft Excel宏运行Java程序

    excel宏 java,Microsoft Excel宏运行Java程序IhavelearnttoreadandwriteanExcelfileusingaJavaprogramwiththehelpofJxlandPOIAPI.IsitpossibletorunaJavaprogramwiththehelpofmacros?解决方案Yes,itispossible.Therearequit…

    2022年6月3日
    34

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

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