Mybatis基础知识 | 小册免费学

450 阅读5分钟

1.Mybatis概述

官方文档定义:

Mybatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。Mybatis免除了几乎所有的JDBC代码以及设置参数和获取结果的工作。Mybatis可以通过简单的XML或注解来配置和映射原始类型、接口和JAVA POJO(Plain Old Java Objects,普通老式Java对象)为数据库中的记录。

核心特性:

生命周期 配置 设计模式 mapper映射 注解 缓存 二次封装 扩展特性

学习Mybatis思路:一个核心特性/模块的基础回顾--->使用示例--->高级使用方法---->原理分析

2.Mybatis的整体架构

接口层:SqlSession是我们平时与Mybatis完成交互的核心接口(包括后续整合Spring后用到的SqlSessionTemplate) 核心层:SqlSession执行的方法,底层需要经过配置文件的解析、SQL解析,以及执行SQL时的参数映射、SQL执行、结果集映射,另外还有穿插其中的扩展插件; 支持层:支持核心层的功能实现,是基于底层的各个模块,共同协调完成的

Mybatis和Hibernate对比

对比指标 Mybatis Hibernate 类型 半自动,半ORM(允许用Map) 全自动ORM(只能使用实体类) 中心 SQL(一切Mapper里都是SQL) 对象关系(一切操作都围绕对象关系) SQL优化 容易(直接修改SQL即可) 困难(修改SQL后还需要转换为HQL,直接使用SQL则会破坏封装) 缓存机制 一般(管理不慎会出现脏数据) 完善(基于ORM的对象管理机制,出现脏数据会给出提示) 数据库的可移植性 不好(切换数据库,需要重写SQL) 好(可配置数据库类型,自动切换生成SQL) 日志打印体系 很有限(只能打印基本日志及交互) 完善(SQL记录、关系异常、优化警告、缓存提示、脏数据警告等) 开发效率、工作量 效率相对低、工作量多 效率相对高、工作量少 学习成本 较低(需要学习的内容相对少) 高(需要额外学习JPA、HQL、QBC、抓取策略等) 适用场景 比较容易出现复杂SQL的项目 复杂查询很少的项目

3.单表增删改查

基于原始Dao的开发方式: 问题是:DepartmentDaoImpl如何拿到SqlSession呢?借助SqlSessionFactory,它又从哪里来呢?而通常一个工程下只允许存在一个SqlSessionFactory,那怎么办呢?

构造方法注入,或setter方法注入

使用try-with-resource的方式,可以省略sqlSession.close()

try (SqlSession sqlSession = sqlSessionFactory.openSession()) { return sqlSession.selectOne("departmentMapper.findById", id); }

原始Dao开发弊端:

可以发现,存在这大量的重复代码,两个方法的方法名不同、参数列表不同、调用的mapper不同、返回值不同,其他的几乎完全相同!使用Mapper动态代理方式

基于Mapper动态代理的开发方式

使用Mapper动态代理的方式开发,需要满足一下几个规范: mapper.xml中的namespace与Mapper接口的全限定名完全相同 mapper.xml中定义的statement,其id与Mapper接口的方法名一致 Mapper接口方法的方法参数类型,与Mapepr.xml中定义的statement的parmeterType类型一致,返回值类型与resultType类型一致

4.关联表查询

一对一关联的查询:分为立即加载、延迟加载 立即加载:

1.定义实体类:

@Data public class User {

private String id;

private String name;

private Integer age;

private Date birthday;

private Department department;

}

2.定义映射resultMap

3.除了把主表的数据查出来映射之外还需要顺道查询一下关联对应的表,将其映射到实体类属性中。

select usr.*, dep.name as department_name from tbl_user usr left join tbl_department dep on usr.department_id = dep.id

注意点:

1.需要把Mapper添加到全局配置文件中 2.需要定义接口方法,且xml的命名空间与其一致3.resultMap需使用定义好一对一的map id

一对一延迟加载:

需修改resultMap ,给association标签添加select 和 column属性,分别指定触发延迟加载时调用的statement语句和执行statement传入的参数的列。 其次,再定义一个新的statement,应用上新定义的resultMap即可。

select * from tbl_user

public interface UserMapper {

List<User> findAll();

List<User> findAllLazy();

}

一对多映射

1.定义实体类

@Data public class Department implements Serializable {

private String id;

private String name;

private String tel;

private Set<User> users;

}

2.修改mapper.xml,定义resultMap,需要再查询主表时,把关联的信息同时查出

<resultMap id="department" type="com.linkedbear.mybatis.entity.Department">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <result property="tel" column="tel"/>
    <collection property="users" ofType="com.linkedbear.mybatis.entity.User"
                select="com.linkedbear.mybatis.mapper.UserMapper.findAllByDepartmentId" column="id"/>
</resultMap>

这里常用延迟加载:一对多的一方,一般查询不会用到关联的多的一方,只有用到多的一方才加载。 select * from tbl_user where department_id = #{departmentId}

3.写好查询语句,把resultMap替换成定义的一对多Map

<select id="findAll" resultMap="department">
    select * from tbl_department
</select>

<select id="findById" parameterType="string" resultMap="department">
    select * from tbl_department where id = #{id}
</select>

ORM:对象关系映射(Object Relational Mapping,简称ORM,或O/RM,或O/R mapping)

用于实现面向对象编程语言里不同类型系统的数据之间的转换

ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象与关系数据库相互映射 ORM可以解决数据库与程序间的异构性,比如:在Java中我们使用String表示字符串,而Oracle中可使用varchar2,MySQL中可使用varchar,SQLServer可使用nvarchar。

  • 它是一种将内存中的对象保存到关系型数据库中的技术
  • 主要负责实体域对象的持久化,封装数据库访问细节
  • 提供了实现持久化层的另一种模式,采用映射元数据(XML)来描述对象-关系的映射细节,使得ORM中间件能在任何一个Java应用的业务逻辑层和数据库之间充当桥梁。

本文正在参与「掘金小册免费学啦!」活动, 点击查看活动详情