初识Mybatis

Mybatis的概念

        MyBatis 是一个Java 持久层框架,核心作用是简化数据库操作,把 SQL 和 Java 代码解耦。

ORM框架

        MyBatis是一个ORM 框架

        所谓ORM 框架,就是把数据库里的表、字段、关系,映射成编程语言里的类、属性、对象引用,从而让我们用“面向对象”的方式去操作关系型数据库,而不用写大量繁复的 JDBC/SQL。

        简而言之,半自动化ORM,将SQL与Java对象映射,不自动生成SQL,只负责把“你写的 SQL”和“你写的 Java 对象”精准地对接起来,半自动化 ORM 是“SQL 与 Java 对象之间的翻译官”。

核心组件

SqlSessionFactory

       作用:  MyBatis 的核心工厂,负责创建和管理  SqlSession  实例。

特点

  • 全局单例:在整个应用中只需要一个实例,线程安全。
  • 初始化:加载 MyBatis 配置文件、解析映射文件,初始化数据库连接池等资源。

功能: 通过  openSession()  方法创建  SqlSession  实例,用于执行 SQL 操作。


SqlSession

作用:MyBatis 的一个会话对象,用于执行 SQL 操作。

特点

  • 线程不安全:每次请求或操作数据库时需要创建一个新的实例,用完后必须关闭。
  • 功能:提供  crud等方法,用于执行 SQL 语句。它还管理事务(提交或回滚)。
  • 生命周期:通常与一个请求或一个业务操作绑定,用完即关闭。
Executor

作用:它是 SqlSession的底层执行器,负责执行 SQL 语句。

类型

  • Simple:每次执行 SQL 时都创建新的 Statement,适合简单场景。
  • Reuse:复用 Statement,减少 Statement 的创建和销毁开销。
  • Batch:批量执行 SQL,适合批量插入或更新操作,可以减少数据库交互次数。

功能:负责执行 SQL 语句,管理 Statement 的生命周期,以及维护一级缓存。


MapperProxy

作用:它是 MyBatis 的动态代理机制,用于实现 Mapper 接口。

特点

  • 动态代理:通过 JDK 动态代理技术,为 Mapper 接口生成代理实例。
  • 功能:将 Mapper 接口的方法调用转换为具体的 SQL 执行操作。
  • 解耦:让开发者只需要关注 Mapper 接口的定义,而不需要关心底层的 SQL 执行细节。

配置文件

此处介绍xml的配置文件,在此文件中添加数据源、事务管理器、类型别名、插件等配置。

全局配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config
3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>
<!--    配置mybatis的环境--><environments default="mysql">
<!--        id和default的值必须保持一致,接下来配置连接mysql的具体信息--><environment id="mysql">
<!--            配置事务类型  JDBC--><transactionManager type="JDBC"></transactionManager>
<!--            配置数据源  它的取值有POOLED 和 UNPOOLED  前者是mysql提供的默认数据源进行数据库的连接
后者是不使用数据源,多次与数据库进行交互--><dataSource type="POOLED">
<!--                配置连接数据库的驱动 url 用户名和密码--><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments>
<!--    在核心配置文件里要导入接口的映射文件--><mappers><mapper resource="com/noy/dao/UserDao.xml"></mapper></mappers>
</configuration>

Mapper XML 文件

若要通过xml来执行SQL操作,那么Mapper 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">
<!--namespace  命名空间  值必须唯一 一般写接口的全限定名即可
-->
<mapper namespace="com.noy.dao.UserDao">
<!--
select标签  就是一个执行查询操作的标签
id必须和接口方法名称一样,才可以保持映射成功
parameterType参数类型的意思,这里不传参可以不写
resultType 是接口的返回值   如果是泛型 ,写泛型的全限定名
--><select id="findAll" resultType="com.noy.pojo.User">SELECT * FROM user</select>
</mapper>

搭建mybatis入门案例的步骤

  1. 导入mybatis相关的依赖
  2. 创建pojo,将pojo和数据表进行关联映射  定义接口
  3. 创建mybatis的核心配置文件sqlMapConfig.xml
  4. 创建接口的映射文件    接口所在的目录  和接口文件所在的目录保持一致
  5. 编写测试代码

SQL映射

        本质上是解耦 SQL 与 Java 代码,通过声明式配置实现数据库操作

基础 CRUD 标签

标签核心属性
<select>idresultType/resultMap
<insert>idparameterType
<update>idparameterType
<delete>idparameterType

id  必须与 Mapper 接口方法同名,MyBatis 就靠这个把接口方法与 SQL 绑定在一起。

参数 & 占位符

#{}表示一个占位符号 通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换,
#{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。如果 parameterType 传输单个简单类 型值,#{}括号中可以是 value 或其它名称。${}表示拼接 sql 串 通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换,
${}可以接收简单类型值或 pojo 属性值,如果 parameterType传输单个简单类型值,${}括号中只能是value。

总而言之,安全用  #{} ,拼接才用  ${} 

列表演示:

特性#{} (预编译占位符)${} (字符串替换)
SQL 安全防止 SQL 注入 ✅有注入风险 ❗
类型处理自动类型转换 (Java→JDBC)直接字符串替换
使用场景值参数(WHERE 条件值)动态表名/列名
日志输出? 占位符替换后的完整 SQL

返回结果

resultType :简单场景,直接写全限定类名或别名,列名与属性名一致即可自动映射。
例: <select id="getById" resultType="com.noy.User"> 

resultMap :复杂场景,自定义映射规则(列名≠属性名、一对多、枚举转换等)。
例: <resultMap id="userMap" type="User"><result column="user_name" property="name"/></resultMap> 

主键回填(insert 专属)

 useGeneratedKeys="true"  开启 JDBC 自动生成主键回填。

keyProperty="id"  指定把数据库生成的主键值塞进参数对象的哪个属性。

<insert id="save" parameterType="User"useGeneratedKeys="true" keyProperty="id">INSERT INTO user(name) VALUES(#{name})
</insert>

插入完成后, User#getId()  就能直接拿到新主键。

多级映射

        一个人可能有不同的身份,不同的人可能有同一种身份,不同的人也可能会有不同的身份,所以映射也是如此

关系类型数据库表现对象关系示例MyBatis 标签使用场景
一对一主表外键指向关联表主键用户 ↔ 身份证<association>用户详情页显示身份证信息
一对多主表主键出现在关联表的外键字段部门 ↔ 员工<collection>部门页面显示下属员工列表
多对多通过中间表维护两个主表的关系学生 ↔ 课程两个<collection>学生选课系统/课程学生名单

一对一

        SQL

CREATE TABLE user (id INT PRIMARY KEY,name VARCHAR(50)
);CREATE TABLE id_card (id INT PRIMARY KEY,card_number VARCHAR(20),user_id INT UNIQUE,  -- 唯一外键FOREIGN KEY (user_id) REFERENCES user(id)
);

        Java

public class User {private Integer id;private String name;private IdCard idCard; // 一对一关联对象
}public class IdCard {private String cardNumber;
}

        MyBatis 映射

<resultMap id="userMap" type="User"><id property="id" column="user_id"/><result property="name" column="user_name"/><!-- 一对一映射 --><association property="idCard" javaType="IdCard"><result property="cardNumber" column="card_number"/></association>
</resultMap><select id="getUserWithCard" resultMap="userMap">SELECT u.id AS user_id, u.name AS user_name,c.card_numberFROM user uJOIN id_card c ON u.id = c.user_idWHERE u.id = #{id}
</select>
一对多

        SQL

CREATE TABLE department (id INT PRIMARY KEY,name VARCHAR(50)
);CREATE TABLE employee (id INT PRIMARY KEY,name VARCHAR(50),dept_id INT,  -- 非唯一外键FOREIGN KEY (dept_id) REFERENCES department(id)
);

        Java

public class Department {private Integer id;private String name;private List<Employee> employees; // 一对多关联集合
}public class Employee {private String name;
}

        MyBatis 映射

<resultMap id="deptMap" type="Department"><id property="id" column="dept_id"/><result property="name" column="dept_name"/><!-- 一对多映射 --><collection property="employees" ofType="Employee"><result property="name" column="emp_name"/></collection>
</resultMap><select id="getDeptWithEmployees" resultMap="deptMap">SELECT d.id AS dept_id,d.name AS dept_name,e.name AS emp_nameFROM department dLEFT JOIN employee e ON d.id = e.dept_idWHERE d.id = #{id}
</select>
多对多

        SQL

CREATE TABLE student (id INT PRIMARY KEY,name VARCHAR(50)
);CREATE TABLE course (id INT PRIMARY KEY,name VARCHAR(50)
);-- 中间表
CREATE TABLE student_course (student_id INT,course_id INT,PRIMARY KEY (student_id, course_id),FOREIGN KEY (student_id) REFERENCES student(id),FOREIGN KEY (course_id) REFERENCES course(id)
);

        Java

public class Student {private Integer id;private String name;private List<Course> courses; // 多对多关联
}public class Course {private String name;private List<Student> students; // 反向关联(可选)
}

       MyBatis 映射

<resultMap id="studentMap" type="Student"><id property="id" column="student_id"/><result property="name" column="student_name"/><!-- 多对多映射(通过中间表) --><collection property="courses" ofType="Course"><result property="name" column="course_name"/></collection>
</resultMap><select id="getStudentWithCourses" resultMap="studentMap">SELECT s.id AS student_id,s.name AS student_name,c.name AS course_nameFROM student sJOIN student_course sc ON s.id = sc.student_idJOIN course c ON sc.course_id = c.idWHERE s.id = #{id}
</select>

实际上,一对多/多对多使用<collection>时,大数据量建议开启延迟加载,具体操作见下列映射策略

映射策略

  • 自动映射:配置 autoMappingBehavior (PARTIAL/FULL/NONE)

  • 嵌套查询<association select="queryDeptById"> + column="dept_id"

  • 延迟加载:在全局启用 lazyLoadingEnabled=true

<settings><!-- 开启全局延迟加载 --><setting name="lazyLoadingEnabled" value="true"/><!-- 关闭积极加载(3.4.1+ 默认为 false,高于此版本的mybatis可以不写) --><setting name="aggressiveLazyLoading" value="false"/>
</settings>

动态 SQL用法

其目的为

  • 动态生成 SQL:根据参数条件自动拼接不同 SQL 片段

  • 替代硬编码:避免在 Java 中手动拼接 SQL 字符串

  • 智能去除多余关键字(AND/OR/)

  • 用声明式 XML 标签代替过程式代码拼接,使 SQL 更清晰、更安全、更易维护。

核心标签为

标签作用常用场景
<if>条件判断按需添加 WHERE 条件
<choose>多选一(类似 switch-case)多种查询方案选择
<where>智能处理 WHERE 子句自动去除开头多余的 AND/OR
<set>智能处理 UPDATE 的 SET 子句自动去除尾部逗号
<foreach>遍历集合IN 查询、批量插入

它们的用法语法也类似于Java

基础条件控制 <if>

<select id="search">SELECT * FROM users<where><!-- 姓名不为空时添加条件 --><if test="name != null">AND name = #{name}</if><!-- 年龄大于0时添加条件 --><if test="age > 0">AND age > #{age}</if></where>
</select>

 多分支选择 <choose>

<select id="getData">SELECT * FROM products<where><choose><!-- 优先按ID查 --><when test="id != null">id = #{id}</when><!-- 其次按名称查 --><when test="name != null">name LIKE #{name}</when><!-- 默认查上架商品 --><otherwise>status = 'ON_SALE'</otherwise></choose></where>
</select>

智能更新 <set>

<update id="updateUser">UPDATE users<set><!-- 动态更新字段 --><if test="name != null">name=#{name},</if><if test="email != null">email=#{email},</if>update_time = NOW() <!-- 固定更新 --></set>WHERE id = #{id}
</update>

集合遍历 <foreach>

<!-- IN 查询 -->
<select id="findByIds">SELECT * FROM usersWHERE id IN<foreach item="id" collection="ids" open="(" separator="," close=")">#{id}</foreach>
</select><!-- 批量插入 -->
<insert id="batchInsert">INSERT INTO users (name, age)VALUES<foreach item="user" collection="list" separator=",">(#{user.name}, #{user.age})</foreach>
</insert>

此外,在动态SQL中,WHERE条件 → 用 <where> 标签,UPDATE 操作 → 用 <set> 标签

空集合处理

<!-- 检查集合非空 -->
<if test="list != null and !list.isEmpty()">...
</if>

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

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

相关文章

使用Jeecg低代码平台实现计划管控系统建设方案--2平台学习

1.前后端列表练习 前端页面下的views下的system下的基本都是系统管理的东西。 在system下新建一个目录edu。 index基本就是列表页面。 modal就是新增编辑弹窗。 api就是接口。 data就是列配置。 一些组件的使用可以参考官方文档&#xff0c;help.jeecg.com。 在创建一个…

调试|谷歌浏览器调试长连接|调试SSE和websocket

长连接需求不常有&#xff0c;控制台调试的细节容易忘&#xff0c;在这截图备忘。本文会记录SSE、websocket连接、普通接口 在谷歌浏览器控制台的对比 文章目录SSE&#xff08;Server-Sent Events&#xff09;观察对象&#xff1a;百度翻译观察请求头和响应头观察EventStream观…

VS2019 Qt5.14.2 OpenCV4.4.0 全流程安装及开发环境搭建与配置(工业相机环境配置)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言Visual Studio 2019 安装步骤项目配置验证Qt 5.14.2 安装步骤项目配置验证Visual Studio Qt 拓展&#xff08;确定项目后&#xff09;OpenCV 4.4.0 安装步骤项目…

正确配置jdk环境但IntelliJ IDEA无法启动

现象&#xff1a;今天突然发现开发工具双击没有正常启动&#xff0c;之前是用着的。问题排查&#xff1a;是否是因为jdk环境变量导致的&#xff0c;之前安装过安卓的开发环境也修改过环境变量。步骤一&#xff1a;cmd输入java -version 或javac&#xff0c;如图没有反应步骤二&…

ubuntu-server安装

1.下载系统镜像&#xff1a; 阿里云镜像站下载服务器镜像 https://mirrors.aliyun.com/ubuntu-releases/24.04/ubuntu-24.04.2-live-server-amd64.iso 1.创建新的虚拟机 按住键盘ctrl n 打开虚拟机创建界面 用光标选择对应语言没有中文哈 然后回车确认 设置计算机名、用户名…

Docker Compose管理新范式:可视化控制台结合cpolar提升容器编排效率?

文章目录前言1. 安装Docker2. 检查本地docker环境3. 安装cpolar内网穿透4. 使用固定二级子域名地址远程访问前言 在容器化应用部署领域&#xff0c;Docker Compose UI为开发者提供了一种更直观的解决方案。这款工具以Web界面形式封装了Docker Compose的核心功能&#xff0c;在…

BSW总结

1.FBL&#xff1a;【有道云笔记】BSW_FBL https://share.note.youdao.com/s/NaeZWTuR 2.NM: 【有道云笔记】BSW_NM https://share.note.youdao.com/s/MKxlIpUS

spring循环依赖解决

问题描述 spring循环依赖是对于ioc容器。类A、B、C&#xff0c;类A依赖了B&#xff0c;类A依赖了C&#xff0c;类B依赖了A&#xff0c;类C依赖了A。假如现在类A需要放到ioc&#xff0c;属性赋值的时候会去找B这个bean&#xff0c;但是B不存在&#xff0c;于是去创建B这个bean&a…

最新安卓原生对接苹果cms App后端+app(最新优化版)

内容目录一、详细介绍二、效果展示1.部分代码2.效果图展示三、学习资料下载一、详细介绍 一定要按照教程教的来搭建&#xff01; App演示图片 二、效果展示 1.部分代码 代码如下&#xff08;示例&#xff09;&#xff1a; public static function apkinfo(){return self::…

嵌入式硬件中运放的基本控制原理

上次课的最后是给大家总结一些基础电子知识的,我们接着往下讲。我们知道了运放的虚短虚断的概念理论上来说 可以进行计算了是吧。 这个图实际上是一个正输入信号的同相放大电路,我们看下如何计算,第一先看虚断。运放的输入脚内部对地是阻抗十分大是吧,那么这个正输入脚上的…

聚集索引与非聚集索引的区别

聚集索引&#xff08;Clustered Index&#xff09;和非聚集索引&#xff08;Non-Clustered Index&#xff09;是索引设计的核心概念&#xff0c;二者的本质区别体现在 与数据物理存储的关联方式 上&#xff0c;这种区别直接决定了它们的性能特性和适用场景。我们平时说的 聚簇索…

《零基础入门AI:传统机器学习进阶(从拟合概念到K-Means算法)》

一、欠拟合与过拟合欠拟合(Underfitting) 欠拟合是指模型在训练数据上表现不佳&#xff0c;同时在新的未见过的数据上也表现不佳。这通常发生在模型过于简单&#xff0c;无法捕捉数据中的复杂模式时。欠拟合模型的表现特征如下&#xff1a; 训练误差较高。测试误差同样较高。模…

Datawhale AI夏令营 第三期 task2 稍微改进

在打造基于大语言模型&#xff08;LLM&#xff09;文档检索的问答系统中&#xff0c;财经研报类文档是最具挑战的场景之一。它包含图文混排、精细定位需求&#xff08;页码、文件名&#xff09;、问题措辞高度多样化等一系列复杂性。 下面的内容是大模型辅助整理的&#xff1a;…

LeetCood算法题~水果成篮

水果成篮 你正在探访一家农场&#xff0c;农场从左到右种植了一排果树。这些树用一个整数数组 fruits 表示&#xff0c;其中 fruits[i] 是第 i 棵树上的水果 种类 。你想要尽可能多地收集水果。然而&#xff0c;农场的主人设定了一些严格的规矩&#xff0c;你必须按照要求采摘水…

【Lua】题目小练8

-- 题目 1&#xff1a;定义一个类 Person-- 属性&#xff1a;name、age&#xff0c;其中 age 默认是 0&#xff0c;不能小于 0。-- 方法&#xff1a;introduce()&#xff0c;输出 "My name is <name>, I am <age> years old."-- 要求使用封装思想&#x…

SAP PP CK466

原因 作业价格没有维护 解决方案 KP26

如何解决pip安装报错ModuleNotFoundError: No module named ‘keras’问题

【Python系列Bug修复PyCharm控制台pip install报错】如何解决pip安装报错ModuleNotFoundError: No module named ‘keras’问题 摘要 在使用 PyCharm 进行深度学习项目开发时&#xff0c;常常需要通过 pip install keras 来安装 Keras 库。但有时即便命令执行成功&#xff0c…

人工智能领域、图欧科技、IMYAI智能助手2024年全年历史更新大事件汇总

2024年 2024年12月29日 【通知】 1、主站导出文档功能优化升级&#xff0c;新增支持了纯文本WORD导出功能&#xff0c;支持使用WPS软件打开 注&#xff1a;原来的富文本WORD不支持使用WPS打开&#xff0c;只支持系统自带的WORD软件打开&#xff0c;比如Microsoft Office Word 2…

UWB实操:使用UCI CMD测距;UCI CMD是一串数字,创建测距session,配置测距session,开始测距session。

使用UCI CMD测距; UCI CMD是一串数字,创建测距session,配置测距session,开始测距session。根据 FiRa_UCI_Technical_Specification,我们可以分析并组织测距cmd 例如: Fira2.0 1v1 发起 DSTWR 创建测距session:210000052222222200 配置测距session: 2103001F222…

从AUTOSAR角度理解CAN以及CANFD

一、AUTOSAR对CAN和CAN FD的基础定位 CAN&#xff1a;基于传统CAN 2.0B协议&#xff0c;是AUTOSAR早期版本&#xff08;如4.0.3及之前&#xff09;的核心车载通信协议&#xff0c;支持最大8字节 payload&#xff0c;仲裁段波特率通常≤1Mbps&#xff0c;适用于低带宽、高实时性…