MyBatis:基础入门

MyBatis基础入门



一、MyBatis 简介

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 工作原理

MyBatis 基于 XML 配置文件生成 Configuration 和一个个 MappedStatement(包括了参数映射配置、动态 SQL 语句、结果映射配置)

MyBatis 架构图:

在这里插入图片描述

  • Mybatis 核心配置文件(如:sqlMapConfig.xml)在加载解析后,会生成 Configuration 对象,并由
    Configuration 对象得到 SqlSessionFactory,也就是 SqlSession 工厂;
  • 基于 SqlSessionFactory 可以生成 SqlSession 对象;
  • SqlSession 是应用程序和数据库之间交互的一个单线程对象(非线程安全的)不同用户的连接不是同一个,数据库的 C、R、U、D及事务的处理接口;
  • Executor 是 SqlSession 底层的对象,用于执行SQL语句;
  • MapperStatement 也是 SqlSession 底层的对象,用于接收输入映射(SQL语句中的参数),以及做输出映射(即将sql 查询的结果映射成相应的结果(HashMap、JavaBean 等));

SqlSession 对象完成和数据库的交互过程:

  1. 用户程序调用 Mybatis 接口层 api(即 Mapper 接口中的方法);
  2. SqlSession 通过调用 api 的 Statement ID 找到对应的 MappedStatement 对象;
  3. 通过 Executor 将 MappedStatement 对象进行解析、sql 参数转化、动态 sql 拼接,生成 jdbc Statement 对象;
  4. JDBC 执行 sql;
  5. 借助MappedStatement 中的结果映射关系,将返回结果转化成 HashMap、JavaBean 等存储结构并返回。

三、MyBatis 与 Hibernate 的对比

1. 原生 Jdbc 存在的问题

  1. 频繁创建、释放数据库连接造成系统资源浪费,影响系统性能。
    解决: 可以在 sqlMapConfig.xml 中配置数据连接池,使用连接池管理数据库连接。
  2. Sql 语句硬编码到 Java 代码中,不易维护,实际应用中 Sql 变化的可能较大,Sql 变动需要改变 Java代码。
    解决: Mybatis 将 Sql 语句配置在 XXXXmapper.xml 文件中与 Java 代码分离。
  3. 向 Sql 语句传参数麻烦,因为 Sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数一一对应(硬编码)。
    解决: Mybatis 自动将 Java 对象映射至 Sql 语句,通过 statement 中的 parameterType 定义输入参数的类型。
  4. 对结果集解析麻烦(查询列硬编码),Sql 变化会导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 Pojo对象解析比较方便。
    解决: Mybatis 自动将 Sql 执行结果映射至 Java 对象,通过 statement 中的 resultType定义输出结果的类型。

2. MyBatis 与 Hibernate 的对比

Hibernate 自动生成表,生成关系对于单表的 CRUD 不用写 Sql\Hql。mybtais 对于多表连接查询等等更加方便 因为 Sql 写起来简单:

  • MyBatis 半自动化模式操作数据,Hibernate 完全面向对象操作数据;
  • MyBatis 运行的性能高于 Hibernate 的性能,因为 Hql 要转化为 Sql,DB 才能识别;
  • MyBatis 的开发效率低于 Hibernate 的开发速度,写 Sql,写配置;
  • MyBatis 应用在互联网项目的开发,Hibernate 用在传统的 MIS 系统开发。

四、MyBatis demo

1. 引入 Maven 依赖

        <!--    Mysql数据库驱动    -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.27</version>
        </dependency>
        <!--    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.13.2</version>
        </dependency>

2. 创建mybatis-config.xml配置文件

<?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 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>
	
	<!-- 将我们写好的sql映射文件(EmployeeMapper.xml)一定要注册到全局配置文件(mybatis-config.xml)中 -->
	<mappers>
		<mapper resource="EmployeeMapper.xml" />
	</mappers>
</configuration>

3. 编写JavaBean类

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 + "]";
    }
    
}

4. Mapper层编写查询接口

public interface EmployeeMapper {
    
    
	
	public Employee getEmpById(Integer id);

}

5. Mapper层所对应 xml 中编写 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.lizhengi.demo.mybatis.bean.dao.mapper.EmployeeMapper">
    <!-- 
    namespace:名称空间;指定为接口的全类名
    id:唯一标识
    resultType:返回值类型
    #{
    
    id}:从传递过来的参数中取出id值
    public Employee getEmpById(Integer id);
     -->
    <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>

6. 编写测试类

/**
 * 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();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_47410172/article/details/127866866