Mybatis面试题
resultType 和 resultMap 的区别?
- resultType 是标签的一个属性,适合简单对象(POJO、JDK 自带类型: Integer、String、Map 等),只能自动映射,适合单表简单查询。
<select id="selectAuthor" parameterType="int" resultType="com.gupaoedu.domain.Author">
select author_id authorId, author_name authorName from author where author_id = #{authorId}
</select>
- resultMap 是一个可以被引用的标签,适合复杂对象,可指定映射关系,适合关联 复合查询
<resultMap id="BlogWithAuthorResultMap" type="com.gupaoedu.domain.associate.BlogAndAuthor">
<id column="bid" property="bid" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/> <!-- 联合查询,将 author 的属性映射到 ResultMap -->
<association property="author" javaType="com.gupaoedu.domain.Author">
<id column="author_id" property="authorId"/>
<result column="author_name" property="authorName"/>
</association>
</resultMap>
collection 和 association 的区别?
- association:一对一
<!-- 另一种联合查询(一对一)的实现,但是这种方式有“N+1”的问题 -->
<resultMap id="BlogWithAuthorQueryMap" type="com.gupaoedu.domain.associate.BlogAndAuthor">
<id column="bid" property="bid" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<association property="author" javaType="com.gupaoedu.domain.Author" column="author_id" select="selectAuthor"/> <!-- selectAuthor 定义在下面 -->
</resultMap>
- collection:一对多、多对多
<!-- 查询文章带评论的结果(一对多) -->
<resultMap id="BlogWithCommentMap" type="com.gupaoedu.domain.associate.BlogAndComment" extends="BaseResultMap" >
<collection property="comment" ofType="com.gupaoedu.domain.Comment">
<id column="comment_id" property="commentId" />
<result column="content" property="content" />
</collection>
</resultMap>
<!-- 按作者查询文章评论的结果(多对多) -->
<resultMap id="AuthorWithBlogMap" type="com.gupaoedu.domain.associate.AuthorAndBlog" >
<id column="author_id" property="authorId" jdbcType="INTEGER"/>
<result column="author_name" property="authorName" jdbcType="VARCHAR"/> <collection property="blog" ofType="com.gupaoedu.domain.associate.BlogAndComment">
<id column="bid" property="bid" />
<result column="name" property="name" />
<result column="author_id" property="authorId" />
<collection property="comment" ofType="com.gupaoedu.domain.Comment">
<id column="comment_id" property="commentId" />
<result column="content" property="content" />
</collection>
</collection>
</resultMap>
PrepareStatement 和 Statement 的区别?
- 两个都是接口,PrepareStatement 是继承自 Statement 的;
- Statement 处理静态 SQL,PreparedStatement 主要用于执行带参数的语句;
- PreparedStatement 的 addBatch()方法一次性发送多个查询给数据库;
- PS 相似 SQL 只编译一次(对语句进行了缓存,相当于一个函数),减少编译次 数;
- PS 可以防止 SQL 注入;
- MyBatis 默认值:PreparedStatement
MyBatis 解决了什么问题?或:为什么要用 MyBatis?或:MyBatis 的核心特性?
- 资源管理(底层对象封装和支持数据源)
- 结果集自动映射
- SQL与代码的分离,集中管理
- 参数映射和动态SQL
- 缓存、插件等
MyBatis 编程式开发中的核心对象及其作用?
- SqlSessionFactoryBuilder 创建工厂类
- SqlSessionFactory创建会话
- SqlSession提供操作接口
- MapperProxy代理Mapper接口后,用于找到SQL
Java 类型和数据库类型怎么实现相互映射?
通过TypeHandler,例如 Java类型中的String要保存成varchar,就会自动调用相应的Handler。如果没有系统自带的TypeHandler,也可以自定义
SIMPLE/REUSE/BATCH 三种执行器的区别?
- SimpleExecutor使用后直接关闭Statement:closeStatement(stmt);
- ReuseExecutor 放在缓存中,可复用:PrepareStatement——getStatement()
- BatchExecutor 支持复用且可以批量执行 update(),通过 ps.addBatch()实现 handler.batch(stmt);
MyBatis 一级缓存与二级缓存的区别?
- 一级缓存:在同一个会话(session)中共享,默认开启,维护在BaseExecutor中
- 二级缓存:在同一个namespace共享,需要在Mapper.xml中开启,维护在CacheExecutor中。
MyBaits 支持哪些数据源类型?
- UNPOOLED:不带连接池的数据源
- POOLED:带连接池的数据源,在PooledDateSource中维护PooledConnection
- JNDI:使用容器的数据源,比如Tomcat配置了C3P0
- 自定义数据源:实现DataSourceFactory接口,返回DataSource。
关联查询的延迟加载是怎么实现的?
动态代理(JAVASSIST、CGLIB),在创建实体类对象时进行代理,在调用代理对象的相关方法时,触发二次查询。 第一次查询返回的对象 已经不是 以前的对象了,而是代理对象,在代理对象中 对事件和查询进行了封装,所以当调用的时候 触发第二次查询。
MyBatis 翻页的几种方式和区别?
- 逻辑翻页:通过RowBounds对象
- 物理翻页:通过改写SQL语句,可用插件拦截Executor实现。例如:PageHelper
怎么解决表字段变化引起的 MBG 文件变化的问题?
- Mapper继承:自动生成的部分不变,创建接口继承原接口,创建MapperExt.xml。在继承接口和MapperExt.xml中修改
- 通用Mapper:提供支持泛型的通用Mapper接口,传入对象类型。例如:Mybatis-Plus中 有一个基础 BaseMapper ,对基础的增删改查进行了封装,只要传入 相应的 类,就可以根据类生成对应的sql。
解析全局配置文件的时候,做了什么?
- 创建了Configuration,设置Configuration
- 解析Mapper.xml,设置MapperStatement,其中有 Mapper接口类型和SQL语句的映射关系。
没有实现类,MyBatis 的方法是怎么执行的?
MapperProxy代理,代理类的invoke()方法中调用了SqlSession.selectOne()
接口方法和映射器的 statement id 是怎么绑定起来的?
MapperStatement对象中存储了statement和Sql的映射关系