MyBatis复习笔记
3.Mybatis复习
3.1 xml配置
-
properties:加载配置文件
-
settings:设置驼峰映射
<settings><setting name="mapUnderscoreToCamelCase" value="true"/> </settings> -
typeAliases:类型别名设置
#这样在映射器里面的resultType属性不需要写实体类的全路径名 <typeAliases><package name="com.sh.pojo"/> </typeAliases> -
mappers 映射器
-
加载接口,关联映射文件
<mappers><package name="com.itheima.sh.dao"/> </mappers>
-
3.2 getMapper底层
- 首先调用Proxy.newProxyInstance方法创建Mapper动态代理
- 动态代理invoke方法里会传入代理对象的方法,通过method.getName()获得方法名,接着使用Xpath解析xml从而获得id=方法名的标签表达式
- 解析resultType属性值,通过反射技术class.forName(“resultType属性值”)获取到Class对象,通过newInstance()构造返回对象
- 解析出sql语句,执行,并且查询结果封装到返回对象中

3.3 SQL语句的CRUD
-
select
<!--parameterType="int" 表示sql语句参数id的类型,int是Integer的别名--> <select id="queryById" resultType="user" parameterType="int">select * from user where id = #{id} </select> -
insert
<insert id="saveUser">insert into user values (null ,#{username},#{birthday},#{sex},#{address}) </insert> -
update
<update id="updateUser">update user set username = #{username},birthday=#{birthday},sex=#{sex},address=#{address} where id = #{id} </update> -
delete
<!--删除--> <delete id="deleteUser" >delete from user where id = #{id} </delete>
3.4 主键自增
新增一条数据成功后,将这条数据的主键封装到实体类中,并查看主键的值。
userMapper.saveUser(user);
//查看新的数据的主键值
System.out.println(user.getId());//null
使用insert标签的属性useGeneratedKeys,keyProperty,keyColumn实现:
| 属性 | 说明 |
|---|---|
| useGeneratedKeys | true 获取自动生成的主键,相当于select last_insert_id() |
| keyColumn | 表中主键的列名 |
| keyProperty | 实体类中主键的属性名 |
<insert id="saveUser" useGeneratedKeys="true" keyColumn="id" keyProperty="id">insert into user values (null ,#{username},#{birthday},#{sex},#{address})
</insert>
3.5 传入多个参数
步骤一 使用@Param注解注定名称:
//根据用户名和性别查询
User queryByUserNameAndSex(@Param("username") String userName, @Param("sex") String sex);
步骤二 在接收参数时,通过指定的名称获取参数值:
<select id="queryByUserNameAndSex" resultType="User">select * from user where username=#{username} and sex=#{sex}
</select>
3.6 Pojo传参
接口与xml:
void saveUser(User user);
<insert id="saveUser">insert into user values (null ,#{username},#{birthday},#{sex},#{address})
</insert>
底层: sql语句中 #{username}取值 -> 到pojo中调用 getUsername(){}
3.7 resultMap
resultMap标签的作用:自定义结果集,自行设置结果集的封装方式
- 配置resultMap
id属性:resultMap标签的唯一标识,不能重复,一般是用来被引用的
type属性:结果集的封装类型
autoMapping属性:操作单表时,不配置默认为true,如果pojo对象中的属性名称和表中字段名称相同,则自动映射。
<resultMap id="userResultMap" type="User" autoMapping="true"><!--配置主键映射关系--><id column="id" property="id"></id><!--配置用户名的映射关系 column 表示数据表列 property表示pojo的属性--><result column="name" property="username"></result>
</resultMap>
-
修改select标签的statement中的resultMap
<select id="queryById" resultMap="userResultMap">select * from user where id = #{id} </select>
4.动态SQL,多表查询,注解开发
4.1 基本动态SQL标签
-
if标签
<if test="判断条件">满足条件执行的代码 </if> -
choose,when,otherwise标签
choose标签:分支选择(多选一,遇到成立的条件即停止)when子标签:编写条件,不管有多少个when条件,一旦其中一个条件成立,后面的when条件都不执行。test属性:编写ognl表达式otherwise子标签:当所有条件都不满足时,才会执行该条件。可能优点乱,那来举个例子:
<!--根据用户名或者住址查询所有男性用户:如果输入了用户名则按照用户名模糊查找,否则就按照住址查找,两个条件只能成立一个,如果都不输入就查找用户名为“孙悟空”的用户。--><select id="queryByUserNameOrAddress" resultType="user">select * from user where sex='男'<choose><when test="userName!=null and userName.trim()!=''">and username like '%${userName}%'</when><when test="address!=null and address.trim()!=''">and address = #{address}</when><otherwise>and username='孙悟空'</otherwise></choose></select> -
where标签
标签作用:用于拼接多选一或者同时成立的SQL情况;
还会根据情况,动态的去掉SQL语句中的AND或者or;
还是举个例子吧:
需求: 如果输入了用户名按照用户名进行查询,如果输入住址,按住址进行查询,如果两者都输入,两个条件都要成立
假如不使用where标签,select标签应该这样:
<select id="queryByUserNameAndAge" resultType="user">SELECT * FROM user where<if test="userName != null and userName.trim()!=''">username = #{userName}</if><if test="address!=null and address.trim()!=''">AND address = #{address}</if></select>但是,假设用户名username是空,那么用户名的sql语句不参与条件,此时sql语句就会变为:SELECT * FROM user where AND address = #{address}
那么可以使用where关键字:
<select id="queryByUserNameAndAge" resultType="user">SELECT * FROM user<where><if test="userName != null and userName.trim()!=''">username = #{userName}</if><if test="address!=null and address.trim()!=''">AND address = #{address}</if></where></select> -
set标签
set标签:在update语句中,可以自动添加一个set关键字,并且会将动态sql最后多余的逗号去除。
案例:修改用户信息,如果参数user中的某个属性为null,则不修改。

因此,set解决了这个问题:
<!--选择性地对user数据进行修改--><update id="updateSelectiveUser">update user<set><if test="username != null and username.trim()!=''">username = #{username},</if><if test="birthday != null">birthday=#{birthday},</if><if test="sex != null and sex.trim()!=''">sex=#{sex},</if><if test="address != null and address.trim()!=''">address=#{address}</if></set>where id = #{id}</update> -
foreach标签
主要用来遍历:
<foreach collection="集合名或者数组名" item="元素" separator="标签分隔符" open="以什么开始" close="以什么结束">#{元素} </foreach>例子:
按照id值是1,2,3来查询用户数据
<!--根据多个id值查询--> <select id="queryByIds" resultType="user">SELECT * FROM user WHERE id IN<foreach collection="arrIds" item="ID" separator="," open="(" close=")">#{ID}</foreach> </select>注意!!!在mapper接口编写传参时一定要加上@Param(“arrIds”)!!!!
4.2 一对多查询
以下例子的表关系如下:

假如我们要查询用户id为1的订单信息,用户(1)->订单(n),sql语句为:
select * from tb_user tbu inner join tb_order tbo on tbu.id = tbo.user_id where tbu.id=1
一个用户关联多个订单 User(List orderList) ,在User类中定义一个List集合存储多个订单Order对象。
编写XML文件:
<!--自定义结果集--><resultMap id="oneToManyResult" type="User" autoMapping="true"><!--User的主键--><id column="uid" property="id"/><!--Order关联映射--><!--1.一对多使用collection子标签进行关联多方Order2.属性:1)property="orders" 这里的orders表示User类的成员变量orders2)javaType="List" 表示User类的成员变量orders存储的Order对象使用的类型,这里是List,可以不配置3) ofType="Order" 表示List集合中存储数据的类型 Order--><collection property="orders" javaType="List" ofType="Order" autoMapping="true"><!--Order的主键--><id column="oid" property="id" /></collection></resultMap><!--根据用户ID查询用户及其订单数据--><select id="oneToManyQuery" resultMap="oneToManyResult">SELECTtbo.id as oid,tbo.order_number,tbu.id as uid,tbu.user_name,tbu.password,tbu.name,tbu.age,tbu.sexFROMtb_user tbuINNER JOIN tb_order tbo ON tbu.id = tbo.user_idWHEREtbu.id = #{id}</select>
总结下:
一对多关系配置:
1、在对象中添加映射关系;
2、编写接口方法,编写SQL;
3、编写resultMap处理数据库字段和实体类之间数据的封装;
4.3 多对多查询
举个例子:查询订单号为20140921001的订单的详情信息即查询订单信息+订单中的商品信息;
订单表(n)->订单商品中间表(1)<-商品表(m) SQL大概这样:
# 【需求】:查询订单号为20140921001的订单的详情信息 订单的详情信息 = 订单+商品
SELECT*
FROMtb_order tbo
INNER JOIN tb_orderdetail detail ON tbo.id = detail.order_id
INNER JOIN tb_item item ON detail.item_id = item.id
WHERE
tbo.order_number = '20140921001';
那具体应该怎么实现呢?
首秀按,对实体类进行修改,一个订单表中关联了多个订单详情信息,所以在订单表中添加List<Orderdetail>属性;每一条订单详情记录中都包含了一条商品信息,所以需要在Orderdetail中添加一个Item属性;
编写xml:
<!--订单及订单详情结果集--><resultMap id="orderAndDetailMap" type="Order" autoMapping="true"><!--tb_order表 和 Order实体类--><!--订单表主键--><id property="id" column="oid"/><!--多个订单详情 1对多:detailList--><collection property="detailList" javaType="List" ofType="Orderdetail" autoMapping="true"><!--tb_order_detail表 和 Orderdetail实体类--><!--订单详情主键 detailId表示下面sql语句的别名--><id property="id" column="detailId"/><!--关联商品对象 一对一:orderdetail-Item--><association property="item" javaType="Item" autoMapping="true"><!--tb_item表 和 Item实体类 itemId 表示下面的sql语句别名--><id property="id" column="itemId"/></association></collection></resultMap><!--多对多查询--><select id="queryOrderAndDetailByOrderNumber" resultMap="orderAndDetailMap">SELECTtbo.id as oid,tbo.order_number,detail.id as detailId,detail.total_price,detail.status,item.id as itemId,item.item_detail,item.item_name,item.item_priceFROMtb_order tboINNER JOIN tb_orderdetail detail ON tbo.id = detail.order_idINNER JOIN tb_item item ON detail.item_id = item.idWHEREtbo.order_number = #{orderNumber};</select>
4.4 高级查询总结
resutlType无法帮助我们自动的去完成映射,所以只有使用resultMap手动的进行映射
resultMap: 属性:type 结果集对应的数据类型 Orderid 唯一标识,被引用的时候,进行指定autoMapping 开启自动映射extends 继承子标签:id:配置id属性result:配置其他属性association:配置一对一的映射property 定义对象的属性名javaType 属性的类型autoMapping 开启自动映射collection:配置一对多的映射property 定义对象的属性名javaType 集合的类型ofType 集合中的元素类型 泛型autoMapping 开启自动映射
4.5 注解开发
@Insert:保存 Value:sql语句(和xml的配置方式一模一样)@Update:更新 Value:sql语句@Delete: 删除Value:sql语句@Select: 查询Value:sql语句@Options:可选配置(主键回填)userGeneratedKeys:开关,值为true表示可以获取主键 相当于select last_insert_id()keyProperty :对象属性keyColumn : 列名
相关文章:
MyBatis复习笔记
3.Mybatis复习 3.1 xml配置 properties:加载配置文件 settings:设置驼峰映射 <settings><setting name"mapUnderscoreToCamelCase" value"true"/> </settings>typeAliases:类型别名设置 #这样在映射…...
HTML的基石:区块标签与小语义标签的深度解析
📚 HTML的基石:区块标签与小语义标签的深度解析 🌐 区块标签:构建网页的框架🏠 <div>:万能的容器📚 <section>、<article>、<aside>:语义化的布局 …...
Windows域控简介
一、Windows 域控概念 Windows 域控即 Active Directory(AD)域控制器,它是 Windows Server 中的一个角色,用于管理网络中的用户帐户、计算机和其他设备。AD 域控制器的功能包括: 用户认证:允许用户通过用…...
项目延期,不要随意加派人手
遇到软件项目出现延期的情况时,不建议随意加派人手。原因如下: 有些任务是不可拆分的,不能拆分为多个并行任务,增加人员不会加快项目进度。新增加人员需要原有人员介绍项目中的技术架构、业务知识,在开发过程中也难免…...
帝国CMS验证码不显示怎么回事呢?
帝国CMS验证码有时候会不显示或打叉,总结自己的解决方法。 1、检查服务器是否开启GD库 测试GD库是否开启的方法:浏览器访问:/e/showkey/index.php,如果出现一堆乱码或报错,证明GD库没有开启,开启即可。 2…...
【必会面试题】Redis 中的 zset数据结构
目录 Redis 中的 zset(sorted set,有序集合)数据结构在底层可以使用两种不同的实现:压缩列表(ziplist) 和 跳跃表(skiplist)。具体使用哪种结构取决于存储元素的数量和大小ÿ…...
括号匹配数据结构
括号匹配是一种数据结构问题,用于检查给定的字符串中的括号是否匹配。例如,对于字符串 "((())())",括号是匹配的,而对于字符串 "())(",括号是不匹配的。 常见的解决括号匹配问题的数据结构是栈。…...
c语言:strcmp
strcmp函数是用于比较两个字符串的库函数,其功能是根据ASCII值逐一对两个字符串进行比较。 语法:strcmp(str1, str2) 返回值: 如果str1等于str2,则返回0。 如果str1小于str2,则返回负数(具体值取决于C…...
传统关系型数据库与hive的区别
数据库和Hive之间存在本质的区别,主要体现在设计目的、数据处理方式、数据存储、查询延迟、数据更新能力、以及适用场景等方面。下面详细阐述它们之间的主要差异: 设计目的与应用场景: 数据库:主要是面向事务处理(OLTP…...
windows-386、windows-amd64、windows-arm64这三者有什么区别?
选择文件的版本出现下面问题: Architectures windows-386 :这些是针对 32 位 Windows 系统编译的。windows-amd64 :这些是针对具有 AMD 或 Intel x86-64 架构的 64 位 Windows 系统编译的。windows-arm64 :这些是针对具有 ARM 架…...
链表经典题目—相交链表和链表倒数第k个节点
🎉🎉🎉欢迎莅临我的博客空间,我是池央,一个对C和数据结构怀有无限热忱的探索者。🙌 🌸🌸🌸这里是我分享C/C编程、数据结构应用的乐园✨ 🎈🎈&…...
Java 写入 influxdb
利用Python随机生成一个1000行的csv文件 import csv import random from datetime import datetime, timedelta from random import randint, choice# 定义监控对象列表和指标名称列表 monitor_objects [Server1, Server2, Server3, DB1] metric_names [CPUUsage, MemoryUsa…...
npm的基本命令和用法
1. 安装与初始化 安装npm 首先,确保你的系统中已安装了Node.js,因为npm随Node.js一同分发。访问Node.js官网下载并安装适合你操作系统的版本。安装完成后,在终端或命令提示符中输入以下命令来验证安装: 1$ node -v 2$ npm -v …...
Python 基于深度图、RGB图生成RGBD点云数据
RGBD点云生成 一、概述1.1 定义1.2 函数讲解二、代码示例三、结果示例一、概述 1.1 定义 RGBD点云:是一种包含颜色和深度信息的点云数据。RGB代表红、绿、蓝三原色,表示点云中每个点的颜色信息;D代表深度,表示点云中每个点的相对于相机的距离信息。通过结合颜色和深度信息…...
力扣刷题--LCR 075. 数组的相对排序【简单】
题目描述 给定两个数组,arr1 和 arr2, arr2 中的元素各不相同 arr2 中的每个元素都出现在 arr1 中 对 arr1 中的元素进行排序,使 arr1 中项的相对顺序和 arr2 中的相对顺序相同。未在 arr2 中出现过的元素需要按照升序放在 arr1 的末尾。 …...
机器学习笔记——K近邻算法、手写数字识别
KNN算法 “物以类聚,人以群分”相似的数据往往拥有相同的类别 其大概原理就是一个样本归到哪一类,当前样本需要归到频次最高的哪个类去 也就是说有一个待分类的样本,然后跟他周围的k个样本来看,k中哪一个类最多,待分类…...
基于STM32实现智能园艺系统
目录 引言环境准备智能园艺系统基础代码示例:实现智能园艺系统 土壤湿度传感器数据读取水泵控制温湿度传感器数据读取显示系统用户输入和设置应用场景:智能农业与家庭园艺问题解决方案与优化收尾与总结 1. 引言 本教程将详细介绍如何在STM32嵌入式系统…...
网络原理-HTTP协议
HTTP协议 HTTP协议全称为超文本传输协议,除了能传输字符串,还能传输图片、视频、音频等。 当我们在访问网页的时候,浏览器会从服务器上下载数据,这些数据都会放在HTTP响应中,然后浏览器再根据这个HTTP响应显示出网页信息。 抓包 抓包工具本质上是一个代理工具,即我们将构造…...
【ES001】elasticsearch实战经验总结(最近更新中)
1.熟悉、梳理、总结下elasticsearch相关知识体系。 2.日常研发过程中使用较少,随着时间的推移,很快就忘得一干二净,所以梳理总结下,以备日常使用参考 3.欢迎批评指正,跪谢一键三连! 文章目录 1. 1....
OpenBayes 一周速览|TripoSR 开源:1 秒即 2D 变 3D、经典 GTZAN 音乐数据集上线
公共资源速递 This Weekly Snapshots !5 个数据集: FER2013 面部表情识别数据集 GTZAN 音乐流派分类数据集 MVTec-AD 工业异常检测数据集 UCAS-AOD 遥感目标检测数据集 Oxford 102 Flowers 花卉图片数据集 3 个教程: Latte 全球首个开…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
DAY 26 函数专题1
函数定义与参数知识点回顾:1. 函数的定义2. 变量作用域:局部变量和全局变量3. 函数的参数类型:位置参数、默认参数、不定参数4. 传递参数的手段:关键词参数5 题目1:计算圆的面积 任务: 编写一…...
FOPLP vs CoWoS
以下是 FOPLP(Fan-out panel-level packaging 扇出型面板级封装)与 CoWoS(Chip on Wafer on Substrate)两种先进封装技术的详细对比分析,涵盖技术原理、性能、成本、应用场景及市场趋势等维度: 一、技术原…...
作为点的对象CenterNet论文阅读
摘要 检测器将图像中的物体表示为轴对齐的边界框。大多数成功的目标检测方法都会枚举几乎完整的潜在目标位置列表,并对每一个位置进行分类。这种做法既浪费又低效,并且需要额外的后处理。在本文中,我们采取了不同的方法。我们将物体建模为单…...
初级程序员入门指南
初级程序员入门指南 在数字化浪潮中,编程已然成为极具价值的技能。对于渴望踏入程序员行列的新手而言,明晰入门路径与必备知识是开启征程的关键。本文将为初级程序员提供全面的入门指引。 一、明确学习方向 (一)编程语言抉择 编…...
安全领域新突破:可视化让隐患无处遁形
在安全领域,隐患就像暗处的 “幽灵”,随时可能引发严重事故。传统安全排查手段,常常难以将它们一网打尽。你是否好奇,究竟是什么神奇力量,能让这些潜藏的隐患无所遁形?没错,就是可视化技术。它如…...
