Spring Mybatis 基本使用 总结
1. 简介
Mybatis库可以简化数据库的操作,专注于sql语句。
2.搭建步骤
2.1 在pom.xml引入mybatis
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.11</version>
</dependency>
2.3 在resources下新建mybatis配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Mapper 3.0/EN""https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><settings>
<!-- <setting name="logImpl" value="STDOUT_LOGGING"/><!– 开启mybatis的日志输出 –>--><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 开启驼峰式自动映射 a_big => aBig --></settings><typeAliases><typeAlias alias="goods" type="com.jojo.pojo.Goods"/><!-- 单独设置别名 --><package name="com.jojo.pojo"/><!-- 批量设置别名, com.jojo.pojo包下的所有类名的别名为类的首字母小写--></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/> <!-- 自动开启事务 --><dataSource type="POOLED"><!-- mybatis维护连接池 --><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/><property name="username" value="root"/><property name="password" value="a12345678"/></dataSource></environment></environments><mappers><!-- 指定mapper xml文件的位置 --><mapper resource="mappers/GoodsMapper.xml"/></mappers>
</configuration>
2.3 在resources/mapper下新建mapper的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.jojo.mapper.GoodsMapper"><!-- 对应Mapper的全限定符 -->
<!-- 这里写sql语句 --><insert id="insert" useGeneratedKeys="true" keyColumn="id" keyProperty="id">insert into goods (name) value(#{name})</insert><update id="update">update goods set name=#{name} where id=#{id}</update><delete id="delete">delete from goods where id = #{id}</delete><select id="selectById" resultType="goods">select * from goods where id = #{id}</select><select id="selectAll" resultType="goods">select * from goods</select>
</mapper>
2.4 新建pojo类
import lombok.Data;
@Data//lombook插件的@Data标签可以自动生成get和set以及toString方法
public class Goods {private Integer id;private String name;
}
2.5 新建mapper接口
public interface GoodsMapper {int insert(Goods goods);int update(Goods goods);int delete(Integer id);Goods selectById(Integer id);List<Goods> selectAll();
}
2.6 测试
public class MybatisTest {@Testpublic void test() throws IOException {//1.读取外部配置文件InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");//2.创建sqlSessionFactorySqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(ips);//3.根据sqlSessionFactory创建sqlSessionSqlSession sqlSession = sqlSessionFactory.openSession();//4.获取接口的代理对象,调用代理对象的方法就会查找mapper接口的方法GoosdMapper mapper = sqlSession.getMapper(GoosdMapper.class);Goods goods = mapper.queryById(1);System.out.println(goods);//5.提交事务和释放资源//sqlSession.commit();sqlSession.close();}
}
3.常用mapper语句
3.1 传入值
<!-- #{id} = 使用占位符?,防止sql注入攻击,但不能替代表名表项-->
<!-- ${id} = 不使用占位符?,不能防止sql注入攻击,但可以替代表名表项-->
<select id="queryById" resultType="com.jojo.pojo.Employee">select emp_id empId,emp_name empName, emp_salary empSalary from t_emp where emp_id = #{id}
</select><delete id="deleteById">delete from t_emp where emp_id = #{id} <!-- 传入Integer类型,id可以改写成任意字符串-->
</delete><select id="queryBySalary" resultType="com.jojo.pojo.Employee">select emp_id empId,emp_name empName, emp_salary empSalary from t_emp where empSalary = #{salary} <!-- 传入Double类型,salary可以改写成任意字符串-->
</select><insert id="insertEmp">insert into t_emp (emp_name, emp_salary) values (#{empName},#{empSalary});<!-- 传入对象时,要写传入对象的属性 -->
</insert><select id="queryByNameAndSalary" resultType="com.jojo.pojo.Employee">select emp_id empId,emp_name empName, emp_salary empSalary from t_emp where empSalary = #{a} and empName = #{b} <!-- 传入两个基本类型,根据接口中的@Param("名称")来指定-->
</select><select id="queryByNameAndSalary" resultType="com.jojo.pojo.Employee">select emp_id empId,emp_name empName, emp_salary empSalary from t_emp where empSalary = #{arg0} and empName = #{arg1} <!-- 法2:传入两个基本类型,可以根据顺序来取arg0...arg1...-->
</select><select id="queryByNameAndSalary" resultType="com.jojo.pojo.Employee">select emp_id empId,emp_name empName, emp_salary empSalary from t_emp where empSalary = #{param1} and empName = #{param2} <!-- 法3:传入两个基本类型,可以根据顺序来取param1...param2...-->
</select><insert id="insertEmpMap">insert into t_emp (emp_name, emp_salary) values (#{name},#{salary});<!-- 传入Map时,要写传入Map的key -->
</insert>
3.2 返回值
<select id="queryNameById" resultType="string"><!-- resultType指定返回的类型,写类的全限定符或者mybatis提供的别名(在mybatis官网查)-->select emp_name from t_emp where emp_id = #{id}
</select><select id="queryById" resultType="employee"> <!-- resultType指定返回的为对象时,select的行需要起别名来与类的属性完全一致-->select emp_id empId,emp_name empName, emp_salary empSalary from t_emp where emp_id = #{id}
</select><select id="queryById" resultType="employee"><!-- resultType指定返回的为对象时,开启驼峰映射(mapUnderscoreToCamelCase)后,select的行不再需要起别名来与类的属性完全一致-->select * from t_emp where emp_id = #{id}
</select><select id="selectEmpNameAndMaxSalary" resultType="map"> <!-- resultType返回的值没有未定义类时,可以用map接值,map的每一项的key对应一个列名 -->select emp_name 员工姓名, emp_salary 员工工资, (SELECT AVG(emp_salary) from t_emp) 部门平均工资 from t_emp where emp_salary=(select max(emp_salary) from t_emp)
</select><select id="queryNamesBySalary" resultType="string"><!--如果返回类型时List<String>,那么指定String即可-->select emp_name from t_emp where emp_salary > #{ salary};
</select><select id="queryAll" resultType="employee"><!--如果返回类型时List<Employee>,那么指定Employee即可-->select * from t_emp;
</select><insert id="insertEmp" useGeneratedKeys="true" keyColumn="emp_id" keyProperty="empId"><!-- 主键自增长型:插入时,获取插入的id放在empId中 -->insert into t_emp (emp_name, emp_salary) value(#{empName},#{empSalary});
</insert><insert id="insertTeacher"><selectKey order="BEFORE" resultType="string" keyProperty="tId">select replace(UUID(),'-',''); <!-- 插入前由数据库生成uuid并放在tId中--></selectKey>insert into teacher (t_id,t_name) value (#{tId},#{tName})
</insert>
4.多表查询
4.1 一对一
1对1关系:一个A类中包含一个B类:
public class A {private Integer Id;private String aName;private Integer bId;private B b;
}public class B {private Integer bId;private String bName;
}
使用resultMap来装数据:
<resultMap id="aMap" type="a"><!-- a的主键 id标签--><id column="a_id" property="aId"/><!-- order的普通列 custom标签--><result column="a_name" property="aName"/><result column="b_id" property="bId"/><!-- 给第二层对象属性赋值 --><association property="b" javaType="b"><id column="b_id" property="bId"/><result column="b_name" property="bName"></result></association>
</resultMap><select id="queryAById" resultMap="aMap">SELECT * FROM t_a ta join t_b tb on ta.b_id = tb.b_id where ta.a_id = #{id};
</select>
在config文件中加入:
<settings><!-- 开启驼峰式自动映射 a_big => aBig --><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 开启自动映射 a_big => aBig --><setting name="autoMappingBehavior" value="FULL"/>
</settings>
后可省略主键以外的映射关系:
<resultMap id="aMap" type="a"><!-- a的主键 id标签--><id column="a_id" property="aId"/><!-- 给第二层对象属性赋值 --><association property="b" javaType="b"><id column="b_id" property="bId"/></association>
</resultMap><select id="queryAById" resultMap="aMap">SELECT * FROM t_a ta join t_b tb on ta.b_id = tb.b_id where ta.a_id = #{id};
</select>
4.2 一对多
1对多关系:一个A类中包含多个B类(List):
public class A {private Integer Id;private String aName;private Integer bId;private List<B> bList;
}public class B {private Integer bId;private String bName;
}
使用resultMap来装数据:
<resultMap id="aMap" type="a"><id column="a_id" property="aId"/><result column="a_name" property="aName"/><result column="b_id" property="bId"/><!--针对List<A>属性使用collection --><collection property="bList" ofType="b"><id column="b_id" property="bId"></id><result column="b_name" property="bName"/></collection>
</resultMap><select id="queryAList" resultMap="aMap">select * from t_a ta join t_b tb on ta.customer_id = tb.customer_id
</select>
在config文件中加入:
<settings><!-- 开启驼峰式自动映射 a_big => aBig --><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 开启自动映射 a_big => aBig --><setting name="autoMappingBehavior" value="FULL"/>
</settings>
后可省略主键以外的映射关系:
<resultMap id="aMap" type="a"><id column="a_id" property="aId"/><!--针对List<A>属性使用collection --><collection property="bList" ofType="b"><id column="b_id" property="bId"></id></collection>
</resultMap><select id="queryAList" resultMap="aMap">select * from t_a ta join t_b tb on ta.customer_id = tb.customer_id
</select>
相关文章:
Spring Mybatis 基本使用 总结
1. 简介 Mybatis库可以简化数据库的操作,专注于sql语句。 2.搭建步骤 2.1 在pom.xml引入mybatis <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.11</version> </dep…...

接口幂等性和并发安全的区别?
目录标题 幂等性并发安全总结 接口幂等性和并发安全是两个不同的概念,虽然它们在设计API时都很重要,但侧重点不同。 幂等性 定义:幂等性指的是无论对接口进行多少次相同的操作,结果都是一致的。例如,HTTP的PUT和DELE…...

【记录一下VMware上开虚拟端口映射到公网】
材料 win11 和装在vmware上的ubuntu 步骤一在Ubuntu上配置静态地址,配置如下 vim /etc/netplan/01-network-manager-all.yaml(此文件看系统上对应的是哪个文件,建议先备份)network:version: 2renderer: NetworkManagerethernets:ens33:dhcp4: falseadd…...

半导体器件制造5G智能工厂数字孪生物联平台,推进制造业数字化转型
半导体器件制造行业作为高科技领域的核心驱动力,正积极探索和实践以5G智能工厂数字孪生平台为核心的新型制造模式。这一创新不仅极大地提升了生产效率与质量,更为制造业的未来发展绘制了一幅智能化、网络化的宏伟蓝图。 在半导体器件制造5G智能工厂中&a…...
数据结构之存储位置
p 和 "hello,world"存储在内存哪个区域?( ) (鲁科安全) int main() { char *p "hello,world"; return 0; } p是栈区,”hello,world”是.ro段 一个由C/C编译的程序,会将占用的内存分为几个部分:堆、栈、代…...

传输层协议(TCP和UDP)
目录 一、UDP 1、UDPAPI 2、UDPAPI的使用 二、TCP 1、TCPAPI 2、TCP的相关特性 2.1 确认应答 2.2 超时重传 2.3 连接管理(三次握手,四次挥手) 2.4 滑动窗口 2.5 流量控制 2.6 拥塞控制 2.7 延时应答 2.8 捎带应答 2.9 面向字节…...

智能仓库|基于springBoot的智能无人仓库管理设计与实现(附项目源码+论文+数据库)
私信或留言即免费送开题报告和任务书(可指定任意题目) 目录 一、摘要 二、相关技术 三、系统设计 四、数据库设计 五、核心代码 六、论文参考 七、源码获取 一、摘要 互联网发展至今,无论是其理论还是技术都已经成熟…...
2.《DevOps》系列K8S部署CICD流水线之部署NFS网络存储与K8S创建StorageClass
架构 服务器IP服务名称硬件配置192.168.1.100k8s-master8核、16G、120G192.168.1.101k8s-node18核、16G、120G192.168.1.102k8s-node28核、16G、120G192.168.1.103nfs2核、4G、500G操作系统:Rocky9.3 后续通过K8S部署GitLab、Harbor、Jenkins 一、环境准备 #关闭防火墙开机自…...

【数据仓库】数据仓库常见的数据模型——维度模型
文章部分图参考自:多维数据模型各种类型(星型、雪花、星座、交叉连接) - 知乎 (zhihu.com) 文章部分文字canla一篇文章搞懂数据仓库:四种常见数据模型(维度模型、范式模型等)-腾讯云开发者社区-腾讯云 (ten…...
【Kubernetes】常见面试题汇总(三十)
目录 82. Worker 节点宕机,简述 Pods 驱逐流程。 特别说明: 题目 1-68 属于【Kubernetes】的常规概念题,即 “ 汇总(一)~(二十二)” 。 题目 69-113 属于【Kubernetes】的生产应用题。 8…...

【Web】PolarCTF2024秋季个人挑战赛wp
EZ_Host 一眼丁真命令注入 payload: ?host127.0.0.1;catf* 序列一下 exp: <?phpclass Polar{public $lt;public $b; } $pnew Polar(); $p->lt"system"; $p->b"tac /f*"; echo serialize($p);payload: xO:5:"Polar":2:{s:2:"…...
职业技能大赛-自动化测试笔记分享-2
一、时间等待处理 1、强制等待(无条件等待) 使用方法:time.sleep(delay) delay的单位为秒,delay设置多少秒页面就会等待多长时间,容易让线程挂掉,使程序抛异常,所以要慎用此方法。 #导入强制等待模块 import time from selenium import webdriverwd = webdriver.Chro…...

LeetCode讲解篇之1343. 大小为 K 且平均值大于等于阈值的子数组数目
文章目录 题目描述题解思路题解代码 题目描述 题解思路 题目让我们求长度为k的子数组并且该子数组的平均值大于threshold,对于这题,我们可以考虑维护一个长度为k的窗口,窗口不断向右滑动,遍历所有长度为k的子数组,我们…...

电子元件制造5G智能工厂物联数字孪生平台,推进制造业数字化转型
5G智能工厂与物联数字孪生平台的融合应用,不仅为电容器制造业注入了新的活力,更为整个制造业的数字化转型树立了新的标杆。电子元件制造过程中,数字孪生平台通过实时监测生产线的各个环节,实现了生产流程的可视化监控。管理人员可…...

【成品论文】2024年华为杯研赛E题25页高质量成品论文(后续会更新
您的点赞收藏是我继续更新的最大动力! 一定要点击如下的卡片链接,那是获取资料的入口! 点击链接加入【2024华为杯研赛资料汇总】:https://qm.qq.com/q/Mxv2XNWxUc https://qm.qq.com/q/Mxv2XNWxUc 高速公路应急车道紧急启用模型…...
【后端】【语言】【python】python常见操作
文章目录 1. List 操作2. JSON 操作3. Dict 操作 下面是分别演示 list、json、dict 操作 1. List 操作 my_list[] # List 操作示例 my_list [1, 2, 3, "apple", True]# 添加元素 my_list.append("new item") # [1, 2, 3, "apple", True, &qu…...

二叉树的链式结构和递归程序的递归流程图
二叉树的链式存储结构是指,用链表来表示一棵二叉树,即用链来指示元素的逻辑关系。 通常的方法是链表中每个结点由三个域组成,数据域和左右指针域,左右指针分别用来给出该结点左孩子和右孩子所在的链结点的存储地址 。链式结构又分…...

研究生如何利用 ChatGPT 帮助开展日常科研工作?
ChatGPT科研 一、 如何精读论文“三步提问法”1.为什么要做这个研究?这个研究是否值得我们做?2.他们怎么做这个研究3.他们发现了什么? 二、如何利用ChatGPT快速精读论文?首先,“三步走之第一步”--为什么要做这个研究&…...

【LLM学习之路】9月16日 第六天
【LLM学习之路】9月16日 第六天 损失函数 L1Loss 可以取平均也可以求和 参数解析 input (N,*) N是batchsize,星号代表可以是任意维度 不是输入的参数,只是描述数据 target 形状要同上 MSELoss平方差 CrossEntr…...

Qt_窗口界面QMainWindow的介绍
目录 1、菜单栏QMenuBar 1.1 使用QMainWindow的准备工作 1.2 在ui文件中设计窗口 1.3 在代码中设计窗口 1.4 实现点击菜单项的反馈 1.5 菜单中设置快捷键 1.6 菜单中添加子菜单 1.7 菜单项中添加分割线和图标 1.8 关于菜单栏创建方式的讨论 2、工具栏QToolBar …...

多云管理“拦路虎”:深入解析网络互联、身份同步与成本可视化的技术复杂度
一、引言:多云环境的技术复杂性本质 企业采用多云策略已从技术选型升维至生存刚需。当业务系统分散部署在多个云平台时,基础设施的技术债呈现指数级积累。网络连接、身份认证、成本管理这三大核心挑战相互嵌套:跨云网络构建数据…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)
题目 做法 启动靶机,点进去 点进去 查看URL,有 ?fileflag.php说明存在文件包含,原理是php://filter 协议 当它与包含函数结合时,php://filter流会被当作php文件执行。 用php://filter加编码,能让PHP把文件内容…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...

【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目
应用场景: 1、常规某个机器被钓鱼后门攻击后,我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后,我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...

CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...