1请写出Mybatis核心配置文件MyBatis-config.xml的内容?

  1. <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
  2.  
  3. <!--加载我们需要的properties文件 获取连接四要素-->
    <properties resource="jdbc.properties"/>
  4.  
  5. <settings>
    <!-- 全局性地启用或禁用延迟加载。当禁用时,所有关联的配置都会立即加载。 -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!--当启用后,一个有延迟加载属性的对象的任何一个延迟属性被加载时,该对象
    的所有的属性都会被加载。否则,所有属性都是按需加载。 -->
    <setting name="aggressiveLazyLoading" value="false"/>
    <!--全局关闭2级缓存 -->
    <!--<setting name="cacheEnabled" value="false"/>-->
  6.  
  7. </settings>
  8.  
  9. <!--创建类的别名-->
    <typeAliases>
    <!--只要是在mapper.xml文件中使用了cn.pb.bean包下面的任意类的时候,无需再用全类名
    使用简写的类名
    之前应该 cn.pb.bean.Student
    现在 Student
    -->
    <package name="cn.pb.bean"/>
    </typeAliases>
  10.  
  11. <!--设置mybatis运行环境 default默认的运行环境====environment id的属性值-->
    <environments default="mysql">
    <environment id="mysql">
    <!--配置事务管理器-->
    <transactionManager type="JDBC"></transactionManager>
    <!--配置数据源 POOLED:mybatis自带的数据源-->
    <dataSource type="POOLED">
    <property name="driver" value="${jdbc.driver}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    </dataSource>
    </environment>
    </environments>
  12.  
  13. <!--配置需要的mapper文件-->
    <mappers>
    <mapper resource="mapper/StudentMapper.xml"/>
    </mappers>
    </configuration>

2请写出Mybatis框架的优缺点?

优点:

1. 易于上手和掌握。

2. sql写在xml里,便于统一管理和优化。

3. 解除sql与程序代码的耦合。

4. 提供映射标签,支持对象与数据库的orm字段关系映射

5. 提供对象关系映射标签,支持对象关系组建维护

6. 提供xml标签,支持编写动态sql。

缺点:

1. sql工作量很大,尤其是字段多、关联表多时,更是如此。

2. sql依赖于数据库,导致数据库移植性差。

3. 由于xml里标签id必须唯一,导致DAO中方法不支持方法重载。

4. 字段映射标签和对象关系映射标签仅仅是对映射关系的描述,具体实现仍然依赖于sql。(比如配置了一对多Collection标签,如果sql里没有join子表或查询子表的话,查询后返回的对象是不具备对象关系的,即Collection的对象为null)

5. DAO层过于简单,对象组装的工作量较大。

6.  不支持级联更新、级联删除。

7. 编写动态sql时,不方便调试,尤其逻辑复杂时。

8 提供的写动态sql的xml标签功能简单(连struts都比不上),编写动态sql仍然受限,且可读性低。

9. 若不查询主键字段,容易造成查询出的对象有“覆盖”现象。

10. 参数的数据类型支持不完善。(如参数为Date类型时,容易报没有get、set方法,需在参数上加@param)

11. 多参数时,使用不方便,功能不够强大。(目前支持的方法有map、对象、注解@param以及默认采用012索引位的方式)

12. 缓存使用不当,容易产生脏数据。

总结:

mybatis的优点其实也是mybatis的缺点,正因为mybatis使用简单,数据的可靠性、完整性的瓶颈便更多依赖于程序员对sql的使用水平上了。sql写在xml里,虽然方便了修改、优化和统一浏览,但可读性很低,调试也非常困难,也非常受限,无法像jdbc那样在代码里根据逻辑实现复杂动态sql拼接。mybatis简单看就是提供了字段映射和对象关系映射的jdbc,省去了数据赋值到对象的步骤而已,除此以外并无太多作为,不要把它想象成hibernate那样强大,简单小巧易用上手,方便浏览修改sql就是它最大的优点了。

mybatis适用于小型且程序员能力较低的项目和人群使用,对于中大型项目来说我并不推荐使用,如果觉得hibernate效率低的话(实际上也是使用不当所致,hibernate是实际上是不适用于拥有高负载的工程项目),还不如直接用spring提供的jdbc简单框架(Template),同样支持对象映射。

3.什么是数据持久化以及ORM?

01.数据持久化的概念
  数据持久化就是将内在中的数据模型转换为存储模型,以及将存储模型转换为内在中的数据模型的统称,数据模型可以是任何数据结构或对象模型,例如JavaBean对象;存储模型可以是关系型数据库表,XML文件,二进制文件等.
02.什么是ORM
  ORM(Object/Relational Mapping)中文翻译为对象/关系型数据映射,它也可以理解为一种数据持久化技术,其主要是把对象模型,例如JavaBean对象和关系型数据库的表建立对应关系,并且提供了一个通过JavaBean对象去操作数据库表的机制.
03.使用ORM技术的好处
  在实际开发中,程序员使用面向对象的技术操作数据,而当要把数据存储起来时,使用的却是关系型数据库,这样就造成了很多的不便,ORM在对象模型和关系数据库的表之间建立了一座桥梁,有了它,程序员就不需要再使用SQL语句操作数据库中的表,直接操作JavaBean对象就可以实现数据的存储,查询,更改和删除等操作,Hibernate就是这样一种技术.

4请写出MybatisUtil工具类

  1. package cn.pb.util;
  2.  
  3. import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  4.  
  5. import java.io.IOException;
    import java.io.InputStream;
  6.  
  7. public class SessionFactoryUtil {
    //01.创建需要单例的对象实例
    private static SqlSessionFactory sessionFactory;
  8.  
  9. //02.私有化构造
    private SessionFactoryUtil(){}
  10.  
  11. /**
    * 03.对外提供访问的接口
    * 001.SqlSession的创建依赖SqlSessionFactory
    * 002.SqlSessionFactory依赖于SqlSessionFactoryBuilder
    * 003.SqlSessionFactoryBuilder依赖于配置文件
    * 004.获取配置文件
    */
    public static synchronized SqlSession getSession(){
    //给我一个文件 返回一个输入流 到 内存中
    try {
    InputStream stream = Resources.getResourceAsStream("mybatis.xml");
    //判断SqlSessionFactory是否为空
    if (sessionFactory==null){
    sessionFactory=new SqlSessionFactoryBuilder().build(stream);
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    /**
    * 之前还需要写一个finally用来关闭流! 现在不需要 为什么不需要??
    * 01.查询源码build(stream)
    * 02.SqlSessionFactoryBuilder类中已经关闭reader.close()
    * 03.所以我们如果关闭流 会报错!
    */
    return sessionFactory.openSession(); //创建session返回
    }
    }

5.请使用association节点实现根据用户id查询用户信息以及对应角色信息(Role实体类中有一个对象User,只写SQL映射文件)?

  1. <!-- 01. 根据角色id 查询出角色信息-->
    <select id="selectRoleById" resultMap="roleMap">
    select id,name,userid from role where id=#{xxx}
    </select>
  2.  
  3. <!-- 02. 根据角色表中查询结果中的userid 查询用户信息
    xxx就是resultmap中传递来的 userid-->
    <select id="selectUserByUserId" resultType="User">
    select userid,name from user where userid=#{xxx}
    </select>
  4.  
  5. <!--对应的roleMap 这种方式 推荐使用 因为使用延迟加载-->
    <resultMap id="rolrMap" type="Role">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <!-- Role有一个属性的类型是 user 域属性
    javaType:域属性对应的类型 -->
    <association property="user" javaType="User" select="selectUserByUserId"
    column="userid"/>
    </resultMap>

6.请使用collection节点实现获取指定用户的相关信息和地址列表(User实体类中有一个复杂类型的Address集合,只写SQL映射文件)?

  1. <!-- 01. 根据用户id 查询出用户信息-->
    <select id="selectUserById" resultMap="userMap">
    select id,name from user where id=#{xxx}
    </select>
  2.  
  3. <!-- 02. 根据用户表中查询结果中的userid 查询地址信息
    xxx就是resultmap中传递来的 userid-->
    <select id="selectAddressByUserId" resultType="Address">
    select id,name,userid from address where userid=#{xxx}
    </select>
  4.  
  5. <!--对应的userMap 这种方式 推荐使用 因为使用延迟加载-->
    <resultMap id="userMap" type="User">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <!-- User有一个属性的类型是 list
    javaType:域属性对应的类型 -->
    <collection property="addresses" javaType="Address" select="selectAddressByUserId"
    column="userid"/>
    </resultMap>

7.MyBatis的一级缓存缓存的是什么,二级缓存缓存的是什么?

mybatis的一级缓存:
  MyBatis会在表示会话的SqlSession对象中建立一个简单的缓存,将每次查询到的结果结果缓存起来,
当下次查询的时候,如果判断先前有个完全一样的查询,会直接从缓存中直接将结果取出,返回给用户,
不需要再进行一次数据库查询了。

  MyBatis会在一次会话的表示----一个SqlSession对象中创建一个本地缓存(local cache),
对于每一次查询,都会尝试根据查询的条件去本地缓存中查找是否在缓存中,如果在缓存中,
就直接从缓存中取出,然后返回给用户;否则,从数据库读取数据,将查询结果存入缓存并返回给用户。

  一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个(内存区域)数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。

  一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。当一个sqlSession结束后该sqlSession中的一级缓存也就不存在了。Mybatis默认开启一级缓存。

  二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession去操作数据库得到数据会存在二级缓存区域,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

  二级缓存是多个SqlSession共享的,其作用域是mapper的同一个namespace,不同的sqlSession两次执行相同namespace下的sql语句且向sql中传递参数也相同即最终执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次会从缓存中获取数据将不再从数据库查询,从而提高查询效率。Mybatis默认没有开启二级缓存需要在setting全局参数中配置开启二级缓存。

如果缓存中有数据就不用从数据库中获取,大大提高系统性能。

8.如何开启MyBatis的二级缓存?

一个项目中肯定会存在很多共用的查询数据,对于这一部分的数据,没必要

每一个用户访问时都去查询数据库,因此配置二级缓存将是非常必要的。

Mybatis的二级缓存配置相当容易,要开启二级缓存,只需要在你的Mapper映射文件中添加一行:

<cache />

配置完<cache/>表示该mapper映射文件中,所有的select语句都将被缓存,所有的insert、update和delete语句都将刷新缓存。但是实际中,我们并不是希望这样,有些select不想被缓存时,可以添加select的属性useCache=“false”;有些insert、update和delete不想让他刷新缓存时,添加属性flushCache=”false ”。

9.请根据商品名称(模糊查询),供应商,以及是否付款进行多条件查询和分页(只写SQL映射文件)

10.#{}和${}的区别是什么?

01.$ 不安全 底层实现是Statement对象

select * from student where id=${id}

如果我们id传入的是11 编译之后

select * from student where id=11

# 安全 底层实现是PreparedStatement对象

select * from student where id=#{id}

如果我们id传入的是11 编译之后

select * from student where id=?

MyBatis启用了预编译功能,在SQL执行前,会先将上面的SQL发送给数据库进行编译;

执行时,如果传入参数为#{}格式的,将传入参数替换编译好的sql中的占位符“?”;

如果传入参数格式为${},则直接使用编译好的SQL就可以了。

因为SQL注入只能对编译过程起作用,所以使用#{}传入参数的方式可以很好地避免了SQL注入的问题。

02.在sql语句需要排序的时候

order by ${id}

只有在需要排序的时候 使用$

其他时候能用#绝对不用$。

MyBatis笔试题的更多相关文章

  1. Java 工程师面试题和笔试题整理(一)

    根据自己之前收集的还有一部分自己面试的整理出来,希望能帮到面试的兄弟(2017). 海科融通 笔试题 1.有一个字符串,如果要在其中查找一个子串,都有哪些方式,写出你认为最好的一个. 2.写出线程都有 ...

  2. JAVA 150道笔试题知识点整理

    JAVA 笔试题 整理了几天才整理的题目,都是在笔试或者面试碰到的,好好理解消化下,对你会有帮助,祝你找工作顺利,收到满意的 offer . 1.Java 基础知识 1.1 Java SE 语法 &a ...

  3. 对Thoughtworks的有趣笔试题实践

    记得2014年在网上看到Thoughtworks的一道笔试题,当时觉得挺有意思,但是没动手去写.这几天又在网上看到了,于是我抽了一点时间写了下,我把程序运行的结果跟网上的答案对了一下,应该是对的,但是 ...

  4. 从阿里巴巴笔试题看Java加载顺序

    一.阿里巴巴笔试题: public class T implements Cloneable { public static int k = 0; public static T t1 = new T ...

  5. 我设计的ASP.NET笔试题,你会多少呢

    本笔试题考查范围包括面向对象基础.HTML.CSS.JS.EF.jQuery.SQL.编码思想.算法等范围. 第1题:接口和抽象类有何区别? 第2题:静态方法和实例方法有何区别? 第3题:什么是多态? ...

  6. C#经典笔试题-获取字符串中相同的字符以及其个数

    public Dictionary<char,int> GetStrSameAs(string str){ //将字符串转换成一个字符数组. char[] charArray=str.To ...

  7. flhs笔试题-回家上机实践

    这是最近参加的一个公司的笔试题,回家上机写了下代码,希望对有需要的小伙伴有用,简单实现字符串和数组在指定位置的插入: package org.flhs; import com.google.commo ...

  8. 也许你需要点实用的-Web前端笔试题

    之前发的一篇博客里没有附上答案,现在有空整理了下发出来,希望能帮助到正在找工作的你,还是那句话:技术只有自己真正理解了才是自己的东西,共勉. Web前端笔试题 Html+css 1.对WEB标准以及w ...

  9. [c#基础]关于try...catch最常见的笔试题

    引言 在翻看之前总结的常见面试题中,关于try...catch异常处理的还是蛮多了,今天看到这个面试题,也就重新学习一下. try..catch语法 try-catch语句由一个try块后跟一个或多个 ...

随机推荐

  1. 浅谈session,cookie,sessionStorage,localStorage的区别及应用场景

    浏览器的缓存机制提供了可以将用户数据存储在客户端上的方式,可以利用cookie,session等跟服务端进行数据交互. 一.cookie和session cookie和session都是用来跟踪浏览器 ...

  2. Netbeans文件被误删怎么办?

    辛辛苦苦写的代码突然不见了,上午还是有的,哪去了?怎么办? 破解办法: 1,良好的版本管理工具(git||svn)使用习惯,代码每天上传更新,技术文件有丢失,也就一天的. 2,Netbeans提供的备 ...

  3. 两种简单的方法Docker构建LANMP

    在初步入门学习Docker的过程中一步步了解了Docker容器在团队开发中所起到的作用,一边学习一边操作基本命令,当然到现在还处于一个擦边的入门阶段. 尝试一下用Docker构建一个集成开发环境. S ...

  4. RGB与HSV之间的转换公式及颜色表

    RGB & HSV 英文全称 RGB - Red, Green, Blue HSV - Hue, Saturation, Value HSV --> RGB 转换公式 HSV --> ...

  5. POJ - 1733 Parity game 种类并查集+离散化

    思路:d(i, j)表示区间(i, j]的1的个数的奇偶性.输入最多共有5000*2个点,需要离散化处理一下.剩下的就是并查集判冲突. AC代码 #include <cstdio> #in ...

  6. Python接口自动化测试 HTTP协议

    一.HTTP协议简述 二.URL 三.请求 四.响应 五.消息报头 六.常见问题

  7. 模板语言变量,js变量,js自执行函数之前嵌套调用

    1.模板语言变量 前端html页面中展示 {{ nodeIp }} 2.js变量引用模板语言变量 把模板语言变量传递给js,js去执行页面操作(变量的转换,只适用于字符串) var IP = &quo ...

  8. Ubuntu 11.04安装arm-linux-gcc-4.4.3/arm-none-linux-gnueabi-gcc安装包

    准备工具和系统 arm-linux-gcc-4.4.3.tar.gz arm-linux-gcc-4.4.3下载地址: 下载在Linux公社的1号FTP服务器里,下载地址: FTP地址:ftp://w ...

  9. 获取NVIDIA显卡的温度

    NVIDIA显卡在硬件上有温度传感器,可以感知显卡的运行环境.温度数据的获取,一般是通过调用NVIDIA的SDK的相关函数即可.SDK的下载的网址(https://developer.nvidia.c ...

  10. hi3531芯片的标识寄存器

    芯片的标识寄存器 0xee0.0xee4.0xee8.0xeec(基址是0x2005_0000) 系统控制器提供了芯片标识(ID)寄存器SC_SYSID.这个标识寄存器是一个概念上 的32bit 的标 ...