【后端高频面试题--Mybatis篇】

🚀 作者 :“码上有前”
🚀 文章简介 :后端高频面试题
🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬

在这里插入图片描述

后端高频面试题--Mybatis篇

  • 什么是Mybatis?Mybatis的优缺点?
  • Mybatis的特点
  • Mybatis框架适合场合
  • JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
  • MyBatis与Hibernate有哪些不同?
  • # 谈一下你对 mybatis 缓存机制的理解?
  • Mybatis中一级缓存与二级缓存
  • MyBatis在insert插入操作时如何返回主键ID
  • MyBatis 的 #{} 和 ${} 的区别?
  • 当实体类中的属性名和表中的字段名不一样,怎么办?
  • 模糊查询like语句该怎么写?
  • 通常一个XML映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
  • 在 mybatis 中,resultType 和 ResultMap 的区别是什么?(必会)
  • 在 Mybatis 中你知道的动态 SQL 的标签有哪些?作用分别是什么?
  • Mybatis是如何进行分页的?分页插件的原理是什么?
  • Mybatis中的Mapper接口和XML文件里的SQL是如何建立关系的?
  • Mybatis用过哪些标签?
  • Mybatis执行流程?

什么是Mybatis?Mybatis的优缺点?

MyBatis(原名为iBatis)是一种Java持久层框架,用于简化数据库访问的开发。它通过将数据库访问逻辑与业务逻辑分离,提供了一种灵活且简单的方式来进行数据库操作。

MyBatis的主要特点包括:

  1. 简化SQL编写:MyBatis通过提供XML配置文件和注解方式,将SQL语句与Java代码分离,使得SQL编写更加清晰和可维护。

  2. 强大的映射功能:MyBatis支持将查询结果自动映射到Java对象,通过配置映射关系,可以方便地进行对象与数据库表之间的转换。

  3. 动态SQL支持:MyBatis提供了动态SQL功能,可以根据不同条件拼接SQL语句,简化了复杂查询的编写。

  4. 缓存支持:MyBatis内置了一级缓存和二级缓存,可以提高查询性能,减少数据库访问次数。

  5. 插件扩展机制:MyBatis提供了插件扩展机制,可以通过插件来扩展和定制MyBatis的功能,如自定义拦截器、修改SQL执行过程等。

MyBatis的优点包括:

  1. 灵活性:MyBatis不强制使用特定的ORM模型,开发者可以自由地编写SQL和控制数据库访问逻辑,适用于复杂的业务需求。

  2. 性能优化:MyBatis提供了缓存机制和动态SQL支持,可以有效地提高数据库访问性能。

  3. 易于集成:MyBatis与Java应用集成简单,可以与各种主流的Java框架(如Spring)无缝集成,提供了丰富的整合支持。

  4. 易于学习和上手:相对于其他ORM框架,MyBatis学习曲线较为平缓,使用起来相对简单,容易上手。

MyBatis的缺点包括:

  1. 配置较复杂:MyBatis需要编写XML配置文件来映射SQL语句和Java对象,对于简单的CRUD操作可能会增加一些额外的配置和工作量。

  2. SQL依赖:MyBatis需要开发者手动编写和维护SQL语句,对于不熟悉SQL的开发者来说,可能需要额外学习和掌握SQL的知识。

  3. 缺乏自动化:相对于全自动的ORM框架,MyBatis需要开发者手动编写SQL语句和映射关系,对于某些简单的业务需求,可能会显得繁琐。

综上所述,MyBatis作为一种轻量级的持久层框架,在灵活性、性能优化和易于集成等方面具有优势,但在配置复杂和SQL依赖方面存在一些缺点。开发者可以根据项目需求和个人经验,评估是否选择使用MyBatis。

Mybatis的特点

MyBatis是一种开源的持久层框架,它具有以下几个特点:

  1. 简化数据库操作:MyBatis通过提供简洁的配置和灵活的映射方式,将数据库操作的细节隐藏起来,开发者只需关注SQL语句的编写和结果的映射,而无需手动处理数据库连接、事务和结果集等底层细节。

  2. 灵活的SQL编写:MyBatis支持使用原生的SQL语句,开发者可以编写和优化自己的SQL语句,灵活性较高。同时,MyBatis也提供了动态SQL的功能,可以根据条件动态拼接SQL语句,方便实现复杂的查询和更新操作。

  3. 强大的映射功能:MyBatis提供了丰富的映射功能,可以将查询结果自动映射到Java对象中,大大简化了结果集的处理。同时,MyBatis还支持一对一、一对多、多对一和多对多等复杂的关联关系映射,方便进行对象之间的关联查询。

  4. 缓存支持:MyBatis提供了缓存机制,可以将查询结果缓存起来,下次相同的查询可以直接从缓存中获取,提高查询性能。MyBatis提供了一级缓存和二级缓存两种缓存级别,可以根据需求选择合适的缓存策略。

  5. 插件扩展:MyBatis支持插件机制,可以通过自定义插件来扩展和定制框架的功能。开发者可以通过插件来拦截和修改MyBatis的SQL执行过程,例如添加自定义的日志、性能监控等功能。

  6. 跨数据库支持:MyBatis可以适配多种不同的关系型数据库,例如MySQL、Oracle、SQL Server等,开发者可以在不同的数据库之间切换而无需修改大量的代码。

总体而言,MyBatis是一款灵活、简单且功能强大的持久层框架,它将数据库操作的细节封装起来,提供了便捷的配置和映射方式,同时支持自定义SQL和插件扩展,使得开发者可以更加高效地进行数据库操作。

Mybatis框架适合场合

MyBatis框架适用于以下场合:

  1. 需要灵活控制SQL语句:如果你需要对SQL语句进行细粒度的控制,包括编写复杂的查询语句、优化SQL性能或者使用数据库特定的高级功能,MyBatis是一个不错的选择。MyBatis允许你直接编写和优化原生SQL语句,同时提供了动态SQL的功能,方便根据条件拼接SQL语句。

  2. 需要高度可定制的映射:MyBatis提供了强大的结果映射功能,可以将查询结果自动映射到Java对象中。如果你的数据库结构与Java对象之间存在复杂的映射关系,例如一对一、一对多等关联关系,MyBatis可以很好地处理这些映射关系,并减少手动处理结果集的工作量。

  3. 需要对数据访问逻辑进行细粒度的控制:MyBatis允许你在SQL语句的执行过程中插入自定义的代码逻辑,包括拦截器、自定义类型处理器等。这样你可以对数据访问逻辑进行更细粒度的控制和定制,例如添加自定义的日志、缓存逻辑或者性能监控等。

  4. 需要细粒度地控制事务:MyBatis允许你对事务进行细粒度的控制,包括手动提交和回滚事务。如果你需要精确地控制事务边界,例如在一个方法中执行多个数据库操作,可以使用MyBatis的事务管理功能。

  5. 对性能有较高要求:MyBatis提供了一级缓存和二级缓存的支持,可以缓存查询结果,提高查询性能。通过合理配置和使用缓存,可以减少数据库访问次数,提高系统的响应速度和吞吐量。

总的来说,MyBatis适用于对SQL语句和数据访问逻辑有较高要求的项目,它提供了灵活的SQL编写方式、强大的结果映射功能和可定制性,可以满足复杂的业务需求。但同时,也需要开发者对数据库操作和SQL语句有一定的了解和掌握。

JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?

JDBC(Java Database Connectivity)是Java语言与数据库进行交互的标准接口,虽然它具有一定的优势,但也存在一些不足之处。以下是JDBC编程的一些不足之处以及MyBatis是如何解决这些问题的:

  1. 冗余的样板代码:JDBC编程需要大量的样板代码来处理数据库连接、事务管理、SQL语句的拼接和结果集的处理等。这些代码冗余且容易出错,增加了开发和维护的工作量。

    MyBatis解决方案:MyBatis通过提供SQL映射配置文件和自定义接口来减少冗余的样板代码。开发者只需编写少量的配置和接口代码,MyBatis会自动处理数据库连接、事务管理和结果集的映射,简化了开发流程。

  2. SQL与Java代码的混合:在JDBC编程中,SQL语句通常与Java代码混合在一起,导致SQL的可读性差、维护困难,并且在修改SQL时需要重新编译Java代码。

    MyBatis解决方案:MyBatis将SQL与Java代码分离,通过XML配置文件或注解方式来定义SQL语句,使得SQL可读性更高,便于维护和修改,无需重新编译Java代码。

  3. 数据库操作的细节:JDBC编程需要开发者手动处理数据库连接的获取和释放、事务管理和异常处理等细节,容易出现资源泄露和错误处理不当的问题。

    MyBatis解决方案:MyBatis封装了底层的数据库访问细节,自动管理数据库连接的获取和释放,提供了事务管理机制,简化了数据库操作的细节处理,减少了出错的可能性。

  4. 性能优化困难:JDBC编程需要开发者手动优化SQL语句、使用批处理和分页等技术来提高性能,这对于不熟悉数据库优化的开发者来说可能较为困难。

    MyBatis解决方案:MyBatis提供了缓存机制、动态SQL和插件扩展等功能,可以帮助开发者进行性能优化。它提供了一些优化技术,如缓存查询结果、动态拼接SQL语句和自定义插件,简化了性能优化的工作。

综上所述,MyBatis通过提供SQL与Java代码分离、自动处理数据库连接和事务管理、性能优化等功能,解决了JDBC编程中存在的冗余代码、SQL与Java代码混合、细节处理和性能优化困难等问题,提供了更简洁、易于维护和优化的数据库访问解决方案。

MyBatis与Hibernate有哪些不同?

MyBatis和Hibernate是两个非常流行的Java持久层框架,它们在一些方面有着明显的不同:

  1. SQL控制方式:MyBatis采用基于SQL的方式,开发者需要手动编写和优化SQL语句,可以对SQL进行精确控制和优化。而Hibernate采用基于对象的方式,开发者不需要编写SQL语句,框架会自动将对象持久化到数据库中,或者从数据库中检索对象。

  2. 对象关系映射(ORM):MyBatis将查询结果映射到Java对象中,提供了灵活的结果映射功能,可以处理复杂的关联关系。但是,开发者需要手动编写SQL语句和结果映射规则。Hibernate则完全执行ORM,自动将数据库表和Java对象进行映射,无需手动编写SQL语句和映射规则。

  3. 查询灵活性:MyBatis提供了动态SQL的功能,可以根据条件动态拼接SQL语句,灵活性较高,适合复杂查询。Hibernate使用Hibernate Query Language(HQL)进行查询,它是一种面向对象的查询语言,类似于SQL,但语法更接近于Java,可以方便地进行对象导航和查询。

  4. 缓存机制:MyBatis提供了一级缓存和二级缓存的支持,可以缓存查询结果,提高查询性能。一级缓存是在会话级别缓存,而二级缓存是在应用程序级别缓存。Hibernate也提供了缓存机制,但缓存的粒度更细,包括对象级缓存、集合级缓存等。

  5. 对数据库的依赖:MyBatis相对于Hibernate对数据库的依赖较低,开发者需要手动编写SQL语句和处理数据库连接、事务等细节。Hibernate则对数据库的依赖较高,框架会自动处理SQL语句的生成、连接管理和事务控制。

  6. 学习曲线:MyBatis相对于Hibernate来说学习曲线较陡峭,需要开发者熟悉SQL语句的编写和优化。Hibernate则相对较简单,使用者只需了解框架提供的API和配置,无需关注SQL语句的编写。

选择使用MyBatis还是Hibernate取决于项目的需求和开发者的偏好。如果对SQL的精确控制和灵活性有较高要求,或者需要处理复杂的关联关系,MyBatis可能是更好的选择。如果对开发速度和对象导航查询有较高要求,或者对SQL编写不熟悉,Hibernate可能更适合。

# 谈一下你对 mybatis 缓存机制的理解?

Mybatis中一级缓存与二级缓存

MyBatis提供了两级缓存来提高查询性能:一级缓存和二级缓存。

  1. 一级缓存:

    • 一级缓存是MyBatis默认开启的,它是在SqlSession的生命周期内有效的。
    • 当SqlSession执行查询操作时,查询的结果会被缓存到一级缓存中,下次相同的查询可以直接从缓存中获取结果,避免了重复查询数据库的开销。
    • 一级缓存是基于对象引用的缓存,即当SqlSession关闭或执行了更新操作(插入、更新、删除)时,缓存将被清空,所有缓存的对象将失效。
  2. 二级缓存:

    • 二级缓存是跨SqlSession的缓存,可以被多个SqlSession共享。
    • 二级缓存需要手动配置并开启,在MyBatis的配置文件中进行配置。
    • 当SqlSession执行查询操作时,结果会被缓存到二级缓存中,其他的SqlSession可以从二级缓存中获取结果。
    • 二级缓存是基于缓存对象的序列化和反序列化,因此需要缓存的对象必须实现序列化接口。
    • 更新操作会导致二级缓存的失效,因为更新操作可能会改变缓存中的数据。

需要注意的是,虽然缓存可以提高查询性能,但在某些场景下可能会导致数据不一致的问题。因此,对于经常变动的数据或者对数据强一致性要求较高的场景,建议谨慎使用缓存,或者在更新操作时手动刷新缓存。

可以通过配置文件中的<cache>元素来配置二级缓存,通过<select>元素的useCache属性来控制是否使用一级缓存。

MyBatis在insert插入操作时如何返回主键ID

在MyBatis中,可以通过以下几种方式获取插入操作后的主键ID:

  1. 使用数据库的自增主键:

    • 如果你的数据库表使用了自增主键,那么在执行插入操作后,可以通过useGeneratedKeyskeyProperty属性来获取插入后的自增主键值。
    • 在插入语句的<insert>元素中,设置useGeneratedKeys="true",表示使用数据库的自动生成的主键。
    • 同时在<insert>元素中,设置keyProperty,指定一个Java对象的属性名,用于接收自动生成的主键值。
    • 插入完成后,可以通过获取该Java对象的属性值来获取主键ID。
  2. 使用数据库的序列:

    • 如果你的数据库表使用了序列来生成主键,那么可以通过selectKey元素来获取插入后的主键值。
    • 在插入语句的<insert>元素中,添加<selectKey>元素,在其中定义查询序列的语句,并设置keyProperty指定一个Java对象的属性名,用于接收序列生成的主键值。
    • 插入完成后,可以通过获取该Java对象的属性值来获取主键ID。

下面是一个使用数据库的自增主键的示例:

<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">
    INSERT INTO user (username, password) VALUES (#{username}, #{password})
</insert>

在Java代码中,执行插入操作后,可以通过获取User对象的id属性来获取主键ID:

User user = new User();
user.setUsername("John");
user.setPassword("123456");
mapper.insertUser(user);
System.out.println(user.getId());

注意,获取主键ID的方式可能因数据库的不同而略有差异,具体应根据使用的数据库类型和配置进行相应的设置。

MyBatis 的 #{} 和 ${} 的区别?

在MyBatis中,#{}${}是两种不同的参数替换方式,它们有以下区别:

  1. #{}参数替换方式:

    • #{}是预编译的方式,会将参数值进行安全地替换,并将参数值作为预编译的占位符传递给数据库驱动,以防止SQL注入攻击。
    • #{}可以用于替换任何位置的参数,包括SQL语句中的表名、列名、条件值等。
    • #{}可以接收任意类型的参数,并且会自动进行类型转换,例如数字、字符串、日期等。
  2. ${}参数替换方式:

    • ${}是文本替换的方式,会将参数值直接替换到SQL语句中,生成最终的SQL语句。
    • ${}可以用于替换SQL语句中的表名、列名等静态部分,不能用于替换条件值等动态部分。
    • ${}只是简单地将参数值替换到SQL语句中,不会进行预编译和安全检查,存在SQL注入的风险。

主要区别总结如下:

  • #{}是预编译占位符,安全且可接收任意类型参数,适合替换动态的值。
  • ${}是文本替换,不做预编译和安全检查,适合替换静态的表名、列名等部分。
  • 为了避免SQL注入攻击,推荐使用#{}替换动态值,尽量避免使用${}替换动态值。

使用示例:

<!-- 使用#{param}方式 -->
<select id="getUserById" parameterType="int" resultType="User">
  SELECT * FROM user WHERE id = #{id}
</select>

<!-- 使用${param}方式 -->
<select id="getUserByTableName" parameterType="String" resultType="User">
  SELECT * FROM ${tableName} WHERE id = 1
</select>

在使用#{}方式时,MyBatis会将参数值进行预编译和安全替换,生成类似于SELECT * FROM user WHERE id = ?的SQL语句,然后将参数值传递给数据库驱动执行。

在使用${}方式时,MyBatis会直接将参数值替换到SQL语句中,生成类似于SELECT * FROM tablename WHERE id = 1的SQL语句。请注意,${}方式存在潜在的安全风险,因此在使用时应谨慎验证和过滤参数值,以避免SQL注入攻击。

当实体类中的属性名和表中的字段名不一样,怎么办?

当实体类中的属性名和表中的字段名不一致时,可以通过在MyBatis中进行映射配置来解决。MyBatis提供了多种方式来处理属性与字段的映射关系:

  1. 使用<resultMap>:可以使用<resultMap>标签来定义属性和字段之间的映射关系。在<resultMap>中,可以使用<result>标签指定属性和字段的对应关系,通过column属性指定数据库字段名,通过property属性指定实体类属性名。

    <resultMap id="userResultMap" type="User">
      <result column="user_name" property="userName"/>
      <result column="user_age" property="userAge"/>
    </resultMap>
    

    然后在SQL映射文件中使用<resultMap>

    <select id="getUserById" resultMap="userResultMap">
      SELECT user_name, user_age FROM user WHERE id = #{id}
    </select>
    

    这样,查询结果中的user_name字段会映射到userName属性,user_age字段会映射到userAge属性。

  2. 使用<result>标签:除了使用<resultMap>,也可以在SQL映射文件的SQL语句中使用<result>标签直接指定属性和字段的对应关系。

    <select id="getUserById" resultType="User">
      SELECT user_name AS userName, user_age AS userAge FROM user WHERE id = #{id}
    </select>
    

    在这个例子中,user_name字段会映射到userName属性,user_age字段会映射到userAge属性。

  3. 使用注解:MyBatis也支持使用注解方式来进行属性和字段的映射配置。可以使用@Results@Result注解来指定属性和字段的对应关系。

    @Results({
        @Result(column = "user_name", property = "userName"),
        @Result(column = "user_age", property = "userAge")
    })
    @Select("SELECT user_name, user_age FROM user WHERE id = #{id}")
    User getUserById(int id);
    

    在这个例子中,user_name字段会映射到userName属性,user_age字段会映射到userAge属性。

通过以上方式,可以将实体类的属性名和表中的字段名进行映射配置,使其能够正确地进行属性和字段之间的转换。

模糊查询like语句该怎么写?

在 MyBatis 中进行模糊查询可以使用 SQL 的 LIKE 语句,并结合通配符 %_ 来匹配模式。下面是几种常见的使用方式:

  1. 匹配开头或结尾的模糊查询:

    <select id="searchUsers" resultType="User">
      SELECT * FROM user WHERE user_name LIKE #{keyword}%
    </select>
    

    在这个例子中,#{keyword} 是要匹配的关键字,% 是通配符,表示匹配任意字符。这样查询会返回所有 user_name 以指定关键字开头的用户。

  2. 匹配包含的模糊查询:

    <select id="searchUsers" resultType="User">
      SELECT * FROM user WHERE user_name LIKE %#{keyword}%
    </select>
    

    在这个例子中,#{keyword} 是要匹配的关键字,% 是通配符,表示匹配任意字符。这样查询会返回所有 user_name 中包含指定关键字的用户。

  3. 自定义通配符:

    <select id="searchUsers" resultType="User">
      SELECT * FROM user WHERE user_name LIKE CONCAT('%', #{keyword}, '%')
    </select>
    

    在这个例子中,使用了 CONCAT 函数将 % 和关键字拼接在一起,实现模糊匹配。这样查询会返回所有 user_name 中包含指定关键字的用户。

请注意,上述示例中的 #{keyword} 是 MyBatis 中的占位符,具体的值需要在实际调用时传入。

另外,如果需要进行大小写敏感的模糊查询,你可以根据数据库的特性来使用相应的函数或操作符,如 UPPER 函数将关键字和数据库字段都转换为大写,以实现不区分大小写的匹配。具体的语法和函数可能会因数据库类型而有所不同,你可以根据使用的数据库进行相应的调整。

通常一个XML映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?

在 MyBatis 中,Dao 接口与 XML 映射文件相互对应,主要负责定义数据库操作的方法。Dao 接口的工作原理是通过 MyBatis 的动态代理机制,将接口的方法调用转化为对应的 SQL 语句执行。

当你定义一个 Dao 接口时,MyBatis 会根据接口的方法名和参数来查找对应的 XML 映射文件中的 SQL 语句进行执行。这样,你可以通过调用 Dao 接口的方法,来实现对数据库的增、删、改、查等操作。

下面是一个示例的 Dao 接口和对应的 XML 映射文件的示例:

public interface UserDao {
    User getUserById(int id);
    List<User> getUsersByKeyword(String keyword);
    void insertUser(User user);
    void updateUser(User user);
    void deleteUser(int id);
}
<!-- UserDao.xml -->
<mapper namespace="com.example.dao.UserDao">
    <select id="getUserById" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
    
    <select id="getUsersByKeyword" resultType="User">
        SELECT * FROM user WHERE user_name LIKE CONCAT('%', #{keyword}, '%')
    </select>
    
    <insert id="insertUser">
        INSERT INTO user (user_name, user_age) VALUES (#{userName}, #{userAge})
    </insert>
    
    <update id="updateUser">
        UPDATE user SET user_name = #{userName}, user_age = #{userAge} WHERE id = #{id}
    </update>
    
    <delete id="deleteUser">
        DELETE FROM user WHERE id = #{id}
    </delete>
</mapper>

在上述示例中,Dao 接口中的方法与 XML 映射文件中定义的 SQL 语句相对应。当调用 getUserById 方法时,MyBatis 会查找 getUserById 对应的 SQL 语句进行执行。

关于方法重载的问题,Java 中的接口是支持方法重载的,因此在 Dao 接口中,方法名相同但参数不同是可以实现方法重载的。例如,你可以定义多个方法名为 getUserById 的方法,但参数列表不同:

public interface UserDao {
    User getUserById(int id);
    User getUserById(String id);
}

这样,在调用时根据传入的参数类型不同,会自动匹配相应的方法。但是需要注意的是,MyBatis 在执行 SQL 语句时是根据方法名进行匹配的,因此方法名必须是唯一的,不能出现重复的方法名。

总结来说,Dao 接口通过定义方法与 XML 映射文件中的 SQL 语句相对应,通过 MyBatis 的动态代理机制将方法调用转化为 SQL 语句的执行。可以根据需要在接口中定义不同的方法名和参数列表,实现对数据库的各种操作。

在 mybatis 中,resultType 和 ResultMap 的区别是什么?(必会)

在 MyBatis 中,resultTyperesultMap 都用于指定查询结果的映射方式,但它们有一些关键的区别。

  1. resultTyperesultType 用于指定查询结果的类型,即将查询结果映射到的 Java 对象的类型。它通常用于简单的映射情况,其中查询结果的列名会与目标对象的属性名一一对应。使用 resultType 时,MyBatis 会使用默认的规则进行自动映射。

    例如,如果查询的结果是一个 User 对象,可以在 SQL 映射文件中这样指定:

    <select id="getUserById" resultType="User">
      SELECT * FROM user WHERE id = #{id}
    </select>
    

    在这个例子中,查询结果会自动映射到 User 类型的对象。

    使用 resultType 的限制是,查询结果的列名必须和目标对象的属性名一一对应,否则无法进行自动映射。

  2. resultMapresultMap 用于定义复杂的结果集映射关系。它提供了更灵活的映射方式,可以手动指定查询结果的列名和目标对象的属性名之间的对应关系。通过 resultMap,可以处理查询结果与目标对象属性名不一致的情况,以及进行关联查询、嵌套对象等复杂映射操作。

    通过 resultMap,可以在 SQL 映射文件中自定义映射规则。下面是一个示例:

    <resultMap id="userResultMap" type="User">
      <id property="id" column="user_id"/>
      <result property="userName" column="user_name"/>
      <result property="userAge" column="user_age"/>
    </resultMap>
    
    <select id="getUserById" resultMap="userResultMap">
      SELECT user_id, user_name, user_age FROM user WHERE id = #{id}
    </select>
    

    在这个例子中,resultMap 定义了 User 类型的映射规则,指定了查询结果中的列名与 User 对象的属性名之间的对应关系。

    使用 resultMap 可以处理更复杂的映射情况,灵活性更高,但需要手动编写映射规则。

总结来说,resultType 适用于简单的结果集映射,通过自动映射规则将查询结果映射到指定类型的对象;resultMap 则适用于复杂的结果集映射,可以手动定义映射规则,处理更灵活的映射需求。

在 Mybatis 中你知道的动态 SQL 的标签有哪些?作用分别是什么?

MyBatis 提供了一些动态 SQL 的标签,用于在 SQL 映射文件中编写灵活的 SQL 语句。以下是一些常用的动态 SQL 标签及其作用:

  1. <if> 标签:用于条件判断,根据条件动态生成 SQL 语句的一部分。

    <select id="getUser" resultType="User">
      SELECT * FROM user
      WHERE
      <if test="id != null">
        id = #{id}
      </if>
      <if test="username != null">
        AND username = #{username}
      </if>
    </select>
    

    在这个例子中,根据传入的参数动态生成了不同的 SQL 语句,如果 id 不为 null,则生成 id = #{id} 的条件;如果 username 不为 null,则生成 AND username = #{username} 的条件。

  2. <choose>、<when>、<otherwise> 标签:用于实现条件选择,类似于 Java 的 switch 语句。

    <select id="getUser" resultType="User">
      SELECT * FROM user
      <choose>
        <when test="id != null">
          WHERE id = #{id}
        </when>
        <when test="username != null">
          WHERE username = #{username}
        </when>
        <otherwise>
          WHERE 1=1
        </otherwise>
      </choose>
    </select>
    

    在这个例子中,根据不同的条件选择生成不同的 SQL 语句,如果 id 不为 null,则生成 WHERE id = #{id} 的条件;如果 username 不为 null,则生成 WHERE username = #{username} 的条件;如果 idusername 都为 null,则生成 WHERE 1=1 的条件。

  3. <foreach> 标签:用于遍历集合或数组,并在 SQL 语句中生成相应的部分。

    <select id="getUsersByIds" resultType="User">
      SELECT * FROM user
      WHERE id IN
      <foreach collection="ids" item="id" separator="," open="(" close=")">
        #{id}
      </foreach>
    </select>
    

    在这个例子中,ids 是一个集合或数组,通过 <foreach> 标签将其中的元素逐个取出,并生成 id IN (id1, id2, id3) 的条件。

  4. <trim><set><where> 标签:用于处理 SQL 语句中的前缀、后缀以及条件的动态拼接。

    <update id="updateUser" parameterType="User">
      UPDATE user
      <set>
        <if test="username != null">
          username = #{username},
        </if>
        <if test="password != null">
          password = #{password},
        </if>
      </set>
      WHERE id = #{id}
    </update>
    

    在这个例子中,<set> 标签用于动态拼接 SET 子句,根据条件拼接不同的字段更新语句。

这些动态 SQL 标签提供了灵活的编写 SQL 语句的方式,可以根据不同的条件动态生成 SQL 的部分,使 SQL 映射文件更具可读性和可维护性。

Mybatis是如何进行分页的?分页插件的原理是什么?

在 MyBatis 中进行分页查询通常有两种方式:使用数据库的分页查询语句或者使用分页插件。

  1. 数据库的分页查询语句:可以使用数据库特定的分页查询语句(如 MySQL 的 LIMIT 关键字或 Oracle 的 ROWNUM)来实现分页查询。在 SQL 语句中通过指定起始行和每页显示的记录数来实现分页效果。

    -- MySQL
    SELECT * FROM table LIMIT 0, 10;
    
    -- Oracle
    SELECT * FROM (SELECT ROWNUM as rowno, t.* FROM table t) WHERE rowno BETWEEN 0 AND 10;
    

    这种方式的优点是简单直接,但不同数据库的分页语句略有差异,需要根据具体的数据库进行调整。

  2. 分页插件:MyBatis 还提供了一些分页插件,例如 PageHelper、PaginationInterceptor 等,它们通过拦截 SQL 执行过程,在查询语句中自动添加分页的逻辑。分页插件的原理大致如下:

    • 拦截 SQL 执行过程:分页插件会拦截 MyBatis 的 SQL 执行过程,通常是通过拦截 Executor 对象的相关方法实现的。

    • 解析分页参数:插件会解析传入的分页参数,包括页码和每页显示的记录数。

    • 修改 SQL 语句:根据分页参数,插件会修改原始的 SQL 语句,添加分页的逻辑,例如在查询语句中添加 LIMIT 关键字或者改写为数据库特定的分页查询语句。

    • 执行分页查询:修改后的 SQL 语句会被执行,获取到分页结果集。

    • 封装分页结果:插件会将分页结果封装为特定的数据结构,通常是一个包含分页信息和数据列表的对象。

    分页插件的优点是使用方便,可以在不修改原始 SQL 语句的情况下实现分页效果,且对不同数据库的分页语句进行了封装,使用时无需关心具体的数据库差异。

需要注意的是,使用分页插件可能会对性能产生一定的影响,特别是在处理大数据量的分页查询时,因为插件需要对整个结果集进行处理。因此,在使用分页插件时,需要合理配置和使用,根据实际情况进行性能优化。

Mybatis中的Mapper接口和XML文件里的SQL是如何建立关系的?

在 MyBatis 中,Mapper 接口和 XML 文件里的 SQL 语句通过一定的约定进行关联,这样可以实现接口方法与对应的 SQL 语句的映射。下面是建立 Mapper 接口和 XML 文件关系的一般步骤:

  1. 创建 Mapper 接口:首先创建一个 Java 接口,该接口定义了需要执行的 SQL 操作,其中的方法名和参数与对应的 SQL 语句相关联。

    public interface UserMapper {
        User getUserById(int id);
        void insertUser(User user);
        void updateUser(User user);
        void deleteUser(int id);
    }
    
  2. 创建 Mapper XML 文件:在 MyBatis 的配置文件中,通过 <mapper> 标签指定 Mapper XML 文件的路径,并在该 XML 文件中编写与接口方法相关的 SQL 语句。

    <!-- userMapper.xml -->
    <mapper namespace="com.example.UserMapper">
        <select id="getUserById" resultType="User">
            SELECT * FROM user WHERE id = #{id}
        </select>
        <insert id="insertUser">
            INSERT INTO user (id, username, password) VALUES (#{id}, #{username}, #{password})
        </insert>
        <!-- 其他方法的 SQL 语句 -->
    </mapper>
    
  3. 配置 MyBatis 映射文件:在 MyBatis 的配置文件中,通过 <mappers> 标签配置 Mapper 映射文件的路径,将 Mapper 接口和对应的 XML 文件关联起来。

    <!-- mybatis-config.xml -->
    <configuration>
        <mappers>
            <mapper resource="com/example/userMapper.xml"/>
        </mappers>
    </configuration>
    

    或者可以使用注解的方式进行配置:

    <mapper class="com.example.UserMapper"/>
    
  4. 使用 Mapper 接口:在应用程序中,可以通过依赖注入或者获取 SqlSession 对象的方式获得 Mapper 接口的实例,然后调用接口方法执行 SQL 操作。

    // 获取 Mapper 接口实例
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    
    // 调用接口方法执行 SQL 操作
    User user = userMapper.getUserById(1);
    

    MyBatis 根据接口方法的名称和参数,通过动态代理的方式,将调用转发给对应的 XML 文件中定义的 SQL 语句。

通过以上的步骤,Mapper 接口与 XML 文件里的 SQL 语句建立了关联,实现了接口方法与对应的 SQL 操作的映射关系。这种方式使得 SQL 语句与 Java 代码分离,提升了代码的可维护性和可读性。

Mybatis用过哪些标签?

MyBatis 使用了多个标签来实现与数据库的交互和映射操作。下面列举了一些常用的 MyBatis 标签:

  1. <configuration>:MyBatis 的配置文件根元素,用于配置全局设置和属性。

  2. <settings>:用于配置 MyBatis 的全局设置选项,例如开启缓存、启用延迟加载等。

  3. <typeAliases>:用于配置类型别名,将 Java 类型与 XML 中的类型名称进行映射,简化映射配置。

  4. <dataSource>:用于配置数据源信息,指定数据库连接的相关参数。

  5. <environments>:用于配置 MyBatis 的运行环境,包括事务管理器和数据源。

  6. <transactionManager>:用于配置事务管理器,指定事务管理的方式,例如 JDBC 或者 Spring 事务管理。

  7. <mappers>:用于配置 Mapper 映射文件的路径或者 Mapper 接口的类名,将 Mapper 接口与对应的 SQL 映射文件进行关联。

  8. <mapper>:用于指定 Mapper 映射文件的路径或者 Mapper 接口的类名,建立 Mapper 接口与对应的 SQL 映射文件的关系。

  9. <resultMap>:用于定义结果集的映射关系,将查询结果映射为 Java 对象。

  10. <select>:用于定义查询操作的 SQL 语句。

  11. <insert>:用于定义插入操作的 SQL 语句。

  12. <update>:用于定义更新操作的 SQL 语句。

  13. <delete>:用于定义删除操作的 SQL 语句。

  14. <sql>:用于定义可重用的 SQL 片段,可以在其他 SQL 语句中引用。

  15. <if><choose><when><otherwise>:用于在 SQL 语句中进行条件判断和分支选择。

  16. <include>:用于引入外部的 SQL 片段,增强 SQL 的可重用性。

  17. <foreach>:用于循环遍历集合或数组,并在 SQL 语句中生成对应的参数。

这些标签涵盖了 MyBatis 中常见的配置和映射操作,通过它们可以进行灵活的 SQL 编写和与数据库的交互。

Mybatis执行流程?

在这里插入图片描述
MyBatis 的执行流程可以大致分为以下几个步骤:

  1. 加载配置文件:MyBatis 在启动时会加载配置文件(通常是 mybatis-config.xml),该配置文件包含了 MyBatis 的全局配置信息,如数据库连接信息、类型别名、映射文件等。

  2. 创建 SqlSessionFactory:通过配置文件,MyBatis 创建一个 SqlSessionFactory 对象,SqlSessionFactory 是 MyBatis 的核心对象,负责创建 SqlSession。

  3. 创建 SqlSession:通过 SqlSessionFactory 创建一个 SqlSession 对象,SqlSession 提供了与数据库交互的方法,包括执行 SQL 语句、获取映射器等。

  4. 获取映射器(Mapper):通过 SqlSession 获取映射器(Mapper)接口的实例,映射器接口定义了要执行的 SQL 操作。

  5. 执行 SQL 操作:通过映射器接口的方法执行 SQL 操作,可以执行查询、插入、更新、删除等操作。

  6. SQL 解析与执行:在执行 SQL 操作时,MyBatis 会解析映射器接口的方法名,并根据方法名找到对应的 SQL 语句。MyBatis 支持使用 XML 文件或注解的方式来定义 SQL 语句,根据配置的方式不同,解析的方式也会略有不同。

    • XML 方式:MyBatis 会根据映射器接口的名称和方法名,找到对应的 XML 映射文件,并解析其中定义的 SQL 语句。

    • 注解方式:MyBatis 会通过 Java 反射机制获取映射器接口上的注解信息,从而得到对应的 SQL 语句。

  7. 参数处理与绑定:MyBatis 会将方法参数与 SQL 语句中的参数进行绑定,将参数传递给 SQL 语句中的占位符。

  8. SQL 执行与结果映射:MyBatis 执行 SQL 语句,并将数据库返回的结果映射为 Java 对象,可以通过配置的 ResultMap 进行对象属性与结果集的映射。

  9. 事务管理:根据配置的事务管理方式,MyBatis 可能会在适当的时机开启、提交或回滚事务。

  10. 关闭 SqlSession:在完成数据库操作后,需要关闭 SqlSession,释放资源。

这是一个基本的 MyBatis 执行流程,具体的执行细节和步骤可能会受到配置和使用方式的影响。通过以上的流程,MyBatis 实现了将 Java 对象与数据库之间的映射和交互,简化了与数据库的编程工作。
都看到这了,点个赞吧🚀

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/382269.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

easyx 随机火花生成器 视觉盛宴

作品介绍&#xff1a; 在数字化艺术的世界里&#xff0c;我们经常寻求模拟自然现象的方式&#xff0c;为观众带来沉浸式的体验。本作品“随机火花生成器”就是一个尝试&#xff0c;通过编程模拟了火花的随机生成和消散过程。 在这段代码中&#xff0c;我们使用了EasyX图形库&…

Caché 为什么在医疗系统中吐槽

目前所知的 Cach 是应用在医院信息系统&#xff08;即 HIS&#xff09;&#xff0c;据说在欧美医疗卫生行业&#xff0c;Cach 占了 70% 的市场份额。国内的东华软件就是采用 Cach 数据库&#xff0c;东华软件在国内医院市场占有率大致为 20%&#xff0c;其中包括北京协和医院、…

redis源码之:cluster集群故障处理

在redis源码之&#xff1a;集群创建与节点通信&#xff08;1&#xff09;分析clusterCron定时任务及在redis源码之&#xff1a;集群创建与节点通信&#xff08;2&#xff09;分析**clusterReadHandler处理ping请求与pong响应时&#xff08;clusterProcessPacket&#xff09;**时…

读千脑智能笔记10_人类智能存在的风险

1. 人类智能存在的风险 1.1. “末日时钟” 1.1.1. 核战争引发的大火列为地球毁灭的主要原因 1.1.2. 气候变化列为人类自我毁灭的第二大潜在原因 1.2. 除非我们刻意加入自私的驱动力、动机或情感&#xff0c;否则智能机器并不会威胁到人类的生存 1.2.1. 人类在不远的将来会…

【数学建模】【2024年】【第40届】【MCM/ICM】【B题 搜寻潜水器】【解题思路】

一、题目 &#xff08;一&#xff09;赛题原文 2024 MCM Problem A: Resource Availability and Sex Ratios Maritime Cruises Mini-Submarines (MCMS), a company based in Greece, builds submersibles capable of carrying humans to the deepest parts of the ocean. A …

CVE-2012-1823 漏洞复现

CVE-2012-1823 PHP SAPI 与运行模式 首先&#xff0c;介绍一下PHP的运行模式。 下载PHP源码&#xff0c;可以看到其中有个目录叫sapi。sapi在PHP中的作用&#xff0c;类似于一个消息的“传递者”&#xff0c;比如在《Fastcgi协议分析 && PHP-FPM未授权访问漏洞 &…

在Ubuntu22.04上部署ComfyUI

ComfyUI 是 一个基于节点流程的 Stable Diffusion 操作界面&#xff0c;可以通过流程&#xff0c;实现了更加精准的工作流定制和完善的可复现性。每一个模块都有特定的的功能&#xff0c;我们可以通过调整模块连接达到不同的出图效果&#xff0c;特点如下&#xff1a; 1.对显存…

【深蓝学院】移动机器人运动规划--第4章 动力学约束下的运动规划--笔记

0. Outline 1. Introduction 什么是kinodynamic&#xff1f; 运动学&#xff08;Kinematics&#xff09;和动力学&#xff08;Dynamics&#xff09;都是力学的分支&#xff0c;涉及物体的运动&#xff0c;但它们研究的焦点不同。 运动学专注于描述物体的运动&#xff0c;而…

第67讲自定义icon实现

element-plus内置有一些常用的icon供我们使用&#xff0c;但是我们假如需要用自己的icon时候&#xff0c;我们可以搞一个icon自定义组件&#xff1b; 先把icons文件放到src下&#xff1b; 再新建一个SvgIcon组件&#xff1b; index.vue <template><svg class"…

Qt中程序发布及常见问题

1、引言 当我们写好一个程序时通常需要发布给用户使用&#xff0c;那么在Qt中程序又是如何实现发布的呢&#xff0c;这里我就来浅谈一下qt中如何发布程序&#xff0c;以及发布程序时的常见问题。 2、发布过程 2.1、切换为release模式 当我们写qt程序时默认是debug模式&#x…

部分意图分类【LLM+RAG】

在生成人工智能领域工作最有价值的事情之一就是发现新兴技术如何融入新的解决方案。 举个例子&#xff1a;在为北美顶级金融服务公司之一设计对话式人工智能助手时&#xff0c;WillowTree 的数据和人工智能研究团队 (DART) 发现&#xff0c;将意图分类与大型语言模型 (LLM) 结合…

学生宿舍管理系统设计与实现(源码+数据库+文档)

学生宿舍管理小程序目录 目录 基于微信小程序的学生宿舍管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、管理员模块的实现 &#xff08;1&#xff09;学生信息管理 &#xff08;2&#xff09;公告信息管理 &#xff08;3&#xff09;宿舍信息管理 &am…

LeetCode---383周赛

题目列表 3028. 边界上的蚂蚁 3029. 将单词恢复初始状态所需的最短时间 I 3030. 找出网格的区域平均强度 3031. 将单词恢复初始状态所需的最短时间 II 一、边界上的蚂蚁 这题没什么好说的&#xff0c;模拟就行&#xff0c;本质就是看前缀和有几个为0。 代码如下 class S…

springBoot,springSecurity返回乱码

框架&#xff1a;SpringBoot3 问题&#xff1a;响应内容乱码 问题代码&#xff1a; // 成功登录响应的内容Overridepublic void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication…

MongoDB从入门到实战之.NET Core使用MongoDB开发ToDoList系统(1)-后端项目框架搭建

前言&#xff1a; 前面的四个章节我们主要讲解了MongoDB的相关基础知识&#xff0c;接下来我们就开始进入使用.NET7操作MongoDB开发一个ToDoList系统实战教程。本章节主要介绍的是如何快熟搭建一个简单明了的后端项目框架。 MongoDB从入门到实战的相关教程 MongoDB从入门到实战…

【从Python基础到深度学习】1. Python PyCharm安装及激活

前言&#xff1a; 为了帮助大家快速入门机器学习-深度学习&#xff0c;从今天起我将用100天的时间将大学本科期间的所学所想分享给大家&#xff0c;和大家共同进步。【从Python基础到深度学习】系列博客中我将从python基础开始通过知识和代码实践结合的方式进行知识的分享和记…

JVM 性能调优 - 常用的垃圾回收器(6)

垃圾收集器 在 JVM(Java虚拟机)中,垃圾收集器(Garbage Collector)是负责自动管理内存的组件。它的主要任务是在程序运行过程中,自动回收不再使用的对象所占用的内存空间,以便为新的对象提供足够的内存。 JVM中的垃圾收集器使用不同的算法和策略来实现垃圾收集过程,以…

ChatGpt报错:Your authentication token is no longer valid解决办法

今天打开ChatGpt突然提示Oops&#xff01;,Your authentication token is no longer valid.&#xff0c;之前还好好的&#xff0c;环境也没变啊&#xff0c;结果弄了好久终于解决&#xff0c;于是记录一下解决过程&#xff0c;顺便总结一下关于OpenAI各种报错的解决办法。 完整…

[C#]winform制作圆形进度条好用的圆环圆形进度条控件和使用方法

【创建圆形进度条流程】 在C# WinForms应用程序中创建一个圆形进度条&#xff08;通常用作仪表盘的显示&#xff09;可以通过多种方式实现。下面是一个简单的例子&#xff0c;演示如何使用System.Drawing命名空间中的图形绘制功能来绘制一个基本的圆形进度条。 首先&#xff0…

hook函数——useRef

useRef useRef 是一个 React Hook&#xff0c;它能帮助引用一个不需要渲染的值。也就是说useRef可以存储一个值&#xff0c;但是不被组件渲染&#xff0c;仅仅只是引用&#xff0c;主要包括两个方面&#xff0c;例如使用ref引用一个值&#xff0c;使用ref引用一个dom节点&…