JavaWeb开发 —— MyBatis基本操作

news2024/11/23 15:40:30

目录

一、环境准备

二、删除操作实现

1. 根据主键删除

2. 删除(预编译SQL)

2.1  SQL注入

 2.2  参数占位符

三、新增操作实现

1. 新增代码实现

 2. 新增(主键返回)

四、更新操作实现

五、查询操作实现

1. 根据ID查询

1.1  数据封装 

 2.  查询(条件查询)

 2.1  参数名说明


通过实例案例进行学习MyBatis基本操作的增删查改。

需求说明:根据资料提供页面原型及需求,完成员工管理的需求开发

功能列表:

① 查询:根据主键ID查询、条件查询。

② 新增    ③ 更新

④ 删除:根据主键ID删除、根据主键ID批量删除。

一、环境准备

  • 准备数据库表emp。
-- 部门管理
create table dept(
    id int unsigned primary key auto_increment comment '主键ID',
    name varchar(10) not null unique comment '部门名称',
    create_time datetime not null comment '创建时间',
    update_time datetime not null comment '修改时间'
) comment '部门表';

insert into dept (id, name, create_time, update_time) values(1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()), (4,'就业部',now(),now()),(5,'人事部',now(),now());



-- 员工管理
create table emp (
  id int unsigned primary key auto_increment comment 'ID',
  username varchar(20) not null unique comment '用户名',
  password varchar(32) default '123456' comment '密码',
  name varchar(10) not null comment '姓名',
  gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
  image varchar(300) comment '图像',
  job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
  entrydate date comment '入职时间',
  dept_id int unsigned comment '部门ID',
  create_time datetime not null comment '创建时间',
  update_time datetime not null comment '修改时间'
) comment '员工表';

INSERT INTO emp
	(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES
	(1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),
	(2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),
	(3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),
	(4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),
	(5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),
	(6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),
	(7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),
	(8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),
	(9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),
	(10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),
	(11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),
	(12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),
	(13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,now(),now()),
	(14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),
	(15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),
	(16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),
	(17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());
  • 创建一个新的springboot工程,选择引入对应的起步依赖(mybatis、mysql驱动、lombok)。
  • application.properties中引入数据库连接信息。
  • 创建对应的实体类Emp(实体类属性采用驼峰命名)。
  • 准备Mapper接口EmpMapper。

二、删除操作实现

1. 根据主键删除

//接口方法
@Delete("delete from emp where id = #{id}")
    public void delete(Integer id);

//实现类 
@Test
public void testDelete(){
     empMapper.delete(17);
}

注意事项:如果mapper接口方法形参只有一个普通类型的参数,#{ ... }里面的属性名可以随便写,如:#[id}、#value}。

2. 删除(预编译SQL)

在上述根据id主键删除元素,当我们执行单元测试时,我们可以看到数据库表结构发生变化,但是我们并不能直观了解到MyBatis框架底层到底执行了什么Sql语句以及执行结构。而我们可以借助MyBatis框架日志看到这些,日志默认关闭。

  • 可以在application.properties中,打开mybatis日志,并指定输出到控制台。
    #指定mybatis输出日志的位置,输出控制台
    mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
    

在MyBatis的mapper接口中声明的SQL语句使用 #{ } 占位符,最终会被问号 ? 替代, 生成预编译SQL语句。问号为预编译SQL语句中的参数占位符,最终执行会将SQL语句以及下方参数一起发送给数据库,数据库执行SQL语句时又会将参数替换问号完成操作。

② 预编译对比与直接拼接参数的优势:

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

2.1  SQL注入

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

正常情况下,数据库执行查询操作 -> count(*) = 1表示用户名和密码存在且正确,登录成功。

但是通过SQL注入攻击服务器:登录成功!(此时where 后条件一直成立)

select count(*) from emp where username = 'zhangwuji' and password = '123456';
select count(*) from emp where username = 'zhangwuji' and password = '111';
select count(*) from emp where username = 'wuieuwiueiwuiew' and password = '' or '1' = '1';

② 防止SQL注入: 通过 #{ } 占位符

 2.2  参数占位符

#{ ... }

  • 执行SQL时,会将 #{...} 替换为?,生成预编译SQL,会自动设置参数值。
  • 使用时机:参数传递,都使用#{...}

${ ... }

  • 拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题。
  • 使用时机:如果对表名、列表进行动态设置时使用。

三、新增操作实现

1. 新增代码实现

//接口方法
@Insert("insert into emp (username,  name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
        "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime});")
    public void insert(Emp emp);

//实现类 
@Test
    public void testInsert(){
        //构建员工对象
        Emp emp = new Emp();
        emp.setUsername("Tom");
        emp.setName("汤姆");
        emp.setImage("1.jpg");
        emp.setGender((short)1);
        emp.setJob((short)1);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行新增员工信息操作
        empMapper.insert(emp);
    }

MyBatis日志:

 2. 新增(主键返回)

① 描述:在数据添加成功后,需要获取插入数据库数据的主键。如:添加套餐数据时,还需要维护套餐菜品关系表数据。

 ② 实现:@Options():会自动将生成的主键值,赋值给emp对象的id属性。

@Options(keyProperty = "id",useGeneratedKeys = true)
@Insert("insert into emp (username,  name, gender, image, job, entrydate, dept_id, create_time, update_time)" +
        "values (#{username},#{name},#{gender},#{image},#{job},#{entrydate},#{deptId},#{createTime},#{updateTime});")
    public void insert(Emp emp);
}

四、更新操作实现

//接口方法
@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);

//实现类 
@Test
    public void testUpdate(){
        //构建员工对象
        Emp emp = new Emp();
        emp.setId(18);
        emp.setUsername("Jery");
        emp.setName("杰瑞");
        emp.setImage("2.jpg");
        emp.setGender((short)1);
        emp.setJob((short)2);
        emp.setEntrydate(LocalDate.of(2000, 1, 1));
        emp.setCreateTime(LocalDateTime.now());
        emp.setUpdateTime(LocalDateTime.now());
        emp.setDeptId(1);

        //执行更新员工信息操作
        empMapper.update(emp);
    }

MyBatis日志:

五、查询操作实现

1. 根据ID查询

//接口方法
@Select("select * from emp where id = #{id};")
    public Emp getById(Integer id);

//实现类 
@Test
    public void testSeclet(){
        Emp emp = empMapper.getById(10);
        System.out.println(emp);
    }

MyBatis日志:

在控制台中,我们可以看到username、password、name、gender等信息都查询出来,但是dept_id、createTime、updateTime均为null空值,并没有被封装进来,但是数据库表结构是有值的。这就涉及到MyBatis的数据封装

1.1  数据封装 

  • 实体类属性名 和 数据库表查询返回的字段名一致,mybatis会自动封装。
  • 如果 实体类属性名 和 数据库表查询返回的字段名不一致,不能自动封装。

解决方案:

给字段起别名,通过别名与实体类属性一致。

@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 getById(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 getById(Integer id);

开启 MyBatis的驼峰命名自动映射开关 。(推荐)

//application.properties
mybatis.configuration.map-underscore-to-camel-case=true

 2.  查询(条件查询)

//接口方法
@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>  getList(String name, short gender, LocalDate begin,LocalDate end);

//实现类 
@Test
    public void testList(){
        List<Emp> list = empMapper.getList("张", (short)1, LocalDate.of(2010, 1, 1), LocalDate.of(2020, 1, 1));
        System.out.println(list);
    }

MyBatis日志:

此时我们注意到,当SQL语句中存在模糊匹配,在关键字前后加 % 百分号,此时这是一个字符串。在字符串中无法使用用 #{ } ,而我们使用的 ${ } 字符串拼接,其生成的不是一个预编译SQL,就有可能出现性能低、不安全、存在SQL注入问题。

我们通过MySQL提供的 Concat 函数解决这一问题:

@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>  getList(String name, short gender, LocalDate begin,LocalDate end);

 2.1  参数名说明

① 在springboot的 2.x 版本#{ }中参数名与形参名直接对应。

 ② 在springboot的 1.x 版本 / 单独使用mybatis需要在每一个形参加上@Param注解为其制定一个名字与#{ }中参数名再对应。

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

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

相关文章

【Python】pip 和 conda install、list的区别,是否一致

【Python】pip 和 conda install、list的区别&#xff0c;是否一致 文章目录【Python】pip 和 conda install、list的区别&#xff0c;是否一致1. 介绍2. 看效果2.1 首先&#xff0c;conda 创建环境2.2 然后&#xff0c;激活环境2.3 查看环境下已经安装包列表2.4 安装新的包&am…

【2023最新】超详细图文保姆级教程:App开发新手入门(2)

上章节我们已经成功的创建了一个 App 项目&#xff0c;接下来我们讲述一下&#xff0c;如何导入项目、编辑代码和提交项目代码。 Let’s Go! 4. 项目导入 当用户创建一个新的应用时&#xff0c;YonStudio 开发工具会自动导入模板项目的默认代码&#xff0c;不需要手动进行代…

C语言的Hello World的汇编剖析(64位 Intel架构)

C语言的Hello World的汇编剖析&#xff08;64位 Intel架构&#xff09; 文章目录C语言的Hello World的汇编剖析&#xff08;64位 Intel架构&#xff09;一. 前提准备二. C转换为汇编操作准备2.1 创建目录&复制代码2.2 C文件转换为汇编文件三. 剖析汇编文件四. 指令相关五. …

TenserRT(三)PYTORCH 转 ONNX 详解

第三章&#xff1a;PyTorch 转 ONNX 详解 — mmdeploy 0.12.0 文档 torch.onnx — PyTorch 2.0 documentation torch.onnx.export 细解 计算图导出方法 TorchScript是一种序列化和优化PyTorch模型的格式&#xff0c;将torch.nn.Module模型转换为TorchScript的torch.jit.Scr…

ERTEC200P-2 PROFINET设备完全开发手册(6-1)

6 报警和诊断 Profinet提供了强大的诊断功能&#xff0c;这是其他通讯协议所无法比拟的。PN设备检测到问题后可以向控制器发送报警信息&#xff0c;报警分为三大类&#xff1a; 诊断报警 &#xff08;PN设备本身故障触发的报警&#xff0c;例如&#xff1a;温度测量通道变送电…

Activiti学习02

这里写目录标题一、流对象简介1.1 事件1.2 活动1.3 条件二、Activiti系统服务结构图核心类:服务类:RepositoryServiceRuntimeServiceTaskServiceHistoryServiceFormServiceIdentityServiceManagementService三、Activiti数据库支持一、流对象简介 一个业务流程图有三个流对象的…

ATFX国际:中国一季度GDP同比增长4.5%,社消总额约11.5万亿元

ATFX国际&#xff1a;中国统计局发布一季度国民经济运行报告&#xff0c;其中值得关注两大数据分别为GDP同比增速、社会消费品零售总额增速。统计显示&#xff0c;一季度GDP总额28.5万亿元&#xff0c;同比增长4.5%&#xff0c;其中第一产业和第二产业的增速低于平均值&#xf…

Pyqt案例讲解(实现模拟计算器效果)

PyQt5是一个用于Python的GUI框架&#xff0c;它提供了一个简单易用的GUI工具包&#xff0c;可以用于创建各种类型的应用程序&#xff0c;包括计算器。下面是一个简单的计算器的实现&#xff0c;其中包括了一些难点和复杂的地方。 难点&#xff1a; 使用Qt的布局管理器来创建窗…

证书扫描件怎么弄?手机也能轻松扫描

现代社会中&#xff0c;证书是人们展示自己能力和经历的重要凭证。然而&#xff0c;我们有时需要将证书扫描并保存在电脑或手机中&#xff0c;以备不时之需。本文将介绍如何扫描证书以及手机上是否能进行扫描。 证书扫描的方法 将证书扫描成电子文档可以方便地将其存储在电脑或…

C++ Primer 第7章 类 - 中(零基础学习C++,精简学习笔记)

&#x1f916; 作者简介&#xff1a;努力的clz &#xff0c;一个努力编程的菜鸟 &#x1f423;&#x1f424;&#x1f425; &#x1f440; 文章专栏&#xff1a;C Primer 学习笔记 &#x1f4d4;专栏简介&#xff1a; 本专栏是博主学习 C Primer 的学习笔记&#xff0c;因为…

技巧:WIN10手动指定某个应用程序使用独立显卡

目录1. 背景2. 解决方法&#xff0c;假如要让剪映始终使用独立显卡2.1 步骤1&#xff0c;右击电脑桌面空白处&#xff0c;选择“显示设置”2.2 步骤2&#xff0c;拉到最下面&#xff0c;点击图形设置2.3 步骤3&#xff0c;选择桌面应用&#xff0c;点击浏览2.4 步骤4&#xff0…

领课在线教育系统源码 各行业都适用的分布式在线教育系统+支持讲师入驻功能

领课教育系统&#xff08;roncoo-education&#xff09;是基于领课网络多年的在线教育平台开发和运营经验打造出来的产品&#xff0c;致力于打造一个各行业都适用的分布式在线教育系统。系统采用前后端分离模式&#xff0c;前台采用vue.js为核心框架&#xff0c;后台采用Spring…

bash shell 无法使用 perl 正则

1.案例现象 前几天有一个小伙伴在群里求助&#xff0c;说他这个 shell 脚本有问题&#xff0c;让大家帮忙看看 #!/bin/bash regularExpression"^\[(\d)\].$" contentcat $1 for i in ${content} doif [[ $i ~ $regularExpression ]]thenecho -e "\033[32m 【 i…

一款多参数多合一的空气质量传感器【温湿度、TVOC甲醛CO2粉尘等】

档案馆库房专用的一款智能型空气质量云测仪 空气质量检测仪 空气质量传感器 环境集成传感器 集成/温湿度、粉尘PM2.5 PM10/甲醛/TVOC/CO2等高度集成的一款传感器/RS485信号输出 ◆温度测量参数: (1)温度测量范围: -40~80℃(2&#xff09;输出分辨率:0.1oC (3&#xff09;…

从零开始学架构——高性能负载均衡

高性能负载均衡 单服务器无论如何优化&#xff0c;无论采用多好的硬件&#xff0c;总会有一个性能天花板&#xff0c;当单服务器的性能无法满足业务需求时&#xff0c;就需要设计高性能集群来提升系统整体的处理性能。高性能集群的本质很简单——通过增加更多的服务器来提升系…

Pandas入门实践1 -初探

我们将开始介绍Series、DataFrame和Index类&#xff0c;它们是pandas的基本构建块&#xff0c;并展示如何使用它们。在本节结束时&#xff0c;您将能够创建DataFrame并对它们执行操作以检查和筛选数据。 DataFrame剖析 DataFrame由一个或多个Series组成。Series的名称构成列名…

( “树” 之 DFS) 111. 二叉树的最小深度 ——【Leetcode每日一题】

111. 二叉树的最小深度 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a; 叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;2…

matplotlib 笔记:subplot之间间距拉开

0 前情介绍 使用matplotlib的subplot时&#xff0c;由于默认间距不大&#xff0c;所以可能导致出的图会挤在一起 import matplotlib.pyplot as pltplt.subplot(221) plt.plot([1, 2, 3])plt.subplot(222) plt.bar([1, 2, 3], [4, 5, 6])plt.xlabel(xlabel, fontsize15, color…

码云私有仓库+宝塔面板部署WebHooks实现代码同步

权限问题&#xff0c;要分清楚两个帐号的权限www和root sudo -u www ssh -T gitgitee.com sudo -u root ssh -T gitgitee.com看清楚是用那个&#xff0c;建议用WWW帐号权限&#xff0c;不能用ROOT权限(最高权限不建议) 所以生成SSH是要注意要用那个帐号来生成&#xff1a; 一…

关于yolov7的一些理解

论文: https://arxiv.org/abs/2207.02696 Github: https://github.com/WongKinYiu/yolov7 YOLOV7的一些理解 1.摘要2.创新点3.具体工作3.1.网络结构优化3.2.辅助头训练3.3.标签分配策略3.4.重参数结构3.5.其它 1.摘要 Yolov7是Yolov4团队的作品&#xff0c;受到了yolo原作者…