MyBatis

Mybatis

MyBatis中文网

mybatis – MyBatis 3 | 简介

MyBatis最初是Apache的一个开源项目IBatis

2010年迁移到了Google Code,并且在iBatis3.x版本时正式更名为MyBatis,2013年迁移到Githubs

在Mybatis使用过程中,如果导包iBatis也属于正常现象


持久性框架对比

JDBC:

  • SQL夹杂在Java代码中,耦合度高,导致硬编码内伤
  • 维护不易且实际开发需求中SQL有变化,修改源码的情况多见
  • 代码冗长,开发效率低

Hibernate和JPA:

  • 操作简单,开发效率高
  • 程序中长难复杂的SQL需要绕过框架
  • 内部自动生成的SQL,不容易做特殊优化
  • 基于全映射的全自动框架,大量字段的POJO部分进行映射比较困难
  • 反射操作太多,导致数据库性能下降

MyBatis:

  • 轻量级,性能出色
  • SQL和Java编码分开,功能边界清晰(Java代码专注于业务,SQL语句服务于数据)
  • 开发效率稍逊色于Hibernate,但是能接受

开发效率: Hibernate > Mybatis > JDBC

运行效率:JDBC > Mybatis >Hibernate


Mapper接口&MapperXML文件

对比于之前学习的JDBC使用方式,MyBatis自带连接池,需要导入的依赖如下

  • mybatis:MyBatis使用的核心依赖
  • mysql:MySQL数据库的驱动依赖

在使用JDBC时,我们对数据库的操作是使用Dao和DaoImpl

在MyBatis中,对数据库操作使用Mapper和MapperXMl

其中,Mapper接口中不再有SQL语句,而是对数据库操作的功能方法,而MapperXML专门用来写SQL语句

在com.xiaobai下新建软件包名为mapper,用以存放Mapper接口

在resources下建立目录名为mappers,用以存放MapperXML文件


mybatis-config.xml

MyBatis不需要使用连接池,因为他自己内置了连接池

那么就需要为MyBatis配置一些参数(例如JDBC四大件)

以下代码是由尚硅谷提供的原生mybatis配置文件的写法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?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>

<!-- environments表示配置Mybatis的开发环境,可以配置多个环境,在众多具体环境中,使用default属性指定实际运行时使用的环境。default属性的取值是environment标签的id属性的值。 -->
<environments default="development">
<!-- environment表示配置Mybatis的一个具体的环境 -->
<environment id="development">
<!-- Mybatis的内置的事务管理器 -->
<transactionManager type="JDBC"/>
<!-- 配置数据源 -->
<dataSource type="POOLED">
<!-- 建立数据库连接的具体信息 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis-example"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>

<mappers>
<!-- Mapper注册:指定Mybatis映射文件的具体位置 -->
<!-- mapper标签:配置一个具体的Mapper映射文件 -->
<!-- resource属性:指定Mapper映射文件的实际存储位置,这里需要使用一个以类路径根目录为基准的相对路径 -->
<!-- 对Maven工程的目录结构来说,resources目录下的内容会直接放入类路径,所以这里我们可以以resources目录为基准 -->
<mapper resource="mappers/EmployeeMapper.xml"/>
</mappers>

</configuration>

MyBatis原生调用

在之前原生JDBC的学习中,我们最后通过Dao调用JDBC的的过程是:

DAO -> BaseDao -> JDBCUtil

其实使用起来也是比较麻烦,只是两个工具类为我们封装好了对象和方法而已

后来学习了JDBCTemplate,才简化了这两个类和对JDBC的操作

原生的MyBatis在调用起来也是一样的麻烦,但后面由SpringIoC接管后,这个过程就会被简化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class MybatisTest {
@Test
public void test() throws IOException {
// 使用流读取外部配置文件(mybatis-config.xml)
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");

// 创建sqlSessionFactory 这个对象是带有配置的模板,全局唯一
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

// 使用sqlSessionFactory创建sqlSession 每个业务创建一个sqlSession,相当一次会话,用完释放
SqlSession sqlSession = sqlSessionFactory.openSession();

// 获取接口的代理对象,这个接口没有具体的实现类,他代理的是Mapper接口的方法+mapperXMl中的sql语句
EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = mapper.queryById(1);
System.out.println("employee = " + employee);

// 提交事务(非DQL)和释放资源
sqlSession.close();
}
}

注:mybatis在配置中是针对非查询开启事务的,所以在执行非查询的时候要提交事务

事务管理器

在 MyBatis 中有两种类型的事务管理器
JDBC – 这个配置直接使用了 JDBC 的提交和回滚功能,它依赖从数据源获得的连接来管理事务作用域。默认情况下,为了与某些驱动程序兼容,它在关闭连接时启用自动提交。然而,对于某些驱动程序来说,启用自动提交不仅是不必要的,而且是一个代价高昂的操作。因此,从 3.5.10 版本开始,你可以通过将 “skipSetAutoCommitOnClose” 属性设置为 “true” 来跳过这个步骤。例如:

1
2
3
<transactionManager type="JDBC">
<property name="skipSetAutoCommitOnClose" value="true"/>
</transactionManager>

iBatis

与MyBatis不同,iBatis没有Mapper接口

在调用iBatis时,不使用代理模式,sqlSession对象提供了增删改查方法,由此对象直接调用标签中的sql语句完成增删改查

sqlSession在调用增删改查的方法时,将mapper标签的namespace + crud标签的id值作为参数传递进去

缺点:

  • 传入的标签定位参数是一个字符串,没有报错提示,容易写错
  • sql的参数需要整合,每次只能传递一个参数
  • 返回值类型为Object,需要强制转型

执行逻辑

iBatis将MapperXML文件中的sql语句,存成类似键值对的形式

键:mapper标签的namespace + crud标签的id值 ,值:sql语句

mybatis-config.xml,配置好四大件之后将数据库信息缓存,同时将mapper.xml的sql语句(键值对缓存起来)

调用iBatis时,通过配置文件读取到四大件和sql,创建SqlSession工厂,创建SqlSession

调用SqlSession的增删改查时,就是在缓存中通过key找到value,带入对sql的参数并执行


MyBatis执行逻辑

Mybatis.png

为了解决iBatis存在的问题,多建立一个对应mapper.xml的接口

Mapper接口中的全限定类名对应mapper标签的namespace属性值

Mapper接口中的方法名对应crud标签的id值

这样,全限定类名+方法名的格式,也能找到具体的sql语句


代理技术

通过SqlSession对象调用getMapper,将接口的类对象作为参数传入

底层使用JDK动态代理,为此接口生成一个代理对象,利用反射的机制获取到接口的全类名和要执行的方法名

这个全类名和方法名拼成字符串(这也是IBatis时调用具体方法的所需参数),再去调用iBatis对应的方法

使用代理模式对接口内容进行丰富,将mapper.xml的sql内容填入其中,形成一个对象

使用对象调用接口的方法,我们发现参数类型和返回值类型早已规定好


Mybatis日志输出

mybatis – MyBatis 3 | 配置

MyBatis的中文官网为我们提供了非常完善的使用说明,其中就包括了MyBatis的配置文件(mybatis-config.xml)的标签含义

其中,settings标签可以配置 MyBatis 的运行时行为,是个极为重要的标签

1
2
3
4
5
6
7
<configuration>
<settings>
<!-- 开启MyBaits日志输出 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
……
</configuration>

在之后的学习中,我们会学习更多的settings的配置参数,让MyBatis使用起来更简单



MyBatis
http://blog.170827.xyz/2024/06/03/MyBatis/
作者
XIAOBAI
发布于
2024年6月3日
许可协议