JavaWeb Day09 Mybatis-基础操作01-增删改查

目录

环境准备

①Emp.sql

②Emp.java

一、删除

①Mapper层

②测试类

③预编译SQL(查看mybatis日志)

1.性能

2.安全

④总结

二、新增

①Mapper层

②测试类

③结果

④新增(主键返回)

1.Mapper层

2.测试类

⑤总结​编辑

三、更新(修改)

案例

①Mapper层

②测试类

四、查询

(一)根据主键ID查询数据回显展示

①Mapper层

②测试类

③解决数据无法封装的问题

方案一:给字段起别名,让别名与实体类属性一致

结果​编辑

方案二:通过mybatis中的@Results,@Result注解手动映射封装

结果​编辑

方案三:Mybatis驼峰命名自动映射的开关 a-column =》 aColumn

结果

总结

思考 

(二)根据条件查询数据回显展示

①Mapper层

②测试类

③结果

④Concat()

1.Mapper层

2.结果

五、XML映射文件(配置文件)

①EmpMapper.xml

②Mapper层

③测试类

④思考

⑤总结


环境准备

①Emp.sql

-- 部门管理
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());

②Emp.java

package com.itheima.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDate;
import java.time.LocalDateTime;@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {private Integer id;private String username;private String password;private String name;private Short gender;private String image;private Short job;private LocalDate entrydate;//日期private Integer deptId;private LocalDateTime createTime;//日期时分秒private LocalDateTime updateTime;
}

一、删除

mybatis的参数占位符#{}

①Mapper层

package com.itheima.mapper;import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {
//    根据ID删除数据@Delete("delete from emp where id=#{id}")
//    public void deltte(Integer id);//返回值代表此次操作影响的记录数public int delete(Integer id);
}

②测试类

package com.itheima;import com.itheima.mapper.EmpMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testDelete(){int delete= empMapper.delete(17);System.out.println(delete);}
}

③预编译SQL(查看mybatis日志)

 

1.性能

在JAVA项目中,要想执行SQL语句,需要链接上数据库,然后把SQL语句发送给数据库服务器,数据库服务器并不是立即执行SQL语句,而是先对SQL语句进行语法解析检查=》优化SQL=》编译SQL(编译为可执行函数)=》执行SQL语句

为了提高效率,数据库服务器会把优化编译的SQL缓存起来,下次再执行SQL,会先检查是否已有SQL缓存

然而因为三条语句的id不一致,数据库服务器会三次执行编译3次

如果采用预编译的SQL,不会把字段值直接拼接到SQL语句,而是使用?占位符,把SQL语句和字段值发送给数据库服务器,先对SQL语句进行语法解析检查=》优化SQL=》编译SQL(编译为可执行函数)=》执行SQL语句

执行SQL语句的时候,会用参数值替代掉占位符

为了提高效率,数据库服务器会把优化编译的SQL缓存起来,下次再执行SQL,会先检查是否已有SQL缓存

三条语句的id不一致,但是缓存中的SQL语句是一致的,数据库服务器只会执行编译1次

2.安全

预编译防止SQL注入的原理就是将敏感字符转义成普通字符

④总结

二、新增

当传递参数有多个的时候,可以用实体类来传递,占位符里写的是实体类的属性名(驼峰命名)

①Mapper层

package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {@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);
}

②测试类

package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testInsert(){//构造员工对象Emp emp=new Emp();emp.setUsername("Tom");emp.setName("tom");emp.setImage("1.jpg");emp.setGender((short)1);emp.setJob((short)1);emp.setEntrydate(LocalDate.of(200,1,1));emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());emp.setDeptId(1);//执行新增员工信息操作empMapper.insert(emp);
}
}

③结果

④新增(主键返回)

1.Mapper层

package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {@Options(useGeneratedKeys = true,keyProperty = "id")@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);
}

需要在插入后获得返回的主键,在方法上面加Options注解,指定两个属性,userGeneratedKeys=true代表我们要返回的主键,keyProperty代表把返回的主键往emp的Id属性封装

2.测试类

package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testInsert(){//构造员工对象Emp emp=new Emp();emp.setUsername("Tom4");emp.setName("tom4");emp.setImage("1.jpg");emp.setGender((short)1);emp.setJob((short)1);emp.setEntrydate(LocalDate.of(200,1,1));emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());emp.setDeptId(1);//执行新增员工信息操作empMapper.insert(emp);System.out.println(emp.getId());
}
}

⑤总结

三、更新(修改)

案例

业务

第一步,根据主键ID查询数据回显展示

第二步,在界面数据修改完毕后点击保存,此时进行修改操作,(根据主键ID修改,因为他不会改变)

点击编辑,会根据当前这条数据的主键Id来查询数据,并且将该记录回显展示出来,此时我们就可以在原有数据的基础上对其进行修改,操作完毕点击保存按钮,就会将该表单数据提交到服务端,最终修改表中的字段值

根据主键修改员工信息

①Mapper层

package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {@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);
}

②测试类

package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;//更新员工@Testpublic void testUpdate(){//构造员工对象Emp emp=new Emp();emp.setId(18);emp.setUsername("Tom1");emp.setName("Tom1");emp.setImage("1.jpg");emp.setGender((short)1);emp.setJob((short)1);emp.setEntrydate(LocalDate.of(2000,1,1));emp.setUpdateTime(LocalDateTime.now());//执行更新员工操作empMapper.update(emp);}
}

四、查询

(一)根据主键ID查询数据回显展示

①Mapper层

package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;@Mapper
public interface EmpMapper {//根据ID查询员工信息@Select("select * from emp where id=#{id};")public Emp getById(Integer id);
}

②测试类

package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;   //根据ID查询员工信息@Testpublic void testGetById(){Emp emp=empMapper.getById(20);System.out.println(emp);}
}

③解决数据无法封装的问题

方案一:给字段起别名,让别名与实体类属性一致

修改Mapper层的接口中的SQL即可

public void update(Emp emp);//根据ID查询员工信息@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);
结果
方案二:通过mybatis中的@Results,@Result注解手动映射封装

修改Mapper层的接口中的SQL即可

 //根据ID查询员工信息@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);

@Results注解中的Values是@Result数组,每一个@Result表示映射一个字段和属性,column是表中的字段名,property是类中的属性名

结果
方案三:Mybatis驼峰命名自动映射的开关 a-column =》 aColumn

前提:表中字段名带下划线分割,实体中的属性名是驼峰命名

将字段名带下划线的自动封装为实体类中的驼峰式属性

在application.properties中配置Mybatis驼峰命名自动映射的开关,原来的Mapper层接口不需要修改

加入以下代码

#开启Mybatis驼峰命名自动映射的开关
mybatis.configuration.map-underscore-to-camel-case=true
结果

总结

思考 

思考:为什么Java中实体类的属性名不更改为和数据库一样的下划线呢?

约定俗成,Java中实体类的属性名应该是驼峰命名

思考:为什么数据库中字段名不更改为与Java相同的驼峰命名呢?

数据库不区分大小写,在数据库用不了驼峰,如果你Java用了驼峰就映射不上

思考:数据库字段为什么要用下划线命名 ?

数据库字段使用下划线命名是一种规范化命名方法,目的是使数据命名更加清晰,易读性更强,并且易于被程序识别。

(二)根据条件查询数据回显展示

①Mapper层

package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;import java.time.LocalDate;
import java.util.List;@Mapper
public interface EmpMapper {//条件查询员工信息@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> list(String name, Short gender, LocalDate begin,LocalDate end);
}

entryDate是一个范围,而属性entrydate是一个值,无法封装范围,故而直接用参数传递
    '%#{name}%'  单引号中的%表示要进行模糊匹配,而#{name}进行预编译后会被?取代,?是不能被放入单引号内的,
    所以要把#改为$,$是字符串拼接,直接将传递过来的name和两个字符串%拼接起来就可以了

②测试类

package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testList(){List<Emp> empList= empMapper.list("z",(short)1,LocalDate.of(2010,1,1),LocalDate.of(2020,1,1));System.out.println(empList);}
}

③结果

④Concat()

然而使用$拼接字符串存在安全问题并且效率不高

故而可以使用mybatis中的concat()函数对字符进行拼接

concat('%',#{name},'%') ,这样#{name}就不会出现在单引号内

1.Mapper层
package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;import java.time.LocalDate;
import java.util.List;@Mapper
public interface EmpMapper {@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> list(String name, Short gender, LocalDate begin,LocalDate end);}
2.结果

这里生成的就是预编译的SQL

五、XML映射文件(配置文件)

源文件放在java中,而配置文件放在resources中

官网:mybatis – MyBatis 3 | 简介

①EmpMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
<!--    resultType:单条记录所封装的类型--><select id="list" resultType="com.itheima.pojo.Emp">select * from emp where name like concat('%',#{name},'%') and gender=#{gender} andentrydate between #{begin} and #{end} order by update_time desc</select>
</mapper>

②Mapper层

package com.itheima.mapper;import com.itheima.pojo.Emp;
import org.apache.ibatis.annotations.*;import java.time.LocalDate;
import java.util.List;@Mapper
public interface EmpMapper {public List<Emp> list(String name, Short gender, LocalDate begin,LocalDate end);}

③测试类

package com.itheima;import com.itheima.mapper.EmpMapper;
import com.itheima.pojo.Emp;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testpublic void testList(){List<Emp> empList= empMapper.list("z",(short)1,LocalDate.of(2010,1,1),LocalDate.of(2020,1,1));System.out.println(empList);}
}

④思考

mapper映射文件还有一个好处,修改sql语句不用重启项目

在方法上实现动态的条件查询就会使接口过于臃肿

如果操作语句多了,直接也在注解上面比较混乱

如果要做手动映射封装实体类的时候 xml方便,项目中会常用

用xml,因为查询的条件会变化,直接写在注解里面的话会使接口过于臃肿

这两个各自找各自对应的,原来是注解绑定,现在是通过路径和方法名绑定

多条件查询要写动态sql用映射文件比较合适,简单的可以直接注解方式

终于找到问题了,xml里的sql语句不能拼接,只能是一长条,运行才不报错

执行list()方法时,根据全限定类名找到对应的namespace ,再找到id为这个方法的SQL语句就可以执行了

⑤总结

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法与设计模式】

一、数据结构与算法 1、算法性能评估 时间复杂度、空间复杂度 2、数据结构 数组与列表 队列 堆栈 链表 二叉树 多叉树 递归算法 二、设计模式 1、单例 &#xff08;1&#xff09;GIL&#xff1a;线程互斥锁。保证同一时刻只有一个线程在进行。 &#xff08;2&#xff09…

前端开发项目中使用字体库

开发中有些项目要求使用固定的字体&#xff0c;这就需要项目中使用字体库。 首先需要下载字体库 将下载的字体文件放进项目中 在项目代码样式文件中定义字体 font-face {font-family: "Tobias-SemiBold";src: url("./assets/font/Tobias-SemiBold.ttf"…

【ElasticSearch】学习使用DSL和RestClient编写查询语句

文章目录 DSL和RestClient的学习前言1、DSL查询文档1.1 查询分类1.2 全文检索查询1.21 全文检索概述1.2.2 基本使用 1.3 精确查询1.3.1 term查询1.3.2 range查询 1.4 地理坐标查询1.4.1 geo_bounding_box查询1.4.2 geo_distance查询 1.5 复合查询1.5.1 常见相关性算法1.5.2 算分…

JVM-虚拟机的故障处理与调优案例分析

案例1&#xff1a;大内存硬件上的程序部署策略 一个15万PV/日左右的在线文档类型网站最近更换了硬件系统&#xff0c;服务器的硬件为四路志强处理器、16GB物理内存&#xff0c;操作系统为64位CentOS 5.4&#xff0c;Resin作为Web服务器。整个服务器暂时没有部署别的应用&#…

IP可视对讲实时录制系统

介绍 软件架构 技术支持 CallRecored介绍 IP可视对讲实时录制系统设计了数据库表&#xff0c;并完成了数据库建模&#xff0c;采用了视频编解码技术&#xff0c;高效网络传输&#xff0c;磁盘高效读写技术&#xff0c;以及提供开放接口。 系统客户端采用扁平化UI&#xff0c;…

asp.net core mvc之路由

一、默认路由 &#xff08;Startup.cs文件&#xff09; routes.MapRoute(name: "default",template: "{controllerHome}/{actionIndex}/{id?}" ); 默认访问可以匹配到 https://localhost:44302/home/index/1 https://localhost:44302/home/index https:…

Python开发运维:Python3.7使用QQ邮箱发送不同类型邮件

目录 一、理论 1.邮件发送 二、实验 1.Python3.7使用QQ邮箱发送普通邮件 2.Python3.7使用QQ邮箱发送包含图片与附件的邮件 三、问题 1.Pycharm中如何放大和缩小代码界面 一、理论 1.邮件发送 &#xff08;1&#xff09;概念 SMTP&#xff08;Simple Mail Transfer Pro…

“辛巴猫舍”内网渗透、提权、撞库学习笔记

前言&#xff1a; 在拿到靶机时&#xff0c;我们最先需要做的是信息收集&#xff0c;包括不限于&#xff1a;C段扫描&#xff0c;端口探测&#xff0c;指纹识别&#xff0c;版本探测等。其次就是 漏洞挖掘、漏洞利用、提权、维持权限、日志清理、留下后门。 以上就是渗透的基本…

【C语言】冒泡排序(图解)

&#x1f308;write in front :&#x1f50d;个人主页 &#xff1a; 啊森要自信的主页 &#x1f308;作者寄语 &#x1f308;&#xff1a; 小菜鸟的力量不在于它的体型&#xff0c;而在于它内心的勇气和无限的潜能&#xff0c;只要你有决心&#xff0c;就没有什么事情是不可能的…

android studio 修改图标

Android Studio 修改图标 简介 Android Studio 是一款由谷歌推出的用于开发 Android 应用程序的集成开发环境&#xff08;IDE&#xff09;。在开发过程中&#xff0c;我们可以根据自己的需求修改 Android Studio 的图标&#xff0c;以个性化我们的开发环境。 本文将介绍如何在…

【深度挖掘Java性能调优】「底层技术原理体系」深入挖掘和分析如何提升服务的性能以及执行效率(引导篇)

深入挖掘和分析如何提升服务的性能以及执行效率 前提介绍知识要点 性能概述教你看懂程序的性能案例介绍性能指标性能的参考指标性能瓶颈&#xff08;木桶原理&#xff09; 性能分析三大定律Amdahl定律计算公式参数解释案例分析定律总结 Gustafson定律与Amdahl定律相对立Gustafs…

数据库 关系数据理论

问题 数据冗余更新异常插入异常删除异常 一个好的模式应当不会发生插入异常、删除异常和更新异常&#xff0c;数据冗余应尽可能少 数据依赖 定义&#xff1a;一个关系内部属性与属性之间的一种约束关系&#xff08;该约束关系是通过属性间值的相等与否体现出来数据间相关联…