Mybatis(面试篇)

目录

Mybatis是什么?

Mybatis的优点

映射器

在mapper中传递多个参数

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

[#{} 和 {} 的区别是什么?](#{} 和 {} 的区别是什么?)

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

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

Mybatis是如何将sql执行结果封装为目标对象并返回的?

Mybatis都有哪些映射形式?

[XML映射文件中,除了常见select | inset | update | delete 标签之外,还有哪些标签?](#XML映射文件中,除了常见select | inset | update | delete 标签之外,还有哪些标签?)

简述Mybatis的XML映射文件和Mybatis内部数据结构之间的映射关系?


大家加油 !!!

Mybatis是什么?

  1. Mybatis是一个半ORM(关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费尽力去处理加载驱动,创建连接等等繁杂的过程。使用时直接编写原生态sql,可以严格控制sql执行性能,灵活度高

  2. Mybati可以使用XML活注解来配置映射原生信息,将POJO映射成数据库中的记录,避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。

Mybatis的优点

  1. 基于SQL语句编程,先当灵活,侵入小,解耦SQL于程序代码的耦合,便于统一管理,支持编写动态SQL语句,可重用

  2. 于JDBC相比减少大量冗余代码,不需要手动开关来连接

  3. 能够于Spring很好的集成

映射器

  1. #{}是占位符,预编译处理;${}是拼接符,字符串替换,没有预编译

  2. Mybatis在处理#{}时,#{}传入参数是以字符串传入,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值

  3. #{}可以有效防止SQL注入,提高系统安全性;${}不能防止SQL注入

4.#{}的变量替换是在DBMS中;${}的变量替换是在DBMS外

在mapper中传递多个参数

方法1:顺序传递法

XML 复制代码
public User selectUser(String name,int deptId);
<select id="selectUser" resultMap="UserResultMap">
  select * from where user_name = #{userName} and dept_id = #{deptId}
</select>
  1. #{}里面的数字代表参数的顺序

  2. 这种方法不建议使用,sql层不直观

方法2:@param注解传参数的顺序

XML 复制代码
public User selectUser(@pARAM("userName")String name,int@Param("deptId"))deptId);
<select id="selectUser" resultMap="UserResultMap">
  select * from user 
  where user_name = #{userName} and dept_id = #{deptId}
</select>
  1. #{}里面的名称对应的是@Param括号里面修饰的名称。

  2. 这种方法在参数不同的情况还是比较直观的(推荐使用)。

方法3:Map传递法

XML 复制代码
public User selectUser(Map<String,Object> params);
<select id="selectUser" parameterType="java.util.Map" resultMap="UserResultMap">
  select * from user
  where user_name = #{userName} and dept_id = #{deptId}
</select>
  1. #{}里面的名称对应的是Map里面的key名称

  2. 这种方法适合传递多个参数,且参数易变能灵活传递的情况,(推荐使用)。

方法4:Java Bean传参法

XML 复制代码
public User selectUser(User user);
<select id="selectUser" parameterType="com.jourwon.pojo.User" resultMap="UserResultMap">
  select * from user
  where user_name = #{userName} and dept_id = #{deptId}
</select>
  1. #{}里面的名称对应的是User类里面的成员属性。

  2. 这种方法直观,需要建一个实体类,扩展不容易,需要加属性,单代码可读性强,业务逻辑处理方便,推荐使用。(推荐使用)

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

第一种:通过在查询的SQL语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。

XML 复制代码
<select id="getOrder" parameterType="int" resultType="com.jouron.pojo.Order">
  select order_id id, order_no orderno,order_price price from orders where order_id=#{id};
</select>

第二种:通过<resultMap>来映射字段名和实体类属性名的--对应的关系。

XML 复制代码
<select id="getOrder" parameterType="int" resultMap="orderResultMap">
  select * from orders where order_id=#{id}
</select>
<resultMap type="com.jourwon.pojo.Order" id="orderResultMap">
  <!-- 用id属性来映射主键字段 -->
  <id property="id" column="order_id">
    <!-- 用id属性来映射非主键字段,property为实体类属性名,column为数据库表中的属性 -->
    <result property = "orderno" column = "order_no"></result>
    <result property = "price" column = "order_price"></result>
  </id>
</resultMap>

#{} 和 ${} 的区别是什么?

#{} 是预编译处理,${}是字符串替换

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的Set方法来赋值;

Mybatis哎处理 {},就是把 {}替换为变量的值。

使用#{}可以有效防止SQL注入,提高系统安全性

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

Dao接口,就是人们常说的Mapper接口,接口的权限名,就映射文件中的nameespace的值,接口的方法名,就是映射文件中MappedStatemment的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口时没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement,举例:

com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面 id = findStudentById的MappedStatement。在Mybatis中,每一个<select>、<insert>、<update>、<delete>标签,都会被解析一个MappedStatement对象。

Dao接口的方法,是不能重载的,因为是全限名 + 方法名的保存和寻找策略。

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

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

Mybatis使用RowBounds对象进行分页,他针对ResultSet结果集执行内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的基本原理使用Mybatis提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的slq,然后重写slq,更具dialect方言,添加对应的物理分页和物理分页参数。

Mybatis是如何将sql执行结果封装为目标对象并返回的?

主要涉及以下几个步骤:

  1. SQL查询:

用户通过MyBatis的API或者Mapper接口触发SQL查询。

Mybatis将SQL语句发送给数据库执行,并获取查询结果集(ResultSet)。

  1. 结果映射:

Mybatis使用<resultMap>元素来定义如何将ResultSet中的数据映射到Java对象上。

<resultMap>可以定义一对一、一对多或者多对多等复杂关系的映射。

  1. 属性映射:

<result>元素用映射简单的属性,例如将数据库表中的列名映射到Java对象的属性上。

<id>元素于<result>类似,但它用于标识主键字段

  1. 复杂映射:

<association>元素用来处理一对一的关系映射。

<collection>元素用来处理一对多的关系映射。

  1. 延迟加载:

MyBatis支持懒加载(lazy loading),这意味着关联对象只有在被显示访问时才会从数据库加载

Mybatis都有哪些映射形式?

  1. XML映射文件

这是Mybatis最常用的映射方式之一,通常会为每个Java接口(Mapper Interface)对应一个XML映射文件。XML文件中包含了SQL语句及相关的映射信息,如参数类型,返回类型等。

XML 复制代码
<mapper namespace="com.example.mapper.UserMapper">
    <select id="selectUser" resultType="com.example.domain.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

2.注解映射

MyBatis 还支持在 Mapper 接口中使用注解来定义 SQL 语句和映射关系,这种方式通常更加简洁,但不如 XML 文件灵活。

java 复制代码
public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{id}")
    User selectUser(@Param("id") int id);
}
  1. 动态SQL

MyBatis提供了动态SQL的支持,允许根据条件动态生成SQL语句。这在处理复炸的查询时非常有用。

XML 复制代码
<select id="selectUsersByCriteria" parameterType="com.example.domain.UserCriteria" resultType="com.example.domain.User">
    SELECT * FROM user
    <where>
        <if test="username != null">
            AND username = #{username}
        </if>
        <if test="age != null">
            AND age = #{age}
        </if>
    </where>
</select>

结果映射,嵌套查询,嵌套结果。

XML映射文件中,除了常见select | inset | update | delete 标签之外,还有哪些标签?

还有很多其他的标签,加上动态sql的9个标签,trim || where | set | foreach | if | choose | when | otherwise | bing 等,其中为sql片段标签,通过标签引入sql片段,为不支持自增的主键生成车策略标签。

简述Mybatis的XML映射文件和Mybatis内部数据结构之间的映射关系?

Mybatis将所有Xml配置信息信息都封装到All-In-One重量级对象 Configuration内部。在Xml映射文件中,<paramenterMap> 标签会被解析为ParameterMap对象,其每个子元素会被解析为ParameterMapping对象。<resultMap> 标签会被解析为ResultMap对象,其每个子元素会被解析为ResultMapping对象。每一个<select>、<insert>、<update>、<delete>标签均会被解析为MappedStatement对象,标签内的sql会被解析为BoundSQL对象

相关推荐
Jabes.yang5 小时前
Java求职面试: 互联网医疗场景中的缓存技术与监控运维应用
java·redis·spring security·grafana·prometheus·oauth2·互联网医疗
初级炼丹师(爱说实话版)5 小时前
内存泄漏与内存溢出
java
CryptoRzz6 小时前
越南k线历史数据、IPO新股股票数据接口文档
java·数据库·后端·python·区块链
!if6 小时前
springboot mybatisplus 配置SQL日志,但是没有日志输出
spring boot·sql·mybatis
学Java的bb6 小时前
MybatisPlus
java·开发语言·数据库
讓丄帝愛伱6 小时前
Mybatis Log Free插件使用
java·开发语言·mybatis
重生之我要当java大帝6 小时前
java微服务-尚医通-编写医院设置接口上
java·数据库·微服务
夫唯不争,故无尤也6 小时前
Tomcat 内嵌启动时找不到 Web 应用的路径
java·前端·tomcat
心之伊始6 小时前
Netty线程模型与Tomcat线程模型对比分析
java·开发语言
gaoshan123456789106 小时前
‌MyBatis-Plus 的 LambdaQueryWrapper 可以实现 OR 条件查询‌
java·tomcat·mybatis