五、MyBatis

40)谈谈 MyBatis

Mybatis 是一个半自动化的 ORM 框架,它对 jdbc 的操作数据库的过程进行封装,使得开发者只需要专注于 SQL 语句本身,而不用去关心注册驱动,创建 connection 等,Mybatis 通过 xml 文件配置或者注解的方式将要执行的各种 statement 配置起来,并通过 java 对象和 statement 中的sql 进行映射成最终执行的 sql 语句,最后由 Mybatis 框架执行 sql 并将结果映射成 java 对象并返回。每个 MyBatis 应用程序主要都是使用 SqlSessionFactory 实例的,一个 SqlSessionFactory 实例可以通过 SqlSessionFactoryBuilder 获得。SqlSessionFactoryBuilder 可以从一个 xml 配置文件或者一个预定义的配置类的实例获得。

Mybatis 分为三层

(1) API 接口层:提供给外部使用的接口 API

(2) 数据处理层:负责具体的 SQL

(3) 基础支撑层:负责最基础的功能支撑,如连接管理,事务管理,配置加载和缓存处。理

41)Mybatis 的优点

  • 基于 SQL 语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL 写在 XML 里,解除 sql 与程序代码的耦合,便于统一管理;提供 XML 标签,支持编写动态 SQL 语句,并可重用。
  • 与 JDBC 相比,减少了 50%以上的代码量,消除了 JDBC 大量冗余的代码,不需要手动开关连接;
  • 很好的与各种数据库兼容(因为 MyBatis 使用 JDBC 来连接数据库,所以只要 JDBC 支持的数据库 MyBatis 都支持)。

    能够与 Spring 很好的集成;
  • 提供映射标签,支持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

42)Mybatis 的优点

  1. Sql 语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写 Sql 语句的功底有一定要求。
  2. 对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis 将是不错的选择。

43)Mybatis 的编程过程是怎样的

  1. 创建 SqlSessionFactory
  2. 通过 SqlSessionFactory 创建 SqlSession
  3. 通过 sqlsession 执行数据库操作
  4. 调用 sqlsession.commit()提交事务
  5. 调用 sqlsession.close()关闭会话

44)Mybatis 中#和$的区别?

  1. ${}是 Properties 文件中的变量占位符,它可以用于标签属性值和 sql 内部,属于静态文本替换

  2. {}是 sql 的参数占位符,Mybatis 会将 sql 中的#{}替换为?号,在 sql 执行前会使用PreparedStatement 的参数设置方法,按序给 sql 的? 号占位符设置参数值。

  3. 方式能够很大程度防止 sql 注入。

    $方式无法防止 Sql 注入。

    $方式一般用于传入数据库对象,例如传入表名。

  4. 为什么 # 可以防止SQL注入?参考作者:https://www.cnblogs.com/coder-who/

    • 1.什么是SQL注入

      答:SQL注入是通过把SQL命令插入到web表单提交或通过页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL指令。

        注入攻击的本质是把用户输入的数据当做代码执行。

        举例如: 表单有两个用户需要填写的表单数据,用户名和密码,如果用户输入admin(用户名),111(密码),若数据库中存在此用户则登录成功。SQL大概是这样

            SELECT * FROM XXX WHERE userName = admin and password = 111

           但若是遭到了SQL注入,输入的数据变为 admin or 1 =1 # 密码随便输入,这时候就直接登录了,SQL大概是这样

            SELECT * FROM XXX WHERE userName = admin or 1 = 1 # and password = 111 ,因为 # 在sql语句中是注释,将后面密码的验证去掉了,而前面的条件中1 = 1始终成立,所以不管密码正确与否,都能登录成功。

      2.mybatis中的#{} 为什么能防止sql注入,${}不能防止sql注入

      答: #{}在mybatis中的底层是运用了PreparedStatement 预编译,传入的参数会以 ? 形式显示,因为sql的输入只有在sql编译的时候起作用,当sql预编译完后,传入的参数就仅仅是参数,不会参与sql语句的生成,而${}则没有使用预编译,传入的参数直接和sql进行拼接,由此会产生sql注入的漏洞。

    • 再次理解sql预编译前后传参数的区别?参考作者:https://blog.csdn.net/weixin_46099269

      • select * from user where uid=#{id} and password=#{pwd};

        这时数据库就会进行预编译,并进行一个缓存动作,缓存一条这样的语句:

        select * from user where uid=? and password=?;

        当我们调用这条语句,并实际向#{id}中的id传了一个值 “deftiii” or 1=1# 时,不需要在编译,数据库会直接找对应的表中有没有名字是 “deftiii” or 1=1# 的用户,而不再有编译sql语句的过程。

45)使用 MyBatis 的 mapper 接口调用时有哪些要求?

  • Mapper接口方法名和 mapper.xml 中定义的每个 sql 的 id 相同
  • Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同
  • Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同
  • Mapper.xml 文件中的 namespace 即是 mapper 接口的类路径。

46)简述 Mybatis 的 Xml 映射文件和 Mybatis 内部数据结构间的映射关系?

  • Mybatis 将所有 Xml 配置信息都封装到 All-In-One 重量级对象 Configuration 内部。
  • 标签会被解析为 ParameterMap 对象,其每个子元素会被解析为ParameterMapping 对象。
  • 标签会被解析为 ResultMap 对象,其每个子元素会被解析为ResultMapping 对象。
  • 每一个 、 、 、 标签均会被解析为MappedStatement 对象,标签内的 sql 会被解析为 BoundSql 对象。

    47)Mybatis 的 Xml 映射文件中,不同的 Xml 映射文件,id 是否可以重复?

    可以!
    不同的 Xml 映射文件,如果配置了 namespace,那么 id 可以重复;如果没有配置 namespace, 那么 id 不能重复。

    48)谈谈Mybatis 缓存

    MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。(缓存的本质就是把你查询过的东西暂时保存一下,如果两次查询都用的同一个session或者是同一个namespace,那么同样的sql语句就不用多次执行了。)
    一级缓存和二级缓存

    默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
    二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
    为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

    一级缓存失效的四种情况

    没有使用到当前的一级缓存,效果就是,还需要再向数据库中发起一次查询请求!sqlSession不同。
    sqlSession相同,查询条件不同

    User user = mapper.queryUserById(1);
    User user2 = mapper2.queryUserById(2);

    sqlSession相同,两次查询之间执行了增删改操作!
    sqlSession相同,手动清除一级缓存

    session.clearCache(); //手动清除缓存

    小结

    只要开启了二级缓存,我们在同一个Mapper中的查询,可以在二级缓存中拿到数据
    查出的数据都会被默认先放在一级缓存中
    只有会话提交或者关闭以后,一级缓存中的数据才会转到二级缓存中

    49)Mybatis 分页

    limit分页

    RowBounds 进行分页,非常方便,不需要在 sql 语句中写 limit,即可完成分页功能。但是由于它是在 sql 查询出所有结果的基础上截取数据的,所以在数据量大的sql中并不适用,它更适合在返回数据结果较少的查询中使用。
    最核心的是在 mapper 接口层,传参时传入 RowBounds(int offset, int limit) 对象,即可完成分页。

    Mybatis分页插件PageHelper

    RowBounds的使用
    mapper 接口层代码如下

    ​ List selectBookByName(Map<String, Object> map, RowBounds rowBounds);
    ​ 调用如下
    ​ List list = bookMapper.selectBookByName(map, new RowBounds(0, 5));
    ​ 原文链接:https://blog.csdn.net/wsjzzcbq/article/details/83447948

    PageHelper的使用
    PageHelper参考自:https://www.jianshu.com/p/50fcd7f127f0
    在service中,先开启分页,然后把查询结果集放入PageInfo中。
    public PageInfo listUserByPage(int pageNum, int pageSize) {
    PageHelper.startPage(pageNum, pageSize);
    List<UserVo> userVoList=userMapper.listUser();
    PageInfo pageInfo=new PageInfo(userVoList);
    return pageInfo;
    }

    ​ PageHelper.startPage(pageNum, pageSize);这句非常重要,这段代码表示分页的开始,意思是从第pageNum页开始,每页显示 pageSize条记录。
    ​ PageInfo这个类是插件里的类,这个类里面的属性会在输出结果中显示,
    使用PageInfo这个类,你需要将查询出来的list放进去

【Java面试题】Mybatis的更多相关文章

  1. java 面试题 mybatis 篇

    1. 一级缓存和二级缓存? 一级缓存策略: 二级缓存策略: 2. 缓存回收策略 LRU –  最近最少使用的:移除最长时间不被使用的对象. FIFO –  先进先出:按对象进入缓存的顺序来移除它们. ...

  2. 最全最新java面试题系列全家桶(带答案)

    最全最新java面试题系列全家桶(带答案) 置顶 2019年04月06日 22:40:28 青春季风暴 阅读数 14082 文章标签: java面试题技术栈 更多 分类专栏: 面试   版权声明:本文 ...

  3. Java面试题全集(上-中-下)及Java面试题集(1-50/51-70)

    阅读量超百万级的文章,收藏并分享一下.感谢原创作者的总结 对初中级java开发人员有特别大的帮助,不论是技术点面试还是知识点总结上. Java面试题全集(上):     https://blog.cs ...

  4. Java面试题之基础篇概览

    Java面试题之基础篇概览 1.一个“.java”源文件中是否可以包含多个类(不是内部类)?有什么限制? 可以有多个类,但只能有一个public的类,且public的类名必须与文件名相一致. 2.Ja ...

  5. 拼多多、饿了么、蚂蚁金服Java面试题大集合

    自己当初找工作时参加过众多一线互联网公司的Java研发面试,这段时间处于寒冬,然而前几天跳槽找工作,两天面了3家,已经拿了两个offer,觉得可以和大家分享下: 下面为拼多多.饿了么.蚂蚁金服.哈啰出 ...

  6. 一些常见的Java面试题 & 面试感悟

    < 前言 > 近期在面试,深感这个行业的浮躁,一些菜不辣基的弱鸡开出的工资待遇要求,超过了我.不知道他们是怎么拿到那么高的工资的,难道是他在公司有亲戚朋友吗?有后台吗?是行业热钱真的过多了 ...

  7. 【面试必备】常见Java面试题大综合

    一.Java基础 1.Arrays.sort实现原理和Collections.sort实现原理答:Collections.sort方法底层会调用Arrays.sort方法,底层实现都是TimeSort ...

  8. 金九银十,史上最强 Java 面试题整理。

    以下会重新整理所有 Java 系列面试题答案.及各大互联网公司的面试经验,会从以下几个方面汇总,本文会长期更新. Java 面试篇 史上最全 Java 面试题,带全部答案 史上最全 69 道 Spri ...

  9. 史上最全阿里 Java 面试题总结

    以下为大家整理了阿里巴巴史上最全的 Java 面试题,涉及大量 Java 面试知识点和相关试题. JAVA基础 JAVA中的几种基本数据类型是什么,各自占用多少字节. String类能被继承吗,为什么 ...

  10. Java面试题全集(下)转载

    Java面试题全集(下)   这部分主要是开源Java EE框架方面的内容,包括hibernate.MyBatis.spring.Spring MVC等,由于Struts 2已经是明日黄花,在这里就不 ...

随机推荐

  1. Linux下SQLPLUS替代工具rlwrap安装使用

    rlwrap工具可以解决linux下sqlplus 提供浏览历史命令行的功能,和删除先前输入错误的字母等问题 1.安装 需要readline包 这个安装光盘就有 [root@asm RedHat]# ...

  2. 服务端高性能网络IO编程模型简析

    服务端高性能网络IO编程模型简析 一.客户端与服务器端 多数网络应用可以分为客户端(client)和服务器端(server)模型,然后中间通过各种定义的协议来进行两端的通信. 比如常用的 Nginx ...

  3. 一次nginx返回422状态码的经历

    故事背景 后端使用Docker Compose部署一个代码片段管理应用:snibox,某天因为云服务卡死重启之后再次访问时,登录或退出都返回422状态码. 界面提示如下: 不过奇怪的是:直接通过IP+ ...

  4. 混合类Mixins介绍

    介绍 混合类是封装了一些通用行为的基类,旨在重用代码.通常,混合类本身并没有什么用,仅扩展这种类也行不通 因为在大多数情况下,它都依赖于其它类中定义的方法和属性.通过多继承,可将混合类与其它类一起使用 ...

  5. 【八股cover#2】CPP语法 Q&A与知识点

    CPP语法 Q&A与知识点 简历cover 1.熟练使用C的指针应用及内存管理 指针与引用的区别 指针是一个存储地址的变量,可以有多级,可以为空,并且在初始化后可以改变指向: 引用是原变量的别 ...

  6. ABP模块签入GitLab后自动打包并推送到ProGet

    # 1.添加一个名为下划线的解决方案文件夹 # 2.把解决方案根目录下的几个必要的文件添加到上述文件夹下 # 3.修改NuGet.Config,添加私有NuGet服务器的网址,并配置用户名和密码: A ...

  7. 【Azure App Service】通过Visual Studio部署Azure App Service 遇见 401 'Unauthorized'错误

    问题描述 最近通过Visual Studio 2022部署Azure App Service的时候,突然遇见了部署失败, 401 Unauthorized错误. 错误消息: Build started ...

  8. 【Azure 应用服务】基于Azure的CI/CD工具链部署App Service

    问题描述 在中国区Azure中,App Service是否支持CI/CD工具部署呢? Windows 和Linux两个系统都是同样的方法吗? 问题解答 目前中国区Azure支持Windows 和 Li ...

  9. C++中OpenCV、Armadillo矩阵数据格式的转换方式

      本文介绍在C++语言中,矩阵库Armadillo的mat.vec格式数据与计算机视觉库OpenCV的Mat格式数据相互转换的方法.   在C++语言的矩阵库Armadillo与计算机视觉库Open ...

  10. 海词 dict.cn 有 词义饼状分布图 和 词性饼状分布图 - 词典推荐

    海词 dict.cn 有 词义饼状分布图 和 词性饼状分布图 http://dict.cn/like