MyBatis的一些面试题理解

什么是MyBatis

半自动ORM框架 XML

  1. MyBatis是一个半自动ORM框架
    • 最主要的功能就是为了避免大量的JDBC链接代码的使用,如加载驱动,创建链接,创建statement
  2. 强大的XML文档解析能力
    • 可以通过XML映射数据库记录与model层,无需手动,即可自动获取JDBC结果集并映射到指定model
    • 通过XML还可以统一管理SQL

MyBatis的优点

避免连接代码的重复使用 xml动态拼接SQL SQL统一管理

  1. 无需大量重复冗余的JDBC连接代码
  2. 通过XML映射后,即可自动获取JDBC的结果集,且封装制定model
  3. XML中有还具有强大的动态拼接SQL功能,如我们常见的 标签 </foreach> </if test=""> </SQL>
  4. XML统一管理SQL,避免SQL与程序代码耦合
  5. 与SpringFramework具有很好的继承
  6. 很好的与各种数据库兼容,JDBC支持的MyBatis都支持

MyBatis的缺点

  1. SQL依赖数据库,数据库移植性差
    • 因为是半自动ORM框架 所以还是会手动写一些SQL语句
    • Hibenate全自动ORM框架,无特定SQL书写
  2. 需大量手动SQL编写,对开发人员SQL功底有一定要求
    • 同样因为半自动

MyBatis与Hibernate的区别

  1. 半自动,全自动
  2. 半自动的需要手动写SQL,全自动的无需
    • 当然现在常用的MyBatis-Plus则是全自动ORM,现在也有自动生成常用SQL的能力,应对一般单表需求 ,或简单无需连表查询的多表需求完全不在话下
    • Hibernate同样也有HQL
  3. MyBatis SQL关联性强,不易移植,Hibernate强调SQL无关性,易移植

#{}与${}的区别

#{}是预编译 会转换成?,${}则是字符替换

使用#{}的好处

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

SQL注入是啥

select * from student where id = ${}

${} = “1 or id !=1”

原本只能查出id = 1 的student数据,现在会全部返回,更危险的像使用delete

数据库table字段名与代码中model字段名不同,如何关联

  1. <resultMap id="">
  2. <resultMap property="">

模糊查询

select * from student where name like concat('%', #{name}, '%')

Mapper接口方法能否重载?

不能重载

  • Mapper接口是没有实现类的,他是通过代理模式,根据Mapper+方法名 全限定名,如com.vission.Mapper.xxMapper.findAll; 动态生成proxy类,再执行根据指定namespace的xml对应方法名id里的SQL,如果全限定名重合,无法通过常规的入参变量区分,将无法生成proxy类

MyBatis的Mapper接口使用要求

  1. Mapper接口的方法名 需要与XML每个sql的id相同
  2. Mapper接口的入参需要与parameterType类型一样
  3. Mapper接口的出参需要与resultType类型一样
  4. XML中的namespace为与Mapper接口的类路径

Mapper.xml id能否相同?

同namespace下不能相同

  • MyBatis通过namespact+id关联接口方法,重合了就没法关联了

MyBatis如何分页

  1. 逻辑分页
    • MyBatis自带的RowBouds,全量加载再进行分页查询,JDBC虽然有优化,但是不推荐使用,数据量大的查询会对DB产生压力
  2. 物理分页
    • 直接SQL使用limit关键字
    • 实现MyBatis的Interceptor,全局拦截SQL拼接limit关键字
    • 使用现成框架PageHelper插件分页
    • MyBatis-Plus集成了分页插件IPage

MyBatis将SQL查询结果映射为指定Model

  1. resultMap
  2. SQL as 别名
  3. 找到对应映射关系通过反射实现

MyBatis如何实现批量插入

  1. MyBatis-Plus,重写DefaultSqlInjector,添加InsertBatchSomeColumn,并自定义BaseMapper继承BaseMapper,添加insertBatchSomeColumn方法

  2. MyBatis,批量提交单条插入方法

    sqlsession sqlsession = sqlsessionfactory.opensession(executortype.batch);
    nameMapper Mapper = sqlsession.getMapper(nameMapper.class);
    for (string name: names) {
    	Mapper.insertname(name);
    }
    sqlsession.commit();
    

* insert如何获取自动生成的主键

insert标签方法默认返回插入行数

  • 使用<insert>标签的usegeneratedkeys属性 可以将生成的key设置回入参对象中

  • keyproperty指定赋值属性

<insert id=insert” usegeneratedkeys=true” keyproperty=”id”></insert>

如何再Mapper中传递多个入参

@param

List<String> selectNames(@param("name") name,@param("deleted")deleted);
<select id = 'selectNames'>
	select * from students where name like contact("%",#{name},"%") and deleted = #{deleted}
</select>

MyBatis中XML动态SQL,使用哪些标签

  1. trim

    • prefix 前缀
    • suffix 后缀
    • prefixOverrides 删除前缀
    • suffixOverrides 删除后缀
  2. where

    • 包装where 条件查询的sql主要用于去除多余的and关键字
  3. set

    • 用于update语句替代sql中set关键字
  4. foreach

    • collection 循环的集合
    • item 单条实例
    • separator 分隔填充
    <where>
        <foreach collection="queryList" item="employeeQuery" separator="or">
                <trim prefix="(" suffix=")">
                    <include refid="emp_query_list_condition"/>
                </trim>
        </foreach>
    </where>
    
  5. if

    • test = “”
  6. choose

    • 配合when otherwise使用
  7. when

  8. otherwise

    <choose>
        <when test = ""></when>
        <when test = ""></when>
        <otherwise></otherwise>
    </choose>
    
  9. bind 没用过

常用的MyBatis标签

  1. <resultMap>
  2. <include>
  3. <sql>

MyBatis一对一

<resultMap type="" id = "">
    <id property = "" column = "">
    <result property = "" column = "">
    <association property = "" javaType = "">
        <id property = "" column = "">
        <result property = "" column = "">
    </association>	
</resultMap>

MyBatis一对多

<resultMap type="" id = "">
    <id property = "" column = "">
    <result property = "" column = "">
    <collection property = "" ofType="">
      <id property = "" column = ""/>
      <result property = "" column = ""/>
    </collection>
</resultMap>

MyBatis查询结果能否延迟加载

MyBatis支持association与collection关联查询的延迟加载

  1. 全局

    application.yml => lazyLoadingEnabled = true|false

  2. 局部

    <!--fetchType="lazy" 懒加载策略 fetchType="eager" ⽴即加载策略-->
    <association property="" column="" javaType = "" select = "" fetchType = "lazy|eager"/>
    <collection property="" column = "" ofType = "" select = "" fetchType = "lazy|eager"/>
    

通过代理模式,拦截,当调用model.getXXX(); 则再去DB执行select的方法 几乎所有的包括Hibernate 凡是支持懒加载的原理都是一样的

实际工作中我确实没用过,甚至同事们的代码也没看到过,难道是因为在dao层model查完都会转为DTO返回去

Mapper的使用的方式

  1. 无Spring

    • MyBatis-config.xml

      <Mappers>
      	<Mapper resource="Mapper/XXX.xml"/>
      </Mappers>
      
    • Main.java

      public static void main(){
          InputStream resourceAsStream = Resources.getResourceAsStream("MyBatisConfig.xml");
          SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
          SqlSession sqlSession = sqlSessionFactory.openSession();
          UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
      }
      
  2. Spring

    • 包扫描

      @MapperScan("XXX")
      
    • Main.java

      public static void main(){
          //伪代码 Application.getBean(Mappper.class)
      }
      

MyBatis的接口绑定

  1. XML

    • namespace
  2. 注解

    • @Select
    • @Update
    • @Delect
    • @Insert
    @Select("select * from user where name = #{name}")
    User findUserByName(@Param("name") String name);
    

MyBatis插件实现原理

实现MyBatis的Interceptor接口,通过拦截器全局拼接sql,例如PageHelp就是拼接的limt关键字

MyBatis的缓存机制

不太懂

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值