Java_Mybatis
Mybatis是一款优秀的持久层框架,用户简化JDBC(使用Java语言操作关系型数据库的一套API)开发
使用Mybatis查询所有用户数据:
代码演示:
UserMapper:
@Mapper //被调用时会通过动态代理自动创建实体类,并放入IOC容器中
public interface UserMapper {@Select("select * " +"from user")public List<User> list();}
单元测试中使用:
@SpringBootTest
class SpringbootMybatisQuickstartApplicationTests {@Autowiredpublic UserMapper userMapper;@Testpublic void contextLoads() {List<User> list = userMapper.list();list.stream().forEach(user -> System.out.println(user));}}
JDBC
JDBC与Mybatis相比:
数据库连接池:
总结:
lombok:
Mybatis日志:
在application.properties中添加代码
#配置Mybatis的日志信息,并输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
数据库操作
1.通过注解操作数据库
删除操作
根据主键删除:
代码演示:
Mapper类:
@Mapper
public interface EmpMapper {@Delete("delete from emp where id = #{id}")public void delete(Integer id);}
单元测试:
@SpringBootTest
class SpringbootMybatisQuickstartApplicationTests {@Autowiredpublic EmpMapper empMapper;@Testpublic void deleteTest() {empMapper.delete(17);}}
注意:
Mapper中的SQL语句“delete from emp where id = #{id}”,这里我们使用的#占位符,表示大括号中间的id为传递的参数,除了#占位符还有$占位符,但是它们有一些区别
★#占位符和$占位符的区别:
使用#占位符执行SQL时会将#{...}替换为?,生成预编译SQL,会自动设置参数值,使用时机:参数传递
使用$占位符执行SQL时会直接将参数拼接到SQL语句中,存在SQL注入问题.
SQL注入:
SQL注入就是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。
比如username='....' and password='.....',传递给password参数:' or '1' = '1 ,这样会得到username='....' and password='' or '1' = '1',总是为true,这样不知道用户名和密码也可以登录了,使用时机:对表名、列表进行动态设置时使用。
SQL预编译的好处:
1.性能更高:要想执行SQL语句,要连接上数据库,然后将SQL语句发送到数据库中,再进行SQL语法解析检查,优化SQL,编译SQL,执行SQL。但是在SQL语法解析检查,优化SQL,编译SQL过程中,为了提高效率,它会将优化编译后的SQL缓存起来,比如delete from emp where id = #{id},会缓存为delete from emp where id = ?,这样如果只有后面传递的id参数值改变,只需要在缓存中调用这一句即可,就只需要编译一次
2.更安全(防止SQL注入),通过参数赋值的方法不会更改原本的SQL语义
新增操作
新增:
代码演示:
Mapper类:
@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);}
单元测试:
@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testvoid insertTest() {Emp emp = new Emp();emp.setUsername("han");emp.setName("韩");emp.setGender((short) 1);emp.setJob((short) 1);emp.setEntrydate(LocalDate.of(2010,1,1));emp.setDeptId(1);emp.setCreateTime(LocalDateTime.now());emp.setUpdateTime(LocalDateTime.now());empMapper.insert(emp);}}
新增(主键返回):
代码演示:
@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);}
更新操作:
更新:
代码演示:
Mapper:
@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);
}
单元测试:
@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testvoid updateTest() {Emp emp = new Emp();emp.setId(19);emp.setUsername("han1");emp.setName("韩1");emp.setImage("1.jpg");emp.setGender((short) 1);emp.setJob((short) 1);emp.setEntrydate(LocalDate.of(2010,1,1));emp.setDeptId(1);emp.setUpdateTime(LocalDateTime.now());empMapper.update(emp);}}
查询操作:
根据id查询:
代码演示:
Mapper:
@Mapper
public interface EmpMapper {@Select("select * from emp where id = #{id}")public Emp getById(Integer id);
}
单元测试:
@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testvoid getByIdTest() {Emp emp = empMapper.getById(19);System.out.println(emp);}}
注意:
这种编写方式得到的结果中有一部分属性值为null
这是因为mybatis的数据封装特性(如下)。
数据封装:
解决方案一:
给字段起别名,让别名与实体类属性保持一致
代码演示:
Mapper:
@Mapper
public interface EmpMapper {/*//与属性名不一致的字段会赋值为null@Select("select * from emp where id = #{id}")public Emp getById(Integer 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);}
解决方案二:
通过@Results,@Result注解手动映射封装
代码演示:
Mapper:
@Mapper
public interface EmpMapper {/*//与属性名不一致的字段会赋值为null@Select("select * from emp where id = #{id}")public Emp getById(Integer 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);*///解决方案二:通过@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的驼峰命名自动映射开关
操作步骤:
只需要在mybatis配置文件application.properties中添加代码
#开启mybatis的驼峰命名自动映射开关(camel)
mybatis.configuration.map-underscore-to-camel-case=true
这样就可以使用最初的代码也能正确赋值
但是需要注意:数据库中的字段名要采用下划线命名,Java类中的属性名要采用驼峰命名法
条件查询:
根据姓名(模糊匹配)、性别、入职日期范围,来查找员工
代码演示:
Mapper:
@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> getList(String name, short gender, LocalDate begin, LocalDate end);}
这里使用concat函数,是由于#{}会生成预编译SQL,编译后会转换成?,而?存在于单引号中会被认为是字符串,所以使用concat函数,来进行字符串的拼接。
单元测试:
@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testvoid listTest() {List<Emp> list = empMapper.getList("张", (short) 1, LocalDate.of(2010, 1, 1), LocalDate.of(2020, 1, 1));System.out.println(list);}}
2.通过XML映射文件操作数据库:
除了可以使用注解来操作数据库,还可以使用XML映射文件。
代码演示:
xml文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--上面为依赖部分,可在Mybatis中文网->入门 中的SQL部分截取-->
<mapper namespace="com.han.mapper.EmpMapper"><!--resultType:单条记录所封装的类型--><select id="getList" resultType="com.han.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:
@Mapper
public interface EmpMapper {public List<Emp> getList(String name, short gender, LocalDate begin, LocalDate end);
}
单元测试:
@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testvoid listTest() {List<Emp> list = empMapper.getList("张", (short) 1, LocalDate.of(2010, 1, 1), LocalDate.of(2020, 1, 1));System.out.println(list);}}
3.使用场景
使用Mybatis的注解,主要是来完成一些简单的增删改查功能/如果需要实现复杂的SQL功能,建议使用XML来配置映射语句。
动态SQL:
标签:
1.<if>(<where>、<set>)
查找(<where>):
更新(<set>):
2.<foreach>
<foreach>一般用于批量操作。
批量操作:
代码演示(批量删除):
XML文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--上面为依赖部分,可在Mybatis中文网->入门 中的SQL部分截取-->
<mapper namespace="com.han.mapper.EmpMapper"><!--resultType:单条记录所封装的类型--><delete id="deleteByIds">delete from emp where id in /*(11,12,13)*/<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach></delete></mapper>
Mapper:
@Mapper
public interface EmpMapper {public void deleteByIds(List<Integer> ids);
}
单元测试:
@SpringBootTest
class SpringbootMybatisCrudApplicationTests {@Autowiredprivate EmpMapper empMapper;@Testvoid deleteByIdsTest() {List<Integer> list = Arrays.asList(11, 12, 13);empMapper.deleteByIds(list);}}
3.<sql>&<include>
代码演示:
如下面的XML文件代码,其中有一段动态SQL条件查询代码和一段根据id查询代码,它们中有大段的复用代码,如:
select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time
from emp
使用前代码:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--上面为依赖部分,可在Mybatis中文网->入门 中的SQL部分截取-->
<mapper namespace="com.han.mapper.EmpMapper"><!--resultType:单条记录所封装的类型--><select id="getById" resultType="com.han.pojo.Emp">select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_timefrom empwhere id = #{id}</select><!--resultType:单条记录所封装的类型--><select id="getList" resultType="com.han.pojo.Emp">select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_timefrom emp<where><if test="name != null">name like concat('%', #{name}, '%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if></where>order by update_time DESC</select></mapper>
使用<sql>和<include>可以减少代码复用
如下面代码
使用后代码:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--上面为依赖部分,可在Mybatis中文网->入门 中的SQL部分截取-->
<mapper namespace="com.han.mapper.EmpMapper"><sql id="commonSelect">select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_timefrom emp</sql><!--resultType:单条记录所封装的类型--><select id="getById" resultType="com.han.pojo.Emp"><include refid="commonSelect"/>where id = #{id}</select><!--resultType:单条记录所封装的类型--><select id="getList" resultType="com.han.pojo.Emp"><include refid="commonSelect"/><where><if test="name != null">name like concat('%', #{name}, '%')</if><if test="gender != null">and gender = #{gender}</if><if test="begin != null and end != null">and entrydate between #{begin} and #{end}</if></where>order by update_time DESC</select></mapper>
相关文章:

Java_Mybatis
Mybatis是一款优秀的持久层框架,用户简化JDBC(使用Java语言操作关系型数据库的一套API)开发 使用Mybatis查询所有用户数据: 代码演示: UserMapper: Mapper //被调用时会通过动态代理自动创建实体类,并放入IOC容器中…...

2024HW|常见红队使用工具
目录 什么是HW? 什么是网络安全红蓝对抗? 红队 常见工具 信息收集工具 Nmap 简介 漏洞扫描工具 Nessus简介 AWVS 简介 抓包工具 Wireshark简介 TangGo 简介 web 应用安全工具 Burpsuite 简介 SQLMap webshell 管理工具 蚁剑 冰蝎 后…...

Redisson集成SpringBoot
前言:Redisson集成SpringBoot主要有两种方式,一个是使用redisson-spring-boot-starter依赖(优先推荐),毕竟springboot主打的就是约定大于配置,这个依赖就是为springboot准备的。 再一种方式就是引入rediss…...

设计模式(十二)行为型模式---模板方法模式
文章目录 模板方法模式结构优缺点UML图具体实现UML图代码实现 模板方法模式 模板方法模式(Template Method)是一种基于继承实现的设计模式,主要思想是:将定义的算法抽象成一组步骤,在抽象类中定义算法的骨架ÿ…...

【气象常用】剖面图
效果图: 主要步骤: 1. 数据准备:我用的era5的散度数据(大家替换为自己的就好啦,era5数据下载方法可以看这里【数据下载】ERA5 各高度层月平均数据下载_era5月平均数据-CSDN博客) 2. 数据处理:…...

LabVIEW高低温试验箱控制系统
要实现LabVIEW高低温试验箱控制系统,需要进行硬件配置、软件设计和系统集成,确保LabVIEW能够有效地监控和控制试验箱的温度。以下是详细说明: 硬件配置 选择合适的试验箱: 确定高低温试验箱的型号和品牌。 确认试验箱是否支持外…...
Flutter 中的 SliverFillViewport 小部件:全面指南
Flutter 中的 SliverFillViewport 小部件:全面指南 Flutter 是一个由 Google 开发的跨平台 UI 框架,它允许开发者使用 Dart 语言来构建高性能、美观的移动、Web 和桌面应用。在 Flutter 的丰富组件库中,SliverFillViewport 是一个用于 Custo…...

明日周刊-第12期
以前小时候最期待六一儿童节了,父母总会给你满足一个愿望,也许是一件礼物也许是一次陪伴。然而这个世界上其实还有很多儿童过不上儿童节,比如某些地区的小孩子,他们更担心的是能不能见到明天的太阳。 文章目录 一周热点航天探索火…...
算法之美阅读笔记
这里写自定义目录标题 序04 缓存 -- 忘了它吧 序 在图书馆闲逛时,一本封面为绿色的清新的书引起了我的兴趣,书名是算法之美。我心里不禁嘀咕,大家好喜欢使用某某之美作为书名,比如:数学之美、架构之美。美丽美好的事物…...
新手学习STM32还是ESP32
对于新手来说,选择学习STM32还是ESP32取决于个人的学习目标和背景。以下是针对这两种微控制器的详细分析,以便您做出更明智的选择: STM32 1. 处理器架构与性能 STM32采用单核或多核处理器架构,基于ARM Cortex-M0,M0…...

关于vlookup的第一个参数的个人理解
VLOOKUP(查阅值,包含查阅值和返回值的查找区域,查找区域中返回值的列号,精确查找或近似查找) 我个人理解,第一个参数应该叫线索值,因为我们要通过它去找与其对应的(也就是与其同行的…...

vector实现后半部分
一.迭代器失效 1.定义 指原迭代器在扩容/缩容/修改后指向无效元素或无效地址处 erase的迭代器失效 2.原因: 1.有的编译器实现erase会缩容拷贝 2.删除最后一个后,其指向无效元素 VS中不允许再次使用erase完的迭代器,为了让编写的代码移植…...

Maven配置
Maven – Download Apache Maven https://maven.apache.org/install.html 得下载有 bin的...
python 第一天
循环打印 while循环 languages ["Regional Assembly Language","Autocode","FORTRAN","IPL (LISP的先驱)","FLOW-MATIC (COBOL的先驱)","COMTRAN (COBOL的先驱)","LISP","ALGOL 58","F…...

Day03 左侧菜单数据绑定
一.左侧菜单数据绑定 1.首先,进行项目结构塔建。按照Prism 框架约定,要使用自动查找绑定功能。即View (视图)中自动查找并绑定到对应的ViewModel(视图模型,处理视图业务逻辑)。就需要在项目中按…...
JavaScript笔记三-JavaScript常用对象
1、数字对象(Number) 1.1 、属性 属性描述Number.MAX_VALUEJavaScript 中所能表示的最大值Number.MIN_VALUEJavaScript 中所能表示的最小值Number.NaN非数字Number.NEGATIVE_INFINITY负无穷,在溢出时返回Number.POSITIVE_INFINITY正无穷&am…...

最新的CleanMyMac X4.15.4中文破解版新功能介绍及CleanMyMac 安装激活指南
知名的Mac系统清理软件CleanMyMac发布了最新的CleanMyMac X4.15.4,更换了矩形图标,更好的融合和兼容macOS Snoma系统。新版CleanMyMac 支持Intel芯片和苹果M1/M2芯片的Mac。 优化 Mac 电脑,用 CleanMyMac X4.15.4中文版 就够了!强…...

密文域可逆信息隐藏安全性研究-从图像到视频
前言 随着云存储、云计算等新兴技术的兴起,海量的隐私信息被广泛地上传、存储到服务器上。为保证用户的隐私性,必须对用户的数据进行加密,然后再将其上传到服务器上。因此,密文域的可逆信息隐藏(reversible data hiding in encry…...
使用Python进行图像锐化的4个基础操作
想要让你的照片从模糊变锐利,就像魔法师轻轻一挥魔杖?今天我们就来学习如何用Python施加这神奇的“锐化滤镜”!🎉 首先,你需要一位得力助手——Pillow库,它能让我们轻松处理图像。如果你还没安装ÿ…...

图解 Python 编程(9) | 模块和包
🌞欢迎来到Python的世界 🌈博客主页:卿云阁 💌欢迎关注🎉点赞👍收藏⭐️留言📝 🌟本文由卿云阁原创! 📆首发时间:🌹2024年6月2日&…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?
uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件,用于在原生应用中加载 HTML 页面: 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
Python网页自动化Selenium中文文档
1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API,让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API,你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...

aardio 自动识别验证码输入
技术尝试 上周在发学习日志时有网友提议“在网页上识别验证码”,于是尝试整合图像识别与网页自动化技术,完成了这套模拟登录流程。核心思路是:截图验证码→OCR识别→自动填充表单→提交并验证结果。 代码在这里 import soImage; import we…...