Java经典面试题汇总:Mybatis

Java经典面试题汇总:Mybatis

MyBatis是Java中一款非常流行的持久层框架,是Apache下的一个开源项目,它提供了使用Java对象来映射数据库操作的ORM框架,封装了原始的JDBC访问,让使用者能够更加方便的使用数据库。本篇文章将介绍MyBatis常见的面试题及其详细解析。

1. MyBatis的使用及原理

1.1 MyBatis的使用

  1. 首先在项目中引入MyBatis相关的依赖:
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>
  1. 在MyBatis的配置文件中配置数据源:
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/StudentMapper.xml"/>
    </mappers>
</configuration>
  1. 创建Mapper映射文件,例如StudentMapper.xml:
<mapper namespace="com.example.mapper.StudentMapper">
    <select id="findById" parameterType="int" resultType="com.example.pojo.Student">
        select * from student where id = #{id}
    </select>
</mapper>
  1. 创建Mapper接口,例如StudentMapper.java:
public interface StudentMapper {
    Student findById(int id);
}
  1. 在SpringBoot主类中添加Mapper扫描注解:
@SpringBootApplication
@MapperScan("com.example.mapper")
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  1. 在Service层中注入Mapper并调用方法:
@Service
public class StudentService {

    @Autowired
    private StudentMapper studentMapper;

    public Student findById(int id) {
        return studentMapper.findById(id);
    }
}

1.2 MyBatis的原理

MyBatis框架主要由以下几部分组成:SqlSessionFactory、SqlSession、Executor、StatementHandler、ParameterHandler、ResultSetHandler、MappedStatement和Configuration。

  • SqlSessionFactory:SqlSessionFactory是MyBatis的核心接口,用于创建SqlSession对象;
  • SqlSession:SqlSession是执行持久化操作的核心接口,它提供了很多方法,例如查询、新增、修改和删除操作;
  • Executor:Executor是MyBatis引擎中最核心的对象,提供了事务管理和执行SQL语句的功能;
  • StatementHandler:StatementHandler是执行SQL语句的核心对象,提供了操作SQL语句的各种方法;
  • ParameterHandler:ParameterHandler是处理SQL参数的核心对象,提供了操作SQL参数的各种方法;
  • ResultSetHandler:ResultSetHandler是处理结果集的核心对象,提供了操作结果集的各种方法;
  • MappedStatement:MappedStatement是执行SQL语句的映射对象,提供了SQL语句、输入参数和输出结果的各种信息;
  • Configuration:Configuration是MyBatis配置信息对象,提供了MyBatis配置信息的各种设置。

2. MyBatis的优化

2.1 使用缓存

MyBatis中的缓存分为一级缓存和二级缓存。一级缓存是SqlSession级别的缓存,查询结果会自动缓存到SqlSession中;二级缓存是Mapper级别的缓存,查询结果会缓存到二级缓存中,多个SqlSession共享这个缓存。使用缓存能够提高查询效率。

一级缓存示例:

public class StudentMapperTest {

    private SqlSession sqlSession;

    @Before
    public void before() throws Exception {
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder()
                .build(Resources.getResourceAsStream("mybatis-config.xml"));
        sqlSession = sessionFactory.openSession();
    }

    @Test
    public void testFindById() throws Exception {
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        Student student1 = studentMapper.findById(1);
        Student student2 = studentMapper.findById(1);
        System.out.println(student1 == student2); // true
    }
}

二级缓存示例:

<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>

2.2 关闭日志

MyBatis框架默认会输出sql语句和参数,可以通过配置关闭日志来提高查询效率:

<configuration>
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
</configuration>

2.3 使用连接池

MyBatis框架默认使用的是简单的JDBC连接池,可以通过使用第三方的连接池来提高效率,例如:Druid连接池、HikariCP连接池。

3. MyBatis的动态SQL

MyBatis的动态SQL是指在执行SQL语句时,可以根据条件进行判断,生成不同的SQL语句,从而实现动态的SQL查询。

3.1 if标签

if标签可以根据条件来判断是否生成SQL语句:

<select id="findByName" resultType="com.example.pojo.Student">
    select * from student where 1=1
    <if test="name != null">
        and name = #{name, jdbcType=VARCHAR}
    </if>
    <if test="sex != null">
        and sex = #{sex, jdbcType=VARCHAR}
    </if>
</select>

3.2 choose标签

choose标签可以根据条件判断生成不同的SQL语句:

<select id="findByCondition" parameterType="com.example.pojo.Student"
        resultType="com.example.pojo.Student">
    select * from student
    <where>
        <choose>
            <when test="name != null">
                and name = #{name, jdbcType=VARCHAR}
            </when>
            <when test="sex != null">
                and sex = #{sex, jdbcType=VARCHAR}
            </when>
            <otherwise>
                and 1=1
            </otherwise>
        </choose>
    </where>
</select>

3.3 foreach标签

foreach标签可以遍历集合生成多个SQL语句:

<delete id="deleteByIds" parameterType="java.util.List">
    delete from student
    where id in
    <foreach collection="list" item="id" open="(" separator="," close=")">
        #{id}
    </foreach>
</delete>

4. MyBatis的乐观锁

MyBatis的乐观锁指通过版本号的方式来实现数据库的同步更新,具有防止高并发多次操作的特点。

4.1 乐观锁的使用

在实体类中添加版本号字段:

public class Student {
    private int id;
    private String name;
    private String sex;
    private int version;
    //getter和setter方法
}

在Mapper映射文件中添加更新方法:

<update id="updateNameByVersion" parameterType="com.example.pojo.Student">
    update student set name = #{name, jdbcType=VARCHAR},
    version = #{version} + 1
    where id = #{id} and version = #{version}
</update>

在Service层中调用更新方法:

@Service
public class StudentService {

    @Autowired
    private StudentMapper studentMapper;

    public boolean updateName(int id, String name) {
        Student student = studentMapper.findById(id);
        student.setName(name);
        return studentMapper.updateNameByVersion(student) > 0;
    }
}

4.2 乐观锁的实现原理

MyBatis的乐观锁通过在执行更新操作时,自动判定版本号是否匹配,如果不匹配则自动回滚整个事务,从而达到同步更新数据的目的。MyBatis乐观锁的实现,是通过在更新数据库表时,在where子句中添加版本号验证的SQL语句来实现的。当多个线程同时更新一行数据时,只有其中一个线程能够成功更新,其他线程则会出现版本号不匹配的情况,导致更新失败,从而实现同步更新数据的目的。

总结

本文从MyBatis的使用、原理、优化、动态SQL和乐观锁几个方面,讲解了MyBatis常见的面试题。MyBatis是Java中非常流行的持久层框架,通过本文中的学习,相信大家对MyBatis的使用和原理都有了更深入的了解。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java经典面试题汇总:Mybatis - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • java编写创建数据库和表的程序

    下面是详细讲解 java 编写创建数据库和表的程序的完整攻略: 创建数据库 步骤一 在使用 Java 连接数据库之前,需要引入 JDBC (Java Database Connectivity)驱动,这可以通过在 Maven POM 文件中添加以下依赖来完成。这里以 mysql-connector-java 为例: <dependency> &l…

    Java 2023年5月19日
    00
  • 在Java的Struts中判断是否调用AJAX及用拦截器对其优化

    在Java的Struts中,可以通过拦截器对AJAX请求进行优化,以提高系统的性能和用户体验。以下是具体的步骤: 1.在struts.xml配置文件中定义拦截器 <interceptors> <interceptor name="ajaxInterceptor" class="com.example.AjaxI…

    Java 2023年5月20日
    00
  • spring框架集成flyway项目的详细过程

    下面是“spring框架集成flyway项目的详细过程”的完整攻略。 一、什么是flyway? Flyway是一个开源的数据库迁移工具,可以帮助我们管理数据库版本的升级和降级。Flyway使用简单,不需要依赖任何第三方库,支持多种数据库,包括MySQL、Oracle、PostgreSQL等。 二、在spring框架中集成flyway 1. 添加依赖 在pom…

    Java 2023年5月19日
    00
  • 深入了解Java SpringBoot自动装配原理

    Java Spring Boot是一个非常流行的开发框架,它可以帮助开发者快速构建Web应用程序。其中一个重要的特性是自动装配,它可以帮助开发者自动配置应用程序的依赖项,从而简化应用程序的开发和部署。以下是深入了解Java Spring Boot自动装配原理的完整攻略: 自动装配原理 Java Spring Boot的自动装配原理基于Spring框架的依赖注…

    Java 2023年5月15日
    00
  • 详解SpringMVC加载配置Properties文件的几种方式

    当我们在SpringMVC项目中需要加载配置文件时,通常会使用Properties文件来存储配置信息。本文将介绍几种在SpringMVC中加载Properties文件的方式。 方式一:使用@PropertySource注解 我们可以使用@PropertySource注解来加载Properties文件。在SpringMVC中,我们可以在配置类中使用该注解来指定…

    Java 2023年5月17日
    00
  • Java的final修饰符

    final 实例域 可以将实例域定义为 final。对于 final 域来说,构建对象时必须初始化 final 实例域,构造对象之后就不允许改变 final 实例域的值了。也就是说,必须确保在每一个构造器执行之后,final 实例域的值被设置,并且在后面的操作中,不能够再对 final 实例域进行修改。 例如,可以将 Employee 类中的 name 域声…

    Java 2023年4月25日
    00
  • Java实现的生成二维码统计扫描次数并转发到某个地址功能详解

    Java实现的生成二维码统计扫描次数并转发到某个地址功能详解 简介 二维码是一种可被扫描识别的矩阵条形码。在现代生活中,二维码广泛应用于各种场景中,例如商业推广、门禁系统、实名认证、票务管理等等。Java语言可以用来生成二维码,并通过统计扫描次数等功能对二维码进行管理。 实现步骤 以下是使用Java生成二维码并统计扫描次数并转发到某个地址的具体步骤: 步骤一…

    Java 2023年5月20日
    00
  • Java SpringBoot 中的操作事务

    我们来详细讲解一下Java SpringBoot中的操作事务。 什么是事务 事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么全部执行,要么全部不执行,如果在执行整个事务时发生错误,会回滚到事务的开始状态,使所有操作都回到事务执行之前的状态。 Spring 中如何使用事务 Spring 提供了一套完整的事务管理机制,其中最基础的是PlatformTr…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部