Mybatis快速入门 一. Mybatis1. 含义MyBatis 是一款优秀的持久层框架用来简化JDBC开发。持久层负责和数据库交互完成数据持久化保存的一层代码。MyBatis是持久层框架封装JDBC把SQL写在XML文件实现Java对象和数据库记录映射简化数据库开发。2. 核心作用封装了JDBC不用手动写大量重复代码注册驱动、获取连接、创建PreparedStatement、关闭资源等。支持自定义SQL、存储过程、高级映射。把数据库查询结果自动封装成Java实体对象。3. 核心思想将SQL语句写在XML映射文件Mapper.xml或者注解中和Java代码分离。Java代码只需要调用方法SQL单独维护方便DBA优化SQL。4. 和JDBC对比JDBC硬编码SQL大量重复样板代码手动封装结果集。MyBatis封装JDBCSQL写在xml自动映射实体简化开发。5. 核心组件SqlSessionFactoryBuilder构建SqlSessionFactory一次性使用SqlSessionFactorySqlSession工厂单例用来生产SqlSessionSqlSession会话对象用来执行SQL获取Mapper代理用完关闭Mapper接口 Mapper.xml映射器定义方法和对应的SQL语句6. 快速入门导依赖定义实体类定义mybatis-config.xml文件,替换连接信息,解决硬编码加载核心配置文件,获取SqlSessionFactory对象直接用sqlSession还是有问题使用 Mapper 代理resultMap就是手动定义【数据库查询出来的结果集】和 Java 实体类的映射规则。解决数据库字段名 和 Java 实体类属性名不一致的映射问题5.执行6.获取结果 7. 释放资源工作流程 ()加载核心配置文件 → 创建 SqlSessionFactory → 打开 SqlSession → 获取 Mapper 代理对象 → 执行 SQL封装结果 → 关闭会话释放资源。二. MyBatis 条件查询条件查询根据传入参数带上where条件查询数据分为静态条件查询和动态条件查询项目最常用1.静态条件查询参数固定适合条件固定参数一定会传不会为空1. 单条件查询根据状态status查询BrandMapper 接口ListBrandselectByStatus(Integerstatus);BrandMapper.xmlselect idselectByStatusresultMapbrandResultMapselect*from tb_brand where status#{status}/select2. 多条件静态查询两个参数都不能为空接口,多参数时用Param(“参数占位符”)ListBrandselectByStatusAndName(Param(status)Integerstatus,Param(brandName)StringbrandName);xml文件select idselectByStatusAndName resultMapbrandResultMap select * from tb_brand where status #{status} and brand_name like concat(%,#{brandName},%) /select缺点一旦某个参数为 nullSQL 直接报错项目很少用2、动态条件查询【⭐重点】场景前端传参可选有值就加这个查询条件没有值就不拼接该 where 条件标签组合whereifBrandMapper.xmlselect idselectByConditionresultMapbrandResultMapselect*from tb_brandwhere!--testOGNL表达式判断属性是否有值不要写#{}--iftestbrandName ! null and brandName ! brand_name likeconcat(%,#{brandName},%)/ififteststatus ! nulland status#{status}/if/where/select where 标签两大核心能力自动生成where关键字自动删除第一个条件前面多余的 and/or防止 SQL 语法异常3. choose 单选条件查询多选一多个查询条件只能选其中一个匹配到第一个满足的就停止类似 switch-caseselect idselectChooseresultMapbrandResultMapselect*from tb_brandwherechoosewhen teststatus ! nullstatus#{status}/whenwhen testbrandName ! null and brandName ! brand_name likeconcat(%,#{brandName},%)/whenotherwise11/otherwise/choose/where/select4. 模糊查询写法条件查询高频坑✅ 推荐写法防 SQL 注入brand_name like concat(%,#{brandName},%)❌ 不推荐like %${brandName}%存在 SQL 注入风险5. 相关问题1. 静态多条件查询有什么缺点静态写死where后面and连接所有参数必须全部传入。如果某个参数传nullSQL语句条件失效查询结果错误项目一般不用只适合参数一定存在的简单场景。2. 动态条件查询 的原理和作用自动生成where关键字自动移除第一个条件前面多余的and/or避免SQL语法报错注意只会去除开头的and末尾多余and无法处理。3. 标签的test属性里面写什么能不能写#{ }test里面是OGNL表达式直接写实体类属性名不能写#{}。字符串类型brandName ! null and brandName ! 要同时判断null和空字符串数字类型status ! null只判断null即可不需要判断空串4. 模糊查询有几种写法推荐哪一种为什么✅推荐brand_name like concat(%,#{brandName},%)使用#{}预编译防止SQL注入。❌不推荐like %${brandName}%${}直接字符串拼接存在SQL注入漏洞。5. choose 、 when 、 otherwise 和多个 if 的区别多个if并行判断满足几个条件就拼接几个条件可以多个同时生效choose多选一从上往下匹配只要命中一个when就不再继续判断剩下条件类似switch-caseotherwise所有when都不满足时执行。6. 如果不用标签怎么手动实现动态条件可以手动写where 11(恒等式)然后所有条件前面加and。缺点写起来麻烦不推荐。select*from tb_brand where11iftestbrandName ! null and brandName ! and brand_name likeconcat(%,#{brandName},%)/if7. 条件查询传多个参数有哪几种方式封装实体类 POJO最常用多条件优先Param 注解给多个独立参数起名字Map 集合封装参数适合临时不确定字段场景。8. 什么场景下 resultType 不行要用 resultMap数据库字段名和 Java 实体属性名不一致下划线与驼峰并且没有开启全局驼峰自动转换 mapUnderscoreToCamelCase时查询出来属性值为 null需要 resultMap 手动指定映射。9. #{} 和 ${} 在条件查询里面区别#{}预编译占位符底层 PreparedStatement防止 SQL 注入会自动给字符串加引号用于值参数where 条件的值${}直接字符串拼接底层 Statement无预编译存在 SQL 注入风险不会自动加引号,一般仅用于动态表名、排序字段(很少)。10. 动态 SQL 什么时候会出现多余逗号 /and怎么解决where 后多余 and/or用where标签update 语句末尾多余逗号用set标签。11. parameterType、resultType、resultMapparameterType传入参数类型可以省略MyBatis 自动推断resultType简单类型 / 实体字段名和属性名一致直接映射resultMap字段名和实体属性名不一致时使用手动配置映射关系数据库brand_name实体brandName可以开启驼峰自动转换代替 resultMapsettingssetting namemapUnderscoreToCamelCasevaluetrue//settingsresultType 和 resultMap不能同时写12. Mapper 代理开发重点Mapper 代理开发规则Mapper 接口名 和 Mapper.xml 文件名相同Mapper 接口全限定名 xml 中namespace接口方法名 xml 中 statement 的 id方法返回值、参数类型 和 xml 中 resultType、parameterType 匹配优点不用写实现类MyBatis 动态生成代理对象。13. MyBatis 事务 ,SqlSession 默认自动提交关闭需要手动 commit ()增删改操作执行完成后必须sqlSession.commit()提交事务异常时rollback()回滚关闭 sessionsqlSession.close()释放连接数据库连接池就是复用 connection避免频繁创建销毁连接。14. MyBatis 一级缓存、二级缓存【高频】一级缓存默认开启范围同一个 SqlSession 会话内底层PerpetualCache失效场景增删改、手动 clearCache、关闭 session二级缓存需要手动开启范围同一个 Mapper跨 SqlSession开启mybatis-config 开启 cacheEnabledmapper.xml 添加cache/实体类需要实现Serializable序列化接口增删改会清空二级缓存一级缓存会话级别默认开启二级缓存 mapper 级别手动开启。15. Mapper 代理原理MyBatis 使用 JDK 动态代理生成 Mapper 接口代理对象调用接口方法时找到 xml 对应的 sql 执行。三. 修改动态sql(if判断) set 标签两个核心作用自动生成set关键字自动删除最后字段后面多余的逗号防止 SQL 语法报错对比左边静态 update静态是所有字段全部更新动态更新传了哪个字段就更新哪个没传的不更新动态 SQL 的作用根据传入参数动态拼接 SQL解决多条件组合查询避免写多条重复 SQL。四. MyBatis foreach 批量删除MyBatisforeach标签 批量删除1. 作用遍历数组/集合自动拼接in (值1,值2,值3)实现批量删除也可以用于批量新增、动态in查询。2. foreach 五大属性属性含义item每次循环得到的单个元素变量名在标签内部使用#{变量名}取值collection指定要遍历的数据源重点面试高频open循环开始拼接的字符串in场景写(close循环结束拼接的字符串in场景写)separator元素之间的分隔符in场景写,3. collection取值规则重中之重数组参数无ParamcollectionarrayIDEA插件会报红警告Cannot resolve symbol array属于插件提示运行不会报错List集合参数无Paramcollectionlist加Param(“xxx”)自定义命名推荐写法collectionxxx✅推荐消除IDEA报红可读性更强企业开发首选。4. 完整示例推荐Param版本Mapper接口IntegerdeleteByIds(Param(ids)Integer[]ids);Mapper.xmldelete iddeleteByIdsdelete from tb_brand where id inforeach itemidcollectionidsopen(separator,close)#{id}/foreach/delete最终拼接 SQLdelete from tb_brand where id in (1,2,3)5. 易错坑点❗IDEA 提示Cannot resolve symbol array只是插件静态检查警告不是运行异常加上Param即可解决。❗忘记提交事务delete 是 DML 修改语句SqlSession 必须 commit 提交否则数据库不会生效。❗in 里面 ID 数量不能无限多MySQL 对 SQL 语句长度有限制大批量数据不建议 in 批量删除。❗collection 名字写错和参数不匹配 → 运行直接抛出异常。❗不要手动写括号交给 open 和 close 自动拼接。6. 背诵foreach 用来遍历集合或数组动态拼接 SQLitem 是循环内单个元素collection 指定遍历对象open 开头字符串close 结尾字符串separator 元素分隔符项目开发推荐使用 Param 注解命名参数避免 IDEA 报红代码可读性更好。五. MyBatis 特征1.轻量级、持久层框架相比HibernateMyBatis体积小、依赖少不需要加载大量配置启动快。2.半自动ORM框架重点面试ORM对象关系映射Java对象 ↔ 数据库表。Hibernate全自动几乎不用写SQLMyBatis半自动自己写SQL语句框架负责映射结果到Java对象。3.SQL与代码分离SQL写在XML映射文件或注解和Java代码分开。好处方便DBA优化SQL修改SQL不用改Java代码便于维护。4.支持动态SQL可以根据参数动态拼接where、and、set、in等SQL片段if/where/set/choose/foreach标签解决拼接SQL麻烦的问题。5.结果映射灵活简单场景开启下划线转驼峰直接resultType自动映射复杂场景使用resultMap自定义映射支持一对一、一对多多表关联映射。6.支持多种参数传入方式基本类型、实体POJO、Map、Param命名参数。#{}预编译占位符防止SQL注入。7.缓存机制一级缓存、二级缓存一级缓存SqlSession级别默认开启同一次会话相同查询直接读缓存减少数据库访问。二级缓存Mapper级别需要手动开启多个SqlSession共享缓存。8.Mapper代理开发主流写法只需要写Mapper接口不用写接口实现类MyBatis自动生成代理对象执行SQL。9.良好兼容性支持绝大多数数据库可以和Spring、SpringBoot无缝整合。MyBatis是轻量级半自动ORM持久层框架SQL写在XML中和代码分离支持动态SQL、灵活的结果映射、参数绑定防SQL注入自带一级缓存默认开启和二级缓存支持Mapper代理开发可与Spring整合。易考点区分半自动ORMSQL需要程序员自己编写框架负责结果集封装到对象全自动ORM(Hibernate)框架自动生成SQL10.优缺点优点简化 JDBC减少大量重复代码SQL 写在 xml代码与 SQL 分离便于维护支持动态 SQL结果自动映射实体缺点SQL 需要手动编写工作量大SQL 依赖数据库移植性差一级缓存容易出现脏数据