背景
- 前身是iBatis,一种半自动的ORM框架
- 传统JDBC编程的弊端
- 工作量大,操作数据库至少需要5步
- 业务代码和技术代码耦合
- 连接资源手动关闭,存在隐患
- Mybatis映射文件三要素
- SQL语句
- 映射规则
- POJO(Plain Ordinary Java Object)
- 只需自己提供SQL语句
- 建立连接,Statement, JDBC相关异常处理等由Mybatis完成
- 可替代Hibernate
架构
使用
- 创建项目,导包
- 创建实体类
- 配置文件mybatis-config.xml
- 提供连接数据库用的驱动,数据库名称,编码方式,账号密码
- 配置文件Category.xml
- 在com.how2java.pojo下创建
- 测试类TestMybatis
配置文件
- 核心配置文件:mybatis-config.xml
- settings:设置运行选项
- mapUnderscoreToCamelCase:开启自动驼峰命名规则
- cacheEnable:全局缓存开关
- lazyLoadingEnabled:延迟加载全局开关
- aggressiveLazyLoading:属性是否按需加载
- typeAllases:类型别名,首字母不区分大小写
- plugin:拦截器,拦截方法调用
- mapper:映射器,配置Spring扫描包
- environments:配置多个环境,如开发、测试、生产(实际多用Spring管理)
- settings:设置运行选项
- SQL映射文件:mapper.xml
- mapper:根节点
- cache:配置给定命名空间的缓存
- resultMap:描述数据库结果集和对象的对应关系
- sql:可重用的SQL块
- insert:映射插入语句
- update:映射更新语句
- delete:映射删除语句
- select:映射查询语句
- parameterType:查询语句传入参数的类型的完全限定名或别名
- resultType:查询语句返回结果类型的完全限定名或别名
传参
- #{}:占位符,用于参数传递,自动实现类型转换,可防止SQL注入
- ${}:获取参数值,直接拼接到sql,不做类型转换,需自行判断类型,不能防止SQL注入
- 使用默认参数名获取参数值
- 在@Param注解指定参数名
- 分表存储时用
原理
- 应用程序找Mybatis要数据
- mybatis从数据库中找来数据
- 通过mybatis-config.xml 定位哪个数据库
- 通过mapper.xml执行对应的select语句
- 基于mapper.xml把返回的数据库记录封装在对象中
- 把多个对象装在一个集合中
- 返回一个集合
相关概念
- 日志
- 知道mybatis执行了什么SQL语句,以便进行调试
- 使用log4j
- 事务管理
- 延迟加载
- 分页
- 导入PageHelper插件jar包
- 在mybatis-config.xml中添加代码,开启PageHelper插件
- 去掉mybatis-config.xml原有分页操作设置
- 一级缓存
- Mybatis的一级缓存在session上
- 下一次再查询相同id的数据,都直接冲缓存中取出来
- 二级缓存
- Mybatis二级缓存是SessionFactory
- 连接池
- 整合C3P0数据库连接池
- 逆向工程
- Mybatis Generator是一个用于Mybatis逆向工程的工具
- 传统流程:先有pojo, mapper, xml, 然后再创建表
- 逆向工程:首先保证数据库里有表,然后通过Mybatis Generator生成pojo, mapper和xml
设计模式
- 外观模式(门面模式)
- 适配器模式
- 代理模式
- 工厂模式
- 装饰器模式
JDBC问题
- 加载驱动:驱动包硬编码到java代码中,更换数据库需要修改源码(写在配置文件中)
- 创建数据库连接:写法固定(写在配置文件中)
- 创建Statement:修改sql必须修改源码(将sql写在配置文件中)
- 设置参数,执行sql:能否写在配置文件中(自动判断类型和位置)
- 遍历结果集:需要判断类型,手动指定字段名(能否将结果自动映射为java对象)
- 释放资源:频繁创建和关闭连接,影响系统性能(使用连接池)
核心流程
- mybatis-config.xml:配置全局参数,只有一个
- mapper.xml:配置多个statement,即sql,可有多个
- 通过mybatis配置文件得到SqlSessionFactory
- 通过SqlSessionFactory得到SqlSession
- 通过Executor执行SqlSession(基本实现 / 带缓存功能的实现)
- 输入、输出参数
- HashMap:k-v格式数据类型
- Java基本数据类型
- POJO:java对象
动态代理
- 使用mapper接口,不用写实现类即可完成数据库操作
- Mapper的namespace必须和mapper接口的全路径一致
- Mapper接口的方法名必须和sql定义的id一致
- Mapper接口方法的输入参数类型必须和sql定义的parameterType一致
- Mapper接口中方法的输出参数类型必须和sql定义的resultType一致
高级特性
- ResultMap
- 如何从数据库结果集中加载对象
- 解决问题:POJO属性名和表结构字段不一致,高级查询
- 动态SQL
- 缓存
- 分页
- 高级查询
源码学习
- 精心挑选项目
- 先看文档
- 下载源码,保证能编译运行
- 摸骨架,从宏观到微观
- 顺流程,找到入口,抓主放次
- 源码调试,找到核心数据结构和关键类
- 勤练习,多折腾
参考
Mybatis 和 JPA
https://www.jianshu.com/p/32ce87c163d6
https://baijiahao.baidu.com/s?id=1654809256030559190&wfr=spider&for=pc