【Day 9】Mybatis CURD + XML 映射 + 动态 SQL

news2024/12/26 11:34:39

1 Mybatis 基础操作

下面进行:增删改查——C(create)U(update)R(retrieve)D(delete)

1.1 删除(删)

根据主键 id 进行删除

注意 占位符 #{ }

返回值是删除的记录条数

测试:

可以在日志中看到 mybatis 具体的语句

预编译 SQL 的优点:

  • 性能更高
  • 更安全(防止 SQL 注入)

        SQL 注入:是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法

        1 等于 1 是true,所以结果是 16,即查到了所有人,但是是大于 0 的,系统判断登录成功,可以进入系统

使用预编译 SQL:

就是使用 占位符 #{ }

Mybatis 占位符

1.2 插入(增)

在 Mapper 里面写 insert 接口方法

注意:

  • emp 的字段采用驼峰命名,而数据库的 emp 表,是用下划线命名(这样更直观)所以在填写 values 的时候,需要看清楚
  • id 不用填写,id 是自增(increment)
  • password 也不用填写,password 是默认'123456'

然后测试

如果需要拿到插入的员工的主键:

@Insert("insert into emp (username, name, gender, image, job, entrydate, dept_id, create_time, update_time)\n" +
            "values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, now());")
public int insert(Emp emp);

1.3 更新(改)

@Update("update emp set username=#{username}, name=#{name}, gender=#{gender}, image=#{image},job=#{job}," +
            "entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
public void update(Emp emp);

1.4 查询(查)

@Select("select * from emp where id=#{id}")
public Emp select(Integer id);

但是注意看,后面三个是 null 值

在数据库中查询,就不是 null 值

是因为 Emp 类字段 和 数据库表属性 不一致

解决方案一:起别名

@Select("select id, username, password, name, gender, image, job, entrydate, dept_id deptId," +
            " create_time createTime, update_time updateTime from emp where id=#{id}")
public Emp select(Integer id);

解决方法二:手动封装

// 解决方案二:通过 @Results,@Result 手动封装
@Results({
    @Result(column = "dept_id",property = "deptId"),
    @Result(column = "create_time", property = "createTime"),
    @Result(column = "update_time",property = "updateTime")
    })
@Select("select * from emp where id = #{id}")
public Emp select(Integer id);

解决方法三:开启 mybatis 的驼峰命名自动映射开关

a_column         =>         aColumn

开启之后,直接按原来的写:

// 解决方案三:开启 mybatis 的驼峰命名自动映射开关
@Select("select * from emp where id=#{id}")
public Emp select(Integer id);

以上三种方法都会得到正确字段:

下面是条件查询:

输入张,性别,入职日期,结果根据更新日期降序

@Select("select * from emp where name like '%${name}%' and gender = #{gender} and entrydate between #{begin} " +
            "and #{end} order by update_time desc")
    public List<Emp> selectByCondition(@Param("name") String name,
                                       @Param("gender") Short gender,
                                       @Param("begin") LocalDate begin,
                                       @Param("end") LocalDate end);

注:

  • 要正确地映射,使用注解@Parm
  • 而且 name 是 ${name}

另:由于 name 使用了 ${name},这不是预编译 SQL,会导致性能差,SQL 注入

解决办法:

使用 MySQL 自带的 concat 方法,进行字符串拼接

2 XML 映射文件

Mybatis 操作数据库有两种方法

  • 注解
  • XML 映射文件

 注意创建文件夹的名字

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.example.mapper.EmpMapper">
    
</mapper>

2.1 MybatisX

IDEA 插件,用来简化 mybatis 

2.2 到底用注解还是 XML

3 动态 SQL(终于讲到这一点了)

        为什么说“终于讲到这一点了”,

        因为之前我就有个疑问,如果我只想查一下姓张的人,我不指定性别和入职日期,以前那个代码就查询不了:

@Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and entrydate between #{begin} " +
            "and #{end} order by update_time desc")
public List<Emp> selectByCondition(@Param("name") String name,
                                       @Param("gender") Short gender,
                                       @Param("begin") LocalDate begin,
                                       @Param("end") LocalDate end);

动态 SQL:随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态 SQL

Mybatis 中有很多动态 SQL 标签

  • <if>
  • <foreach>
  • <sql><include>

3.1 <if>

在 XML 里面去写

注意:and 要在新的一行里面写,之前我在行尾写,那样不行

<mapper namespace="com.example.mapper.EmpMapper">

    <select id="selectByCondition" resultType="com.example.pojo.Emp">
        select *
        from emp
        where
            <if test="name!=null">
                name like concat('%',#{name},'%')
            </if>
            <if test="gender!=null">
                and gender = #{gender}
            </if>
            <if test="begin!=null">
                <if test="end!=null">
                    and entrydate between #{begin} and #{end}
                </if>
            </if>
        order by update_time desc
    </select>
</mapper>

这样就可以查到只姓张的人了

注意:判断入职日期,也可以在中间用 and,就不用像我那样两层 if:

<if test="begin!=null and end!=null">

</if>

但是对于只输入性别,其他三个字段都为 null,又报错

@Test
    public void testSelectGender(){
        List<Emp> empList = empMapper.selectByCondition(null, (short) 1, null, null);
        empList.stream().forEach(System.out::println);
    }

因为 name 为 null,在 XML 里面跳过name,直接到 gender,where 直接以 and 开头了,

解决办法:把 where 改为 <where>

标签版的 where 可以自动去掉 and 或者 or,并且在条件都不成立的情况下去掉 where(真的智能)

3.2 关于之前 update 的动态 SQL

之前的 update 存在问题

正常应该是传过来什么字段,就更新什么字段,没有就不变

但是现在是没有字段的情况下,直接设置为 null

解决:使用动态 SQL

就不用注解了,把之前代码注释掉

    // 这段代码有问题,现在不用了,在 XML 重写了
//    @Update("update emp set username=#{username}, name=#{name}, gender=#{gender}, image=#{image},job=#{job}," +
//            "entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} where id=#{id}")
public void update(Emp emp);

在 XML 里加 

<update id="update"> #  更新不需要返回什么东西,所以没有属性 resultType
        update emp
        set
            <if test="username!=null">username=#{username}</if>
            <if test="name!=null">,name=#{name}</if>
            <if test="gender!=null">,gender=#{gender}</if>
            <if test="image!=null">,image=#{image}</if>
            <if test="job!=null">,job = #{job},</if>
            <if test="entrydate!=null">,entrydate=#{entrydate}</if>
            <if test="deptId!=null">,dept_id=#{deptId}</if>
            <if test="createTime!=null">,create_time=#{createTime}</if>
            <if test="updateTime!=null">,update_time = now()</if>
        where id=#{id}

    </update>

 这一次我们把第20个人,张测试,把他性别改成女,其他的字段不变:

 还是像上次一样,set 也有标签版本的 <set>

用标签版本的 set 更好

3.3 <foreach>

批量删除:

 MySQL 语句:

delete from emp where id in (18,19,20);

现在是 Mybatis:

EmpMapper 里面添加:

 然后alt + 回车在 XML <mapper>里面写

<!--
            批量删除员工 delete from emp where id in(18,19,20)

            collection 遍历的集合
            item 遍历的元素
            separator 分隔符
            open 遍历开始前拼接的 SQL 片段
            close 遍历结束后拼接的 SQL 片段
-->
    <delete id="deleteByIds">
        delete from emp where id in
            <foreach collection="list" item="id" separator="," open="(" close=")">
                #{id}
            </foreach>
    </delete>

 测试(没有 17 是因为之前删除过)

3.4 <sql><include>

这两个标签解决代码复用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1627628.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Taro +vue3 中实现全局颜色css变量的设置和使用

当我们现在需要弄一个随时修改的页面颜色主题色 我们可以随时修改 我使用的是 Taro 框架 一般有一个app.less 文件 我们在这个里面 设置一个root 全局样式 :root {--primary-color: #028fd4;--secondary-color: #028fd6;/* 添加其他颜色变量 */ } 这样在全局我们就可以使用这…

调度问题变形的贪心算法分析与实现

调度问题变形的贪心算法分析与实现 一、问题背景与算法描述二、算法正确性证明三、算法实现与分析四、结论 一、问题背景与算法描述 带截止时间和惩罚的单位时间任务调度问题是一个典型的贪心算法应用场景。该问题的目标是最小化超过截止时间导致的惩罚总和。给定一组单位时间…

【python】语言学习笔记--用来记录总结

请问以下变量哪些是tuple类型&#xff1a; a ()b (1)c [2]d (3,)e (4,5,6)answer在Python中&#xff0c;元组&#xff08;tuple&#xff09;是由逗号分隔的一组值组成的有序序列&#xff0c;通常用圆括号括起来。让我们逐个检查变量&#xff0c;看哪些是元组类型&#xff…

python中怎么注释多行

多行代码注释 方法一&#xff1a;先选中要注释的段落&#xff0c;然后按下“ctrl/”&#xff0c;即可实现多行代码的注释。效果如下&#xff1a; 再一次按下“ctrl/”就可以取消注释。 方法二&#xff1a;跟注释单行一样在每一行前面输入“shift#”。 #r(i-arr[idx])*rat[idx]…

计算机网络大框架图形

如标题&#xff0c;精心画了一个计算机网络的框架性的图&#xff0c;包含了计算机网络的核心思想&#xff0c;在此分享和备份下。各层具体协议参考TCP/IP常用协议栈图解-CSDN博客

JavaScript创建和填充数组的更多方法

空数组fill()方法创建并填充数组 ● 我们之前创建数组的方式都是手动去创建去一个数据&#xff0c;例如 console.log([1, 2, 3, 4, 5, 6, 7]);● 当然我们也可以使用Array对象来构造数组 console.log([1, 2, 3, 4, 5, 6, 7]); console.log(new Array(1, 2, 3, 4, 5, 6, 7));…

SQL异常

异常 EXCEPTION 预定义异常 系统已经设置好的异常&#xff0c;包含了异常名&#xff0c;异常代码&#xff0c;异常信息组成 CASE NOT FOUND 未知异常&#xff1a;OTHERS 异常信息&#xff1a;SQLERRM 错误代码&#xff1a;SQLCODE 有各种各样的很多异常 捕获异常的语法 DE…

codeforce#933 题解

E. Rudolf and k Bridges 题意不讲了&#xff0c;不如去题干看图。 传统dp&#xff0c;每个点有两个选择&#xff0c;那么建桥要么不建。需要注意的是在状态转移的时候&#xff0c;桥是有长度的&#xff0c;如果不建需要前d格中建桥花费最少的位置作为状态转移的初态。 #incl…

ubuntu 24.04 beta server NAT模式上网设置

在Ubuntu 24.04 Beta上设置网络通常涉及使用命令行工具。以下是设置静态IP地址和动态IP地址的步骤&#xff1a; 动态IP设置&#xff1a; 查找你的网络接口名称&#xff1a; ip a ens37是我NAT模型的一张网卡&#xff0c;此时是没有ip的。 下面介绍如何NAT模式下添加DHCP动态…

网络安全实训Day24(End)

写在前面 并没有完整上完四个星期&#xff0c;老师已经趁着清明节假期的东风跑掉了。可以很明显地看出这次持续了“四个星期”实训的知识体系并不完整&#xff0c;内容也只能算是一次基础的“复习”。更多的内容还是靠自己继续自学吧。 网络空间安全实训-渗透测试 文件包含攻击…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 4月27日,星期六

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年4月27日 星期六 农历三月十九 1、 教育部&#xff1a;深入实施学生欺凌防治专项行动&#xff0c;对所有中小学校开展起底式大排查。 2、 商务部等七部门联合印发《汽车以旧换新补贴实施细则》&#xff0c;购车最高补贴1万…

游戏发行困境及OgGame云游戏解决方案简述

随着全球化浪潮的持续推进&#xff0c;中国游戏开发者们不再满足于国内市场的发展&#xff0c;而是开始将目光投向更为广阔的海外市场。这一趋势的崛起背后&#xff0c;是中国企业意识到国际化是其发展的必由之路&#xff0c;也是游戏行业突破国内困境的体现。本文将简要阐述游…

Java集合框架-Collection-Set-HashSetTreeSetLinkedHashSet简介

目录 一、HashSet概述底层数据结构常用方法 二、TreeSet概述底层数据结构常用方法 三、LinkedHashSet概述底层数据结构常用方法 一、HashSet 概述 HashSet 是 Java 中的一个集合类&#xff0c;它实现了 Set 接口&#xff0c;用于存储不重复的元素。它基于 HashMap 实现(对Hash…

【WEEK9】 【DAY5】Web开发静态资源处理【中文版】

2024.4.26 Friday 目录 7.Web开发静态资源处理7.1.Web开发探究7.1.1.简介7.1.2.使用SpringBoot的步骤&#xff1a;7.1.2.1.创建一个SpringBoot应用&#xff0c;选择我们需要的模块&#xff0c;SpringBoot就会默认将我们的需要的模块自动配置好7.1.2.2.手动在配置文件中配置部分…

.NET Core Swagger运行异常

遇到的问题 因为新增了一个控制器方法&#xff0c;从而导致在运行Swagger的时候直接报错&#xff0c;异常如下&#xff1a; SwaggerGeneratorException: Conflicting method/path combination "POST api/UserOperationExample" for actions - WebApi.Controllers.Us…

OpenSceneGraph

文章目录 关于 OpenSceneGraphScreenshots - OpenMW 关于 OpenSceneGraph 官网&#xff1a;https://openscenegraph.github.io/openscenegraph.io/github : https://github.com/openscenegraph/OpenSceneGraphClasses : https://podsvirov.github.io/osg/reference/opensceneg…

汽车新智能图谱里:理解腾讯的AI TO B路径

将自身的C2B产品和产业理解充分AI化&#xff0c;在自身内部场景率先验证跑通后&#xff0c;进而释放给产业伙伴&#xff0c;对应到具体的需求痛点&#xff0c;一起打磨对应的行业AI模型。 这也恰是腾讯“实用”标签背后的AI产业路径。 作者|皮爷 出品|产业家 成本、性价…

用NuGet安装 Oracle ODP.NET

oracle官网原文&#xff1a;Using NuGet to Install and Configure Oracle Data Provider for .NET Using NuGet to Install and Configure Oracle Data Provider for .NET In this section, you will install ODP.NET NuGet packages from nuget.org. Select View > Solut…

CARLA (I)--Ubuntu20.04 服务器安装 CARLA_0.9.13服务端和客户端详细步骤

目录 0. 说明0.1 应用场景&#xff1a;0.2 本文动机&#xff1a; 1. 准备工作2. 安装 CARLA 服务端软件【远程服务器】3. 安装 CARLA 客户端【远程服务器】3.1 .egg 文件安装&#xff1a;3.2 .whl 文件安装&#xff1a;3.3 从Pypi下载Python package 4. 运行服务端程序5. 运行客…

分布式版本控制系统——Git

分布式版本控制系统——Git 一、Git安装二、创建版本库三、将文件交给Git管理四、Git的工作区和暂存区1.工作区&#xff08;Working Directory&#xff09;2.版本库 五、版本回退和撤销修改1.版本回退2.撤销修改 六、删除文件七、常用基础命令总结八、参考 分布式版本控制系统&…