面试题009-Java-MyBatis

时间:2024-07-11 20:48:39

面试题009-Java-MyBatis

目录

  • 面试题009-Java-MyBatis
    • 题目自测
    • 题目答案
      • 1. 什么是MyBatis?它与Hibernate有什么区别?
      • 2. 说一下MyBatis的执行流程?
      • 3. MyBatis是否支持延迟加载?
      • 4. MyBatis中一级缓存和二级缓存的区别?
      • 5. MyBatis中的动态SQL是什么?
      • 6. 如何在MyBatis中实现分页?
      • 7. MyBatis如何实现大规模数据插入MySQL数据库中?
      • 8. MyBatis-Plus了解吗?

题目自测

  • 1. 什么是MyBatis?它与Hibernate有什么区别?
  • 2. 说一下MyBatis的执行流程?
  • 3. MyBatis是否支持延迟加载?
  • 4. MyBatis中一级缓存和二级缓存的区别?
  • 5. MyBatis中的动态SQL是什么?
  • 6. 如何在MyBatis中实现分页?
  • 7. MyBatis如何实现大规模数据插入MySQL数据库中?
  • 8. MyBatis-Plus了解吗?

题目答案

1. 什么是MyBatis?它与Hibernate有什么区别?

答:MyBatis是一个半自动化的持久层框架,它可以通过XML或注解来编写SQL语句,并将SQL语句与Java对象进行映射。MyBatis不完全自动生成SQL语句,而是让开发人员手动编写SQL,从而提供了更大的灵活性和控制权。
Hibernate是一个全自动的ORM框架,它可以自动生成SQL语句,提供了更多的功能,但是它的配置也相对比较复杂。

2. 说一下MyBatis的执行流程?

答:MyBatis的执行流程包括几个主要步骤,从配置初始化到执行SQL并返回结果。详细流程如下

  1. 加载配置文件:记载配置文件(如mybatis-config.xml),里面包含数据库连接信息、映射文件位置等信息。
  2. 创建SqlSessionFactory:通过SqlSessionFactoryBuilder构造器创建SqlSessionFactory实例。
  3. 创建SqlSession:通过SqlSessionFactory获取SqlSession实例,里面提供了执行SQL语句所需的方法。
  4. 获取Mapper:通过SqlSession获取具体的Mapper实例。
  5. 执行SQL:调用Mapper接口方法,MyBatis根据配置文件中的映射信息生成并执行具体的SQL语句。
  6. 处理结果集:MyBatis将数据库返回的结果集映射为Java对象,并返回给调用者。
  7. 事务管理:如果配置了事务管理器,SqlSession会处理事务的开始、提交或回滚。
  8. 关闭SqlSession:释放资源。
    // 1. 加载配置文件
    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    
    // 2. 创建SqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
    // 3. 创建SqlSession
    try (SqlSession session = sqlSessionFactory.openSession()) {
        
        // 4. 获取Mapper
        UserMapper mapper = session.getMapper(UserMapper.class);
    
        // 5. 执行SQL
        User user = mapper.selectUser(1);
    
        // 6. 处理结果集
        System.out.println(user);
    
        // 7. 管理事务(如果需要)
        session.commit();
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        // 8. 关闭SqlSession
        session.close();
    }
    

3. MyBatis是否支持延迟加载?

答:MyBatis支持延迟加载。延迟加载是一种优化技术,只有当真正需要数据时才从数据库加载。在MyBatis中,延迟加载主要用于关联对象或集合对象。当需使用关联数据时,MyBatis才执行相应的SQL语句。
MyBatis中延迟加载可以通过全局配置或具体的映射文件进行配置。

4. MyBatis中一级缓存和二级缓存的区别?

答:MyBatis中的缓存机制分为一级缓存和二级缓存,都是用于提高数据库的查询性能。

  • 一级缓存:是SqlSession级别的缓存,作用范围是当前的SqlSession,默认是开启的。

    try (SqlSession session = sqlSessionFactory.openSession()) {
        UserMapper mapper = session.getMapper(UserMapper.class);
    
        // 第一次查询,从数据库中查询并缓存结果
        User user1 = mapper.selectUser(1);
        System.out.println(user1);
    
        // 第二次查询,相同的SqlSession,相同的查询和参数,从缓存中取值
        User user2 = mapper.selectUser(1);
        System.out.println(user2);
    }
    
  • 二级缓存:是Mapper级别或全局级别的缓存,作用范围是整个应用程序,多个SqlSession可以共享,需要手动配置开启。

    // 第一次查询
    try (SqlSession session1 = sqlSessionFactory.openSession()) {
        UserMapper mapper = session1.getMapper(UserMapper.class);
        User user1 = mapper.selectUser(1);
        System.out.println(user1);
    }
    
    // 第二次查询,不同的SqlSession,但二级缓存启用,从缓存中取值
    try (SqlSession session2 = sqlSessionFactory.openSession()) {
        UserMapper mapper = session2.getMapper(UserMapper.class);
        User user2 = mapper.selectUser(1);
        System.out.println(user2);
    }
    

5. MyBatis中的动态SQL是什么?

答:MyBatis中的动态SQL是一种根据运行时条件生成SQL语句的机制。它使得SQL语句更加灵活和动态,能够适应不同的查询条件和需求。MyBatis通过提供一组标签和表达式,允许开发人员在XML映射文件中编写动态SQL。- -

  • :用于条件判断,根据条件决定是否包含某段SQL。
  • 、、 :类似于Java中的switch-case语句,选择性包含SQL片段。
  • 、、 :用于处理SQL片段中的多余部分(如逗号、AND/OR等)。
  • :用于迭代集合生成SQL片段。
  • :绑定表达式结果到变量。

6. 如何在MyBatis中实现分页?

答:在MyBatis中,有多种方式可以实现分页。1. 可以直接通过编写分页SQL语句。 2. 使用RowBounds对象进行分页。 3. 使用分页插件 PageHelper 实现分页。

  • 使用SQL语句分页

    <select id="selectUsers" resultType="User">
        SELECT * FROM users
        LIMIT #{offset}, #{limit}
    </select>
    
  • 使用RowBounds对象分页

    RowBounds rowBounds = new RowBounds(offset, limit);
    List<MyEntity> entities = sqlSession.selectList("mySelectStatement", parameter, rowBounds);
    
  • 使用分页插件PageHelper

    PageHelper.startPage(pageNum, pageSize);
    List<MyEntity> entities = sqlSession.selectList("mySelectStatement", parameter);
    

7. MyBatis如何实现大规模数据插入MySQL数据库中?

答:将大规模数据插入到MySQL有多种实现方式,如使用MyBatis的批量插入,原生JDBC,MyBatis-Plus插件等方式。在疲劳插入时,需要对数据进行分批处理,控制事务的使用 来提高插入性能和安全。

  • MyBatis批量插入:
    <mapper namespace="com.example.mapper.UserMapper">
        <insert id="insertUsers">
            INSERT INTO users (username, email)
            VALUES
            <foreach collection="users" item="user" separator=",">
                (#{user.username}, #{user.email})
            </foreach>
        </insert>
    </mapper>
    
    public class BatchInsertExample {
    
        public static void main(String[] args) {
            String resource = "mybatis-config.xml";
            InputStream inputStream = BatchInsertExample.class.getClassLoader().getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
            List<User> users = new ArrayList<>();
            for (int i = 0; i < 1000000; i++) {
                users.add(new User("username" + i, "email" + i));
            }
    
            int batchSize = 1000;
            try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
                UserMapper mapper = session.getMapper(UserMapper.class);
                for (int i = 0; i < users.size(); i += batchSize) {
                    List<User> batchList = users.subList(i, Math.min(i + batchSize, users.size()));
                    mapper.insertUsers(batchList);
                    session.commit();
                    session.clearCache();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

8. MyBatis-Plus了解吗?

答:MyBatis-Plus是MyBatis的一个增强工具,在MyBatis的基础上提供了许多额外的功能和特性,使得开发者可以更加方便快捷地操作数据库。

MyBatis-Plus官方:

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可*配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

参考资料

  • JavaGuide
  • 牛客网-Java面试宝典
  • ChatGPT
  • MyBatis官方文档
  • MyBatis-Plus官方文档