本篇内容包括:MyBatis 简介、MyBatis 工作原理\执行流程、原生 Jdbc 存在的问题、MyBatis 与 Hibernate 的对比以及一个 MyBatis demo。
MyBatis 源起于 Apache 的开源项目 iBatis,2010年这个项目由 Apache Software Foundation 迁移到了 Google code,并且改名为 MyBatis 。2013 年 11 月迁移到 Github。
MyBatis中文文档:https://mybatis.net.cn/
GitHub:https://github.com/mybatis/mybatis-3
MyBatis 是一款优秀的持久层框架,MyBatis 是一个优秀的持久层框架,MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建Connection、创建 Statement、手动设置参数、结果集检索等 JDBC 繁杂的过程代码。
MyBatis 支持自定义 SQL、存储过程以及高级映射。它可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录,将要执行的各种 Statement(statement、preparedStatemnt)配置起来,并通过 Java 对象和 Statement 中的 sql 进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射回 Java POJO 返回。
MyBatis 基于 XML 配置文件生成 Configuration 和一个个 MappedStatement(包括了参数映射配置、动态 SQL 语句、结果映射配置)
MyBatis 架构图:
SqlSession 对象完成和数据库的交互过程:①、用户程序调用 Mybatis 接口层 api(即 Mapper 接口中的方法);②、SqlSession 通过调用 api 的 Statement ID 找到对应的 MappedStatement 对象;③、通过 Executor 将 MappedStatement 对象进行解析、sql 参数转化、动态 sql 拼接,生成 jdbc Statement 对象;④、JDBC 执行 sql;⑤、借助MappedStatement 中的结果映射关系,将返回结果转化成 HashMap、JavaBean 等存储结构并返回。
Hibernate 自动生成表,生成关系对于单表的 CRUD 不用写 Sql\Hql。mybtais 对于多表连接查询等等更加方便 因为 Sql 写起来简单:
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.27version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.7version>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.13.2version>
dependency>
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="root" />
dataSource>
environment>
environments>
<mappers>
<mapper resource="EmployeeMapper.xml" />
mappers>
configuration>
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
}
}
public interface EmployeeMapper {
public Employee getEmpById(Integer id);
}
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lizhengi.demo.mybatis.bean.dao.mapper.EmployeeMapper">
<select id="getEmpById" resultType="com.lizhengi.demo.mybatis.bean.Employee">
select id, last_name lastName, email, gender
from tbl_employee
where id = #{id}
select>
mapper>
/**
* 1、接口式编程
* 原生: Dao ====> DaoImpl
* mybatis: Mapper ====> xxMapper.xml
*
* 2、SqlSession代表和数据库的一次会话;用完必须关闭;
* 3、SqlSession和connection一样她都是非线程安全。每次使用都应该去获取新的对象。
* 4、mapper接口没有实现类,但是mybatis会为这个接口生成一个代理对象。
* (将接口和xml进行绑定)
* EmployeeMapper empMapper = sqlSession.getMapper(EmployeeMapper.class);
* 5、两个重要的配置文件:
* mybatis的全局配置文件:包含数据库连接池信息,事务管理器信息等...系统运行环境信息
* sql映射文件:保存了每一个sql语句的映射信息:
* 将sql抽取出来。
*/
public class MyBatisTest {
public SqlSessionFactory getSqlSessionFactory() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
return new SqlSessionFactoryBuilder().build(inputStream);
}
/**
* 1、根据xml配置文件(全局配置文件)创建一个SqlSessionFactory对象 有数据源一些运行环境信息
* 2、sql映射文件;配置了每一个sql,以及sql的封装规则等。
* 3、将sql映射文件注册在全局配置文件中
* 4、写代码:
* 1)、根据全局配置文件得到SqlSessionFactory;
* 2)、使用sqlSession工厂,获取到sqlSession对象使用他来执行增删改查
* 一个sqlSession就是代表和数据库的一次会话,用完关闭
* 3)、使用sql的唯一标志来告诉MyBatis执行哪个sql。sql都是保存在sql映射文件中的。
*/
@Test
public void test01() throws IOException {
// 1、获取sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
// 2、获取sqlSession对象
SqlSession openSession = sqlSessionFactory.openSession();
try {
// 3、获取接口的实现类对象
//会为接口自动的创建一个代理对象,代理对象去执行增删改查方法
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
Employee employee = mapper.getEmpById(1);
System.out.println(mapper.getClass());
System.out.println(employee);
} finally {
openSession.close();
}
}
}