Java——MyBatis从入门到精通:一站式学习指南

MyBatis从入门到精通:一站式学习指南

作为一款优秀的半自动ORM框架,MyBatis以其灵活的SQL控制和简洁的配置方式,成为Java后端开发中持久层框架的首选。本文将从基础概念到高级特性,全面讲解MyBatis的使用方法,包含实用代码示例和最佳实践。

一、MyBatis核心概念

1. 什么是MyBatis?

MyBatis是一款半自动ORM(对象关系映射)框架,本质是对JDBC的封装。与全自动ORM框架(如Hibernate)不同,MyBatis需要开发者手动编写SQL语句,但免除了JDBC中繁琐的连接管理、参数设置和结果集解析工作。

其核心优势在于:

  • 支持自定义SQL,便于复杂查询和性能优化
  • 强大的结果映射能力,自动完成数据库记录与Java对象的转换
  • 轻量灵活,易于集成Spring等主流框架
  • 适用于高并发、大数据量的互联网项目

2. 核心组件

MyBatis的工作流程依赖于以下核心组件:

  • SqlSessionFactory:会话工厂,由SqlSessionFactoryBuilder根据配置文件创建,全局唯一
  • SqlSession:数据库会话对象,用于执行SQL操作,生命周期为方法级
  • Mapper接口:定义数据库操作方法的接口,无需实现类,MyBatis通过动态代理生成实现
  • 映射文件:存储SQL语句和映射规则,与Mapper接口对应

二、环境搭建(Maven)

1. 引入依赖

pom.xml中添加MyBatis核心依赖和数据库驱动:

<dependencies><!-- MyBatis核心包 --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.7</version></dependency><!-- MySQL驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency><!-- 单元测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency>
</dependencies>

2. 核心配置文件

创建mybatis-config.xml(放在resources目录下),配置数据库连接和映射文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 环境配置 --><environments default="mysql"><environment id="mysql"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis_db?serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="root"/></dataSource></environment></environments><!-- 注册映射文件 --><mappers><mapper resource="mapper/UserMapper.xml"/></mappers>
</configuration>

三、基本CRUD操作

1. 定义实体类

创建与数据库表对应的POJO类:

public class User {private Integer id;private String username;private String sex;private String address;// 省略getter、setter和toString方法
}

2. Mapper接口与映射文件

(1)Mapper接口
public interface UserMapper {// 查询所有用户List<User> findAll();// 根据ID查询User findById(Integer id);// 新增用户void add(User user);// 更新用户void update(User user);// 删除用户void delete(Integer id);
}
(2)映射文件(UserMapper.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">
<mapper namespace="com.example.mapper.UserMapper"><!-- 查询所有 --><select id="findAll" resultType="com.example.pojo.User">select * from user</select><!-- 根据ID查询 --><select id="findById" parameterType="int" resultType="com.example.pojo.User">select * from user where id = #{id}</select><!-- 新增 --><insert id="add" parameterType="com.example.pojo.User">insert into user(username, sex, address) values(#{username}, #{sex}, #{address})</insert><!-- 更新 --><update id="update" parameterType="com.example.pojo.User">update user set username = #{username}, sex = #{sex}, address = #{address} where id = #{id}</update><!-- 删除 --><delete id="delete" parameterType="int">delete from user where id = #{id}</delete>
</mapper>

3. 测试代码

public class UserMapperTest {private SqlSession session;private UserMapper userMapper;@Beforepublic void init() throws IOException {// 读取配置文件InputStream is = Resources.getResourceAsStream("mybatis-config.xml");// 创建SqlSessionFactorySqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);// 获取SqlSessionsession = factory.openSession();// 获取Mapper代理对象userMapper = session.getMapper(UserMapper.class);}@Testpublic void testFindAll() {List<User> users = userMapper.findAll();users.forEach(System.out::println);}@Testpublic void testAdd() {User user = new User();user.setUsername("张三");user.setSex("男");user.setAddress("北京");userMapper.add(user);session.commit(); // 手动提交事务}@Afterpublic void destroy() {session.close();}
}

注意:MyBatis的事务默认手动提交,执行增删改操作后需调用session.commit()

四、动态SQL

动态SQL是MyBatis的强大特性,可根据条件动态生成SQL片段,避免手动拼接SQL的繁琐和错误。

1. <if>标签:条件判断

<select id="findByCondition" parameterType="com.example.pojo.User" resultType="com.example.pojo.User">select * from user<where><if test="username != null and username != ''">and username like #{username}</if><if test="sex != null and sex != ''">and sex = #{sex}</if></where>
</select>
  • <where>标签会自动处理多余的AND,替代传统的where 1=1写法

2. <foreach>标签:遍历集合

用于批量操作(如批量删除):

<delete id="deleteBatch" parameterType="int">delete from user where id in<foreach collection="array" open="(" close=")" separator="," item="id">#{id}</foreach>
</delete>
  • collection:集合类型(数组用array,List用list
  • item:遍历的元素名
  • open/close:SQL片段的开始/结束符
  • separator:元素间的分隔符

3. <choose>标签:多条件分支

类似Java的switch-case

<select id="findByLevel" parameterType="User" resultType="User">select * from user<where><choose><when test="level == 1">and age &lt; 18</when><when test="level == 2">and age between 18 and 30</when><otherwise>and age &gt; 30</otherwise></choose></where>
</select>

五、缓存机制

MyBatis提供两级缓存,用于减少数据库交互,提高查询效率。

1. 一级缓存

  • 作用域:SqlSession(会话级)
  • 特性:默认开启,同一SqlSession内的相同查询会复用缓存
  • 失效场景:执行增删改操作、调用clearCache()commit()、关闭SqlSession
@Test
public void testL1Cache() {// 第一次查询(从数据库获取)User user1 = userMapper.findById(1);// 第二次查询(从一级缓存获取)User user2 = userMapper.findById(1);System.out.println(user1 == user2); // true
}

2. 二级缓存

  • 作用域:SqlSessionFactory(应用级)
  • 特性:需手动开启,同一工厂创建的SqlSession共享缓存
  • 要求:缓存的POJO需实现Serializable接口

开启步骤:

  1. 配置全局开关(mybatis-config.xml):
<settings><setting name="cacheEnabled" value="true"/>
</settings>
  1. 在映射文件中声明缓存:
<mapper namespace="com.example.mapper.UserMapper"><cache size="1024"/> <!-- 开启二级缓存 --><!-- SQL语句... -->
</mapper>
  1. 实体类实现序列化:
public class User implements Serializable {// 字段和方法...
}

六、关联查询

MyBatis支持一对一、一对多等关联查询,通过<association><collection>标签实现。

1. 一对一查询(如学生-班级)

<resultMap id="studentMap" type="com.example.pojo.Student"><id property="id" column="sid"/><result property="name" column="sname"/><!-- 关联班级对象 --><association property="clazz" column="cid" javaType="com.example.pojo.Clazz"><id property="id" column="cid"/><result property="name" column="cname"/></association>
</resultMap><select id="findStudentWithClazz" resultMap="studentMap">select s.id sid, s.name sname, c.id cid, c.name cnamefrom student s left join clazz c on s.cid = c.id
</select>

2. 一对多查询(如班级-学生)

<resultMap id="clazzMap" type="com.example.pojo.Clazz"><id property="id" column="cid"/><result property="name" column="cname"/><!-- 关联学生集合 --><collection property="students" column="cid" ofType="com.example.pojo.Student"><id property="id" column="sid"/><result property="name" column="sname"/></collection>
</resultMap><select id="findClazzWithStudents" resultMap="clazzMap">select c.id cid, c.name cname, s.id sid, s.name snamefrom clazz c left join student s on c.id = s.cid
</select>

七、MyBatis Generator自动生成代码

MyBatis Generator(MBG)是官方代码生成器,可根据数据库表自动生成POJO、Mapper接口和映射文件,减少重复工作。

1. 配置MBG插件(pom.xml)

<build><plugins><plugin><groupId>org.mybatis.generator</groupId><artifactId>mybatis-generator-maven-plugin</artifactId><version>1.3.7</version><configuration><configurationFile>src/main/resources/generatorConfig.xml</configurationFile><overwrite>true</overwrite></configuration></plugin></plugins>
</build>

2. 编写配置文件(generatorConfig.xml)

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfigurationPUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN""http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration><!-- 数据库驱动路径 --><classPathEntry location="F:/maven/repository/mysql/mysql-connector-java/8.0.26/mysql-connector-java-8.0.26.jar"/><context id="mysql" targetRuntime="MyBatis3"><!-- 去除注释 --><commentGenerator><property name="suppressAllComments" value="true"/></commentGenerator><!-- 数据库连接 --><jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"connectionURL="jdbc:mysql://localhost:3306/mybatis_db"userId="root"password="root"/><!-- 生成POJO --><javaModelGenerator targetPackage="com.example.pojo" targetProject="src/main/java"/><!-- 生成映射文件 --><sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/><!-- 生成Mapper接口 --><javaClientGenerator type="XMLMAPPER"targetPackage="com.example.mapper"targetProject="src/main/java"/><!-- 指定表 --><table tableName="user"/></context>
</generatorConfiguration>

3. 运行生成命令

在Maven插件中执行mybatis-generator:generate,自动生成以下文件:

  • User.java:POJO类
  • UserMapper.java:Mapper接口
  • UserMapper.xml:映射文件
  • UserExample.java:复杂查询条件构建类

八、分页插件PageHelper

PageHelper是MyBatis常用的分页插件,可简化分页查询实现。

1. 引入依赖

<dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.0</version>
</dependency>

2. 配置插件(mybatis-config.xml)

<plugins><plugin interceptor="com.github.pagehelper.PageInterceptor"><property name="helperDialect" value="mysql"/></plugin>
</plugins>

3. 使用示例

@Test
public void testPage() {// 设置分页参数(页码从1开始,每页3条)PageHelper.startPage(1, 3);// 执行查询List<User> users = userMapper.findAll();// 封装分页结果PageInfo<User> pageInfo = new PageInfo<>(users);System.out.println("总条数:" + pageInfo.getTotal());System.out.println("总页数:" + pageInfo.getPages());System.out.println("当前页数据:" + pageInfo.getList());
}

总结

MyBatis以其灵活性和高效性,在Java持久层框架中占据重要地位。本文从环境搭建到高级特性,涵盖了MyBatis的核心用法,包括CRUD操作、动态SQL、缓存机制、关联查询等。掌握这些内容后,可轻松应对日常开发中的数据库操作需求。

建议在实际项目中根据场景选择XML配置或注解开发(XML更适合复杂SQL,注解更简洁),并合理使用缓存和分页插件优化性能。

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

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

相关文章

面试150 添加与搜索单词--数据结构设计

思路 通过哈希法去实现&#xff0c;这里主要描述search的思路&#xff1a;如果’.‘不在word中&#xff0c;我们只需要去查询word在不在set中。如果’.‘存在&#xff0c;我们对哈希中的字符串进行遍历w&#xff0c;如果当前字符串的长度不等于word跳过,对word进行遍历&#xf…

学习打卡网站(搭子版本)

概述 之前用了网上的一些学习打卡类app&#xff0c;基本都是收费的&#xff0c;而且有些自己想要的功能却没有&#xff0c;甚至还有广告&#xff0c;正好暑假是个需要容易懒惰的时间&#xff0c;所以干脆自己做了一个能和学习搭子一起记录计划的小网站。 昨天早上开始写&#x…

分享如何在Window系统的云服务器上部署网站及域名解析+SSL

最近看到阿里云的服务器有个199的活动&#xff0c;买了个2核4G带宽5M的服务器&#xff0c;用于小网站的运营也足够&#xff0c;于是就买一个&#xff0c;并且我还挑了个新加坡的站点&#xff0c;本想着运营独立站&#xff0c;用新加坡的站点外网访问会更友好一点。于是问题就来…

FastAdmin系统框架通用操作平滑迁移到新服务器的详细步骤-优雅草卓伊凡

FastAdmin系统框架通用操作平滑迁移到新服务器的详细步骤-优雅草卓伊凡我们蜻蜓hr系统采用的后端框架就是fastadmin&#xff0c;因此我们平稳迁移以此为例&#xff0c;为什么要迁移一份是因为有甲方需要。迁移FastAdmin系统到新服务器需要确保数据完整性和系统功能正常。以下是…

Request和Response相关介绍

Request 和 Response 是什么&#xff1f; Request&#xff08;请求对象&#xff09;&#xff1a;用来接收浏览器发过来的数据。 Response&#xff08;响应对象&#xff09;&#xff1a;用来把服务器处理后的结果返回给浏览器。 1. request 的作用&#xff08;获取请求数据&am…

Springboot 实现热部署

spring为开发者提供了一个名为spring-boot-devtools的模块来使Spring Boot应用支持热部署&#xff0c;提高开发者的开发效率&#xff0c;无需手动重启Spring Boot应用。引入依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>s…

虚拟机扩展磁盘容量后扩展分区大小

1. 首先检查磁盘剩余空间sudo fdisk -l /dev/sda2. 如果有未分配空间&#xff0c;直接扩展分区sudo fdisk /dev/sda在fdisk交互界面中&#xff0c;依次写入d # 删除分区 3 # 例如选择分区3&#xff08;/dev/sda3&#xff09; n # 新建分区 p # 主分区 3 # 分区号3 # 起始扇…

元宇宙与游戏:虚实交融的数字文明新纪元

引言&#xff1a;当游戏遇见元宇宙在纽约现代艺术博物馆&#xff08;MoMA&#xff09;的"虚拟世界"特展中&#xff0c;一幅数字艺术作品《元宇宙诞生》引发观展热潮。这幅由AI与人类艺术家共同创作的作品&#xff0c;描绘了游戏《堡垒之夜》的虚拟演唱会与现实世界交…

音视频学习(四十二):H264帧间压缩技术

必要性与优势 原始数字视频数据量庞大&#xff0c;未经压缩的视频难以有效传输和存储。例如&#xff0c;一个 1080p、30fps 的无压缩视频&#xff0c;每秒数据量可达数百兆比特。视频压缩的目标是在保证视觉质量的前提下&#xff0c;最大限度地减少数据冗余。视频数据中存在多种…

微服务雪崩防护最佳实践之sentinel

思考1、当服务访问量达到一定程度&#xff0c;流量扛不住的时候&#xff0c;该如何处理&#xff1f;2、服务之间相互依赖&#xff0c;当服务A出现响应时间过长&#xff0c;影响到服务B的响应&#xff0c;进而产生连锁反应&#xff0c;直至影响整个依赖链上的所有服务&#xff0…

阿里云监控及运维常见问题

云监控介绍&#xff1a;阿里云的云监控服务&#xff08;CloudMonitor&#xff09;是一款简单易用、功能强大的监控工具&#xff0c;主要用来帮助用户实时监控阿里 云上的各种资源&#xff08;比如服务器、数据库、网络等&#xff09;&#xff0c;并在出现问题时及时发出警报&am…

深入解析 vLLM 分布式推理与部署策略

在当今人工智能快速发展的时代&#xff0c;大型语言模型&#xff08;LLM&#xff09;的推理和部署面临着诸多挑战&#xff0c;尤其是当模型规模日益庞大时&#xff0c;如何高效地利用硬件资源成为关键问题。vLLM 作为一种强大的工具&#xff0c;为分布式推理和部署提供了多种策…

PostgreSQL 终端命令详解及实际应用案例

PostgreSQL 作为一款功能强大的开源关系型数据库&#xff0c;其终端命令是数据库管理员、开发人员日常操作的核心工具。这些命令覆盖数据库连接、对象管理、数据操作、备份恢复、权限控制等多个维度&#xff0c;掌握其实际应用场景能显著提升工作效率。本文结合不同行业的实操案…

步进电机基础

1、ENABLE‾\overline{ENABLE}ENABLE 的意思&#xff1a; ENABLE上面的横线表示这是一个低电平有效的信号&#xff1a;当ENABLE信号为低电平&#xff08;0V或逻辑0&#xff09;时&#xff0c;芯片被使能&#xff08;激活&#xff09;当ENABLE信号为高电平&#xff08;VDD或逻辑…

Redis进阶--缓存

目录 一、引言 二、介绍 1.为什么Mysql的速度慢呢&#xff1f; 2.缓存更新策略 1.定期生成 2.实时生成 3.redis的内存淘汰机制 4.注意事项 1.缓存预热 2.缓存穿透 3.缓存击穿 4.缓存雪崩 三、总结 一、引言 本篇文章将介绍Redis其中一个重要的作用&#xff0c;作为…

微软原版系统下载的几个好用网站

“不要因为走得太远&#xff0c;而忘记为什么出发。” 愿每一位Windows用户&#xff0c;都能在这份情怀中找到属于自己的小确幸&#xff01;满满的情怀&#xff01; 微软官方渠道 微软官网提供纯净的ISO镜像下载&#xff0c;适用于Windows 10/11等系统。访问Microsoft官网下…

kotlin Flow快速学习2025

其实&#xff0c;第一章节&#xff0c;只是让你了解下Flow的基本情况。我们开发中&#xff0c;基本很少使用这种模式。所以来讲&#xff0c;我们甚至可以直接使用StateFlow和SharedFlow才是正途。这是很多教程没有说明的点。所以第一章随便浏览下即可。日后再补充理解都是可以的…

【人工智能99问】什么是教师强制?(16/99)

文章目录什么是教师强制&#xff1f;教师强制&#xff08;Teacher Forcing&#xff09;的定义原比例&#xff08;Original Proportion&#xff09;教师强制的举例说明&#xff08;一&#xff09;教师强制的举例说明&#xff08;二&#xff09;优点和缺点解决曝光偏差的方法什么…

【WPF】WPF 自定义控件之依赖属性

&#x1f4e6; WPF 自定义控件之依赖属性 在开发 WPF 应用时&#xff0c;自定义控件能帮助我们复用逻辑和样式&#xff0c;但我很快会遇到一个问题&#xff1a;在控件内部如何支持数据绑定和属性变更通知&#xff1f;特别是我们继承自 Control 的时候&#xff0c;已经不能再继承…

DOM型XSS破坏

目录 首先 然后 第一种 第二种&#xff08;DOM&#xff09; HTMLCollection HTML Relationships Custom 解 首先 <script>//urlencode解码 //location接口的hash属性是一个字符串&#xff0c;包含一个“#”后跟位置URL的片段标识符。如果URL没有片段标识符&#…