五、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. powerdesigner自定义实体显示的属性

    我做概要设计的时候需要画实体的逻辑模型图,默认的时候是这样的: 但是我想只保留属性名,隐藏数据类型和下面的横线怎么办?效果如下: 按以下操作即可实现:

  2. 解决etcd集群空间占用问题 mvcc: database space exceeded

    一.查看状态 ./etcdctl --write-out=table endpoint status 可以看到空间占用(DB SIZE).本次是清理过了.原本达到了2G(为默认上限) 二.查看当前版本 ...

  3. cronet 的简单学习

    官方的解释 "Cronet is the networking stack of Chromium put into a library for use on mobile. This is ...

  4. [Android逆向]Exposed 破解 jwxdxnx02.apk

    使用exposed 遇到了一些坑,这里记录一下 源码: package com.example.exposedlesson01; import de.robv.android.xposed.IXpos ...

  5. 2、dubbo原理

    图例说明: 图中左边淡蓝背景的为服务消费方使用的接口,右边淡绿色背景的为服务提供方使用的接口,位于中轴线上的为双方都用到的接口. 图中从下至上分为十层,各层均为单向依赖,右边的黑色箭头代表层之间的依赖 ...

  6. 牛客“迎新春,过大年”多校程序设计竞赛A题

    题目描述: 这里有个小trick 当时也看到数据范围的问题了 \(n是1e6 \quad \sum_{i=1}^na[i]<=5e7\) 我们考虑不同的数\(1 \quad 2 \quad .. ...

  7. [学习笔记].Net5项目打包到Linux系统服务时遇到的坑

    ​如果按照官方文档的步骤手动安装.Net5 会有一个坑: 在 Linux 上手动安装 .NET - .NET | Microsoft Docs 在使用systemd打包.Net5服务的时候,无法运行, ...

  8. git 提交本地仓库 提交错误撤销命令

    git reset --hard HEAD~1

  9. vim没有clipboard,没法复制到系统剪切板,通过xclip将复制、删除的内容放到系统剪切板

    解决方法:在/etc/vim/vimrc 或者 ~/.vimrc 中添加下面的命令 au TextYankPost * exe system("xclip -selection clipbo ...

  10. 关于Java执行Cmd命令出现的死锁问题解决

    原文:关于Java执行Cmd命令出现的死锁问题解决 - Stars-One的杂货小窝 问题 之前研究了Java通过执行cmd命令从而触发Android打包的思路,但是发现Android打包成功之后,后 ...