java面试题之mybatis篇
1,什么是Mybatis?Mybatis的优缺点?
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
JDBC有四个核心对象:
(1)DriverManager,用于注册数据库连接
(2)Connection,与数据库连接对象
(3)Statement/PrepareStatement,操作数据库SQL语句的对象
(4)ResultSet,结果集或一张虚拟表
Mybatis也有四个核心对象:
(1)SqlSession对象,该对象中包含了执行SQL语句的所有方法【1】。类似于JDBC里面的Connection 【2】。
(2)Executor接口,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护。类似于JDBC里面的Statement/PrepareStatement。
(3)MappedStatement对象,该对象是对映射SQL的封装,用于存储要映射的SQL语句的id、参数等信息。
(4)ResultHandler对象,用于对返回的结果进行处理,最终得到自己想要的数据格式或类型。可以自定义返回类型。
优点:
(1)它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。
(2)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。
(3)基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。
(4)能与Spring很好的集成
缺点:
(1)SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。
(2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
2,Mybatis的工作流程
(1)读取配置文件,配置文件包含数据库连接信息和Mapper映射文件或者Mapper包路径。
(2)有了这些信息就能通过SqlSessionFactoryBuilder类的build()方法来创建SqlSessionFactory。SqlSessionFactory的生命周期是程序级,程序运行的时候建立起来,程序结束的时候消亡
(3)再通过调用SqlSessionFactory的openSession()方法产生SqlSession,该对象中包含了执行SQL语句增删改查的所有方法。SqlSession是过程级,一个方法中建立,方法结束应该关闭
(4)创建Executor(执行器)接口,它将根据SqlSession传递的参数动态地生成需要执行的SQL语句,同时负责查询缓存的维护
(5)在Executor接口的执行方法中有一个MappedStatement类型的参数,该参数是对映射信息的封装,用于存储要映射的SQL语句的id、参数等信息
(6)在有了sql语句的映射信息后就会到指定数据库中执行sql语句8
3,#{}和${}的区别是什么?
#{}是预编译处理,${}是字符串替换
Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
Mybatis在处理${}时,就是把${}替换成变量的值。
使用#{}可以有效的防止SQL注入,提高系统安全性。
4,如何解决实体类中的属性名和表中的字段名不一样?
最常用的是ResultMap:
5,接口的动态代理需要满足哪些要求?
(1)namespace必须是接口的全路径名
(2)接口的方法名必须和接口的id一致
(3)接口的入参与parameterType类型一致,返回值与resultType类型一致
6,Mybatis的Xml映射文件中,不同的Xml映射文件,id是否可以重复?
不同的Xml映射文件,如果配置了namespace,那么id可以重复;如果没有配置namespace,那么id不能重复;原因就是namespace+id是作为Map<String, MapperStatement>的key使用的,如果没有namespace,就剩下id,那么,id重复会导致数据互相覆盖。有了namespace,自然id就可以重复,namespace不同,namespace+id自然也就不同。但是,在以前的Mybatis版本的namespace是可选的,不过新版本的namespace已经是必须的了。
7,一对一关联查询和一对多关联查询的实现
一对一关联查询:订单表(Order)是主表,学生表(student)是关联表
定义resultMap,使用associate标签关联一对一关系表
一对多关联查询:学生表(Student)为主表,订单表(Order)为关联表
定义resultMap,使用collection标签关联一对一关系表