1、MyBatis简介
1.1、MyBatis历史
MyBatis最初是Apache的一个开源项目iBatis, 2010年6月这个项目由Apache Software Foundation迁 移到了Google Code。随着开发团队转投Google Code旗下, iBatis3.x正式更名为MyBatis。代码于 2013年11月迁移到Github。
iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。 iBatis提供的持久层框架 包括SQL Maps和Data Access Objects(DAO)。
1.2、MyBatis特性
1) MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
2) MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
3) MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
4) MyBatis 是一个 半自动的ORM(Object Relation Mapping)框架
1.3、MyBatis下载
MyBatis下载地址:https://github.com/mybatis/mybatis-3
1.4、和其它持久化层技术对比
-
JDBC
-
SQL 夹杂在Java代码中耦合度高,导致硬编码内伤
-
维护不易且实际开发需求中 SQL 有变化,频繁修改的情况多见
-
代码冗长,开发效率低
-
Hibernate 和 JPA
-
操作简便,开发效率高
-
程序中的长难复杂 SQL 需要绕过框架
-
2、搭建MyBatis
2.1 环境配置和工程
所需要的maven依赖
<dependencies>
<!-- Mybatis核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- log4j日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
创建MyBatail的核心配置文件
习惯上命名为mybatis-config.xml,这个文件名仅仅只是建议,并非强制要求。将来整合Spring
之后,这个配置文件可以 省略,所以大家操作时可以直接复制、粘贴。
核心配置文件主要用于配置连接数据库的环境以及MyBatis的全局配置信息
核心配置文件存放的位置是src/main/resources目录下
2.2 创建mapper接口
MyBatis中的mapper接口相当于以前的dao。但是区别在于,mapper仅仅是接口,我们不需要提供实现类。
public interface UserMapper {
//增
int insertUser();
}
2.3 创建MyBatis的映射文件
对象关系映射的概念
相关概念:ORM(Object Relationship Mapping)对象关系映射。
对象:Java的实体类对象
关系:关系型数据库
映射:二者之间的对应关系
1、映射文件
表所对应的实体类的类名+Mapper.xml
例如:表t_user,映射的实体类为User,所对应的映射文件为UserMapper.xml
因此一个映射文件对应一个实体类,对应一张表的操作
MyBatis映射文件用于编写SQL,访问以及操作表中的数据
MyBatis映射文件存放的位置是src/main/resources/mappers目录下
2、 MyBatis中可以面向接口操作数据,要保证两个一致:
mapper接口和映射文件要保证两个一致:mapper接口的全类名和映射文件的namespace一致
mapper接口的方法的方法名要和映射文件中的SQL中的id保持一致。这样,每次调用接口,都会根据接口找到对应的映射文件, 然后根据调用接口的方法,定位到具体的SQL语句
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zylai.mybatis.mapper.UserMapper">
<!--int insertUser()-->
<insert id="insertUser">
insert into t_user values(null,'admin','123456',23,'男','123@qq.com')
</insert>
</mapper>
2.4 执行流程和原理
执行流程
@Test
public void testInsert() throws IOException {
//1.获取核心配置文件的输入流
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//2.获取SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//3.获取SqlSessionFactory对象,根据核心配置文件的输入流
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//4.获取sql的会话对象SqlSession,是MyBatis提供的操作数据库的对象
//7.调用有参的方法,设置自动提交事务。空参方法默认不自动提交
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//5.获取UserMapper的代理实现类对象,底层使用代理模式实现
//通过代理对象实现接口的方法,当调用接口的方法时,
// 其实执行了SqlSession的具体方法,然后其会根据接口的全类名及方法名
//定位到映射文件对应的SQL,如下面说的一样
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//6.调用mapper接口中的方法,实现添加用户信息的功能
int res = mapper.insertUser();
System.out.println("结果"+res);
//7.提交事务,使用空参的SqlSession,需要自己进行事务的控制
//sqlSession.commit();
//8.关闭会话
sqlSession.close();
}
原理
通过Mapper接口的代理对象其实是执行这个SQL的最终方法,其本质上就是代理对象实现了接口中的方法,会实际执行SqlSession的具体方法,比如:sqlSession.insert("com.atguigu.mybatis.mapper.UserMapper.insertUser");此类方法根据SQL的唯一标识找到SQL并执行,唯一标识是namespace.sqlId,**即mapper方法对应的全类名加上方法名。**因此,他会去获取当前方法的全类名和方法名作为参数传入上述方法中。
//注意:这里使用Mapper接口的代理对象其实是最终的一种方法,通过代理对象重写接口的方法
//本质上,就是调用了接口的方法,实现类中使用SqlSession的方法
// 提供sql的唯一标识找到SQL并执行,唯一标识是namespace.sqlId。
// 这里就不需要用到接口了,接口的名称和方法只是作为唯一id,完全可以换成其他的。
// int res1 = sqlSession.insert(“com.zylai.mybatis.mapper.UserMapper.insertUser”);
// System.out.println(“结果:”+res1);
/*
总结:
1.创建mapper接口的代理对象
2.代理对象重写了mapper接口中的方法
3.执行SqlSession的方法,参数是sql的唯一标识
4.返回结果
*/
因此如果不使用mapper接口的代理对象,采用如下的方式,其本质上是完全一样的
这里就不需要用到接口了,接口的名称和方法只是作为唯一id,完全可以换成其他的。