【精选】框架初探篇之——MyBatis入门必知【面试常问】

什么是MyBatis?

在这里插入图片描述

MyBatis是一个半自动的ORM框架,其本质是对JDBC的封装。使用MyBatis不需要写JDBC代码,但需要程序员编写SQL语句。之前是apache的一个开源项目iBatis,2010年改名为MyBatis。

补充:

Hibernate也是一款持久层ORM框架,多年前的市场占有率很高,但近年来市场占有率越来越低。

MyBatis与Hibernate的比较:

  • MyBatis是一个半自动的ORM框架,需要手写SQL语句。
  • Hibernate是一个全自动的ORM框架,不需要手写SQL语句。
  • 使用MyBatis的开发量要大于Hibernate。

为什么Hibernate市场占有率越来越低:

  • 对于新手学习Hibernate时间成本比MyBatis大很多,MyBatis上手很快。
  • Hibernate不需要写SQL语句是因为框架来生成SQL语句。对于复杂查询,开发者很难控制生成的SQL语句,这就导致SQL调优很难进行。
  • 之前的项目功能简单,数据量小,所以使用Hibernate可以快速完成开发。而近年来项目的数据量越来越大,而互联网项目对查询速度要求也很高,这就要求我们一定要精细化的调整SQL语句。此时灵活性更强,手动编写SQL语句的MyBatis慢慢代替了Hibernate使用。
  • 在高并发、大数据、高性能、高响应的互联网项目中,MyBatis是首选的持久框架。而对于对性能要求不高的比如内部管理系统等可以使用Hibernate。

MyBatis入门

环境搭建

  1. 将SQL文件导入数据库

  2. 创建maven工程,引入依赖

    <dependencies>
      <!--  mybatis  -->
      <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
      </dependency>
      <!--  mysql驱动包  -->
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
      </dependency>
    
    
      <!--  junit  -->
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
      </dependency>
      <!--  log4j  -->
      <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
      </dependency>
    </dependencies>
    
    
  3. 创建mybatis核心配置文件SqlMapConfig.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="mysql">
        <environment id="mysql">
          <!--  事务类型  -->
          <transactionManager type="JDBC"></transactionManager>
          <!--  数据源  -->
          <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql:///mybatis"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
          </dataSource>
        </environment>
      </environments>
    </configuration>
    
    
  4. 将log4j.properties文件放入resources中,让控制台打印SQL语句。

  5. 创建实体类

    public class User {
      private int id;
      private String username;
      private String sex;
      private String address;
        // 省略getter/setter/构造方法/toString方法
    }
    
    

创建持久层接口和映射文件

  1. 在java目录创建持久层接口

    public interface UserMapper {
      List<User> findAll();
    }
    
    
  2. 在resource目录创建映射文件

    <?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.java.mapper.UserMapper">
      <select id="findAll" resultType="com.java.pojo.User">
         select * from user
      </select>
    </mapper>
    
    
  3. 将映射文件配置到mybatis核心配置文件中

    <!--  注册映射文件  -->
    <mappers>
      <mapper resource="com/java/mapper/UserMapper.xml">     </mapper>
    </mappers>
    
    

映射文件注意事项:

  • 映射文件要和接口名称相同。

  • 映射文件要和接口的目录结构相同。

  • 映射文件中namespace属性要写接口的全名。

  • 映射文件中标签的id属性是接口方法的方法名。

  • 映射文件中标签的resultType属性是接口方法的返回值类型。

  • 映射文件中标签的parameterType属性是接口方法的参数类型。

  • 映射文件中resultTypeparameterType属性要写全类名,如果是集合类型,则写其泛型的全类名。

测试持久层接口方法

@Test
public void testFindAll() throws Exception {
  // (1)读取核心配置文件
  InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
  // (2)创建SqlSessionFactoryBuilder对象
  SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  // (3)SqlSessionFactoryBuilder对象获取SqlSessionFactory对象
  SqlSessionFactory factory = builder.build(is);
  // (4)SqlSessionFactory对象获取SqlSession对象
  SqlSession session = factory.openSession();
  // (5)SqlSession对象获取代理对象
  UserMapper userMapper = session.getMapper(UserMapper.class);
  // (6)代理对象执行方法
  List<User> all = userMapper.findAll();
  all.forEach(System.out::println);


  // (7)释放资源
  session.close();
  is.close();
}

MyBatis核心对象及工作流程

在这里插入图片描述

MyBatis核心对象

  • SqlSessionFactoryBuilder

    SqlSession 工厂构建者对象,使用构造者模式创建SqlSession工厂对象。

  • SqlSessionFactory

    SqlSession工厂,使用工厂模式创建SqlSession对象。

  • SqlSession

    该对象可以操作数据库,也可以使用动态代理模式创建持久层接口的代理对象操作数据库。

  • Mapper

    持久层接口的代理对象,他具体实现了持久层接口,用来操作数据库。

MyBatis工作流程

  1. 创建SqlSessionFactoryBuilder对象
  2. SqlSessionFactoryBuilder对象构建了SqlSessionFactory对象:构造者模式
  3. SqlSessionFactory对象生产了SqlSession对象:工厂模式
  4. SqlSession对象创建了持久层接口的代理对象:动态代理模式
  5. 代理对象操作数据库

使用SqlSession操作数据库

除了代理对象能够操作数据库,SqlSession也能操作数据库。只是这种方式在开发中使用的较少,接下来我们使用SqlSession操作数据库:

@Test
public void testFindAll2() throws Exception {
  // (1)读取核心配置文件
  InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
  // (2)创建SqlSessionFactoryBuilder对象
  SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  // (3)SqlSessionFactoryBuilder对象获取SqlSessionFactory对象
  SqlSessionFactory factory = builder.build(is);
  // (4)SqlSessionFactory对象获取SqlSession对象
  SqlSession session = factory.openSession();
  // (5)SqlSession直接操作数据库
  List<User> users = session.selectList("com.java.mapper.UserMapper.findAll");
  users.forEach(System.out::println);
  // (6)关闭资源
  session.close();
  is.close();
}

Mapper动态代理原理

Mapper动态代理:

  • SqlSession的getMapper方法,最终是调用的是JDK动态代理方法,生成一个代理对象,类型就是传入的接口类型。
  • MapperProxy对象通过调用MapperMethod的execute方法定义了代理方式,该方法的底层调用的是SqlSession的方法。
posted @ 2023-11-24 08:32  Gjq-  阅读(2)  评论(0编辑  收藏  举报  来源