Java 岗大厂面试百日冲刺 - 日积月累,每日三题【Day20,从 java 后端到全栈百度云
* [二级缓存](about:blank#_184) * [追问 1:一级缓存和二级缓存的使用顺序](about:blank#1_227) * [每日小结](about:blank#_236) * * * 本栏目 Java 开发岗高频面试题主要出自以下各技术栈:`Java 基础知识`、`集合容器`、`并发编程`、`JVM`、`Spring 全家桶`、`MyBatis 等 ORMapping 框架`、`MySQL 数据库`、`Redis 缓存`、`RabbitMQ 消息队列`、`Linux 操作技巧`等。 []( )面试题 1:说说你对 Mybatis 的理解? =================================================================================== Mybatis 是一个`持久层的框架`,是 apache 下的顶级项目。 ![在这里插入图片描述](https://static001.geekbang.org/infoq/ac/ac350b5387052d2f84079af953bec3aa.png) Mybatis 内部封装了 jdbc,开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement 等繁杂的过程。 mybatis 通过`xml`或`注解`的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。 MyBatis `支持定制化 SQL、存储过程以及高级映射`。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO 映射成数据库中的记录。 []( )追问 1:说一下 MyBatis 的工作原理和流程吧。 --------------------------------------------------------------------------------------- 1. `读取 MyBatis 配置文件`:`mybatis-config.xml`为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。 2. `加载映射文件`:映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。 ![在这里插入图片描述](https://static001.geekbang.org/infoq/28/28c3f3398e6148e956bbd8b7a8734cd4.png) 3. ``` 【一线大厂 Java 面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】 浏览器打开:qq.cn.hn/FTf 免费领取 ``` `构造会话工厂`:通过 MyBatis 的环境等配置信息构建会话工厂 `SqlSessionFactory`。 4. `创建会话对象`:由会话工厂创建 `SqlSession` 对象,该对象中包含了执行 SQL 语句的所有方法。 5. `Executor 执行器`:MyBatis 底层定义了一个 `Executor 接口来操作数据库`,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时`负责查询缓存的维护`。 6. `MappedStatement 对象`:在 Executor 接口的执行方法中有一个 `MappedStatement` 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。 7. `输入参数映射`:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。 8. `输出结果映射`:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。 []( )追问 2:列举几个 MyBatis 的核心组件,说说分别干啥用? -------------------------------------------------------------------------------------------- | 组件名称 | 功能 | | --- | --- | | SqlSession | MyBatis 工作的主要顶层 API,用于`和数据库交互的会话,完成必要数据库增删改查功能` | | Executor | MyBatis 执行器,是 MyBatis 调度的核心,负责`SQL 语句的生成和查询缓存的维护` | | StatementHandler | 封装了 JDBC Statement 操作,负责对 JDBC statement 的操作,如设置参数、将 Statement 结果集转换成 List 集合。 | | ParameterHandler | 负责对用户传递的参数转换成 JDBC Statement 所需要的参数, | | ResultSetHandler | 负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 类型的集合; | | TypeHandler | 负责 java 数据类型和 jdbc 数据类型之间的映射和转换 | | MappedStatement | 维护一条`<select|update|delete|insert>`节点的封装, | | SqlSource | 负责根据用户传递的 parameterObject,`动态生成 SQL 语句`,将信息封装到 BoundSql 对象中,并返回 | | BoundSql | 表示动态生成的 SQL 语句以及相应的参数信息 | | Configuration | MyBatis`所有的配置信息`都维持在 Configuration 对象之中。 | * * * ![在这里插入图片描述](https://static001.geekbang.org/infoq/57/573fe66c5646989bb159828d2863c375.jpeg) 课间休息,又来秀一下来自咱们群里同学的随手拍,坐标:**杭州西湖 断桥残雪**。 作者:`B.A.T.J.M` * * * []( )面试题 2:(问几个实际使用的问题)Mybatis 动态 sql 是做什么的?都有哪些动态 sql? ============================================================================================================ 动态 sql 是指在进行 sql 操作的时候,传入的参数对象或者参数值,根据匹配的条件,有可能需要动态的去判断是否为空、循环、拼接等情况,用于辅助开发者更方便的进行半自动化的 SQL 开发; Mybatis 动态 sql 可以让我们在 Xml 映射文件内,以标签的形式编写动态 sql,完成逻辑判断和动态拼接 sql 的功能。 Mybatis 提供了 9 种动态 sql 标签:`trim`、`where`、`set`、`foreach`、`if`、`choose`、`when`、`otherwise`、`bind`。 其执行原理为,使用 OGNL 从 sql 参数对象中计算表达式的值,根据表达式的值动态拼接 sql,以此来完成动态 sql 的功能。 []( )追问 1:Xml 映射文件中,除了常见的 select|insert|updae|delete 标签之外,你还常用哪些标签? ------------------------------------------------------------------------------------------------------------------------- 用于 Mybatis 的 Mapper 文件中,有很多常见标签如:`<resultMap>`、`<parameterMap>`、`<sql>`、`<include>`、`<namespace>`等等,需要的话可以挨个解释一下其作用。 []( )追问 2:Mybatis 是如何将 sql 执行结果封装为目标对象并返回的?都有哪些映射形式? ---------------------------------------------------------------------------------------------------------- 我们首先要根据代码中实体类和数据表中的列名是否一一对应,如果对应上就可以直接返回。但多字段无法对应的情况怎么返回? 第一种:使用 sql 列的别名功能,将列的别名书写为对象属性名,强行与实体类保持一致,但不方便维护。 第二种:使用`resultMap`标签,逐一定义数据库列名和对象属性名之间的映射关系,处理起来就比较清晰。 <resultMap type="com.xxxx.entity.Task" id="task"> <id column="taskId" property="id"/> <result column="taskName" property="task_name"/> <result column="frequency" property="frequency"/> <result column="updateTime" property="updateTime"/> <result column="description" property="description"/> <result column="modifier" property="modifier"/> <result column="remark" property="remark"/> </resultMap> 有了列名与属性名的映射关系后,Mybatis 通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。 []( )追问 3:MyBatis 中接口绑定你都用过哪几种方式? ----------------------------------------------------------------------------------------- 我们一般通过注解绑定或在 Mapper 中进行绑定: 1. `注解绑定`:在接口的方法上面加上 `@Select`、`@Update`等注解里面包含 Sql 语句来绑定,Sql 语句比较简单的时候,推荐注解绑定。 2. `Mapper 标签绑定`:通过 xml 里面写 SQL 来绑定, 指定 xml 映射文件里面的`namespace 必须为接口类的全路径名,select 标签中的 id 来定义接口名称`,须一一对应。 <mapper namespace="com.xxxxx.dao.TaskDao"> <!-- 查询任务信息 --> <select id="getAllTaskDao" parameterType="int" resultMap="task" > SELECT taskId,taskName,frequency,updateTime,description,modifier,remark from task_info </select> </mapper> []( )追问 4:我们知道 insert 方法总是返回一个 int 值 ,这个值代表的是插入的行数。那我如何获取自动生成的主键(id)值? ---------------------------------------------------------------------------------------------------------------------------- 如果采用自增长策略,自动生成的键值在 insert 方法执行完后可以被设置到传入的参数对象中。 <insert id=”insertUser” usegeneratedkeys=”true” keyproperty=”id”> insert into users_info (id,name) values (null,#{name}) </insert> []( )追问 5:有两个 XML 文件和这个 Dao 建立关系,如何避免冲突? --------------------------------------------------------------------------------------------- 不管有几个 XML 和 Dao 建立关系,只要`保证 namespace+id 唯一即可`。 * * * ![在这里插入图片描述](https://static001.geekbang.org/infoq/a2/a2b9cc06f283ccd5cac91955a855d07f.jpeg) 课间休息,又来秀一下来自咱们群里同学的随手拍,坐标:**新加坡**。 作者:`一半`
评论