Mybatis面试知识点总结:
1. 介绍一下Mybatis框架。
答:Mybatis是一个优秀的持久层框架。它和Hibernate一样,对jdbc操作数据库的过程进行了封装。它本来叫iBatis,是apache公司的一个开源项目,但在2010年的时候迁移到了Google公司,并改名为Mybatis。
2. 使用jdbc操作数据库存在的缺点?
答:1.频繁的创建连接和释放资源,造成系统资源浪费。
2.sql语句在代码中硬编码。
3.使用preparedStatement向占位符传参数存在硬编码。
4.对结果集解析存在硬编码。
3. 介绍一下Mybatis的架构。
答:首先加载配置文件,mybatis有两个配置文件:
SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。
(1)通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂
(2)由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
(3)mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
(4)Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。
(5)Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。
(6)Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。
4. mybatis的核心配置文件叫什么?除了核心配置文件,还需要其它的配置文件吗?
答:sqlMapConfig.xml(官方提供的名称)。需要,针对数据库中的每张表都要有一个对应的映射配置文件,如mapper.xml.
5. mybatis的核心配置文件sqlMapConfig.xml和每张表格的映射配置文件之间存在什么关系呢?
答:核心配置文件sqlMapConfig.xml主要用来连接数据库,在命名空间<environments>里面嵌套<environment>标签,在<environment>标签里面配置jdbc事物管理、数据库连接池等。除此之外,在核心配置文件sqlMapConfig.xml中要配置映射配置文件的地址,
代码如下:
<?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> <!-- 引入properties配置文件--> <properties resource="jdbc.properties"/>
<!-- 别名 包以其子包下所有类 头字母大小都行--> <typeAliases> <!-- <typeAlias type="com.itheima.mybatis.pojo.User" alias="User"/> --> <package name="com.itheima.mybatis.pojo"/> </typeAliases>
<!-- 和spring整合后 environments配置将废除 --> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理 --> <transactionManager type="JDBC" /> <!-- 数据库连接池 --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource> </environment> </environments> <!-- Mapper的位置 Mapper.xml 写Sql语句的文件的位置 --> <mappers> <!-- <mapper resource="sqlmap/User.xml" class="" url=""/> --> <!-- <mapper resource="sqlmap/User.xml" class="" url=""/> --> <!-- <mapper class="com.itheima.mybatis.mapper.UserMapper" /> --> <!-- <mapper url="" /> --> <package name="com.itheima.mybatis.mapper"/> </mappers> </configuration> |
注意:如果只使用mybatis时,我们是这样配的,但如果用spring来整合mybatis的话,<environment>标签就不用了,spring框架可以帮助mybatis框架连接数据库。在大多数情况下,映射配置文件也不需要我们来配,我们可以使用逆向工程自动生成,但是逆向工程只针对单表,在一些复杂的情况下满足不了需求,所以对于映射配置文件的配置我们一定要熟稔于心。
6. 当你配置完sqlMapConfig.xml主配置文件和映射配置文件之后,要对数据库进行操作,在测试类中分几步呢?
答:1.加载核心配置文件
2. 创建SqlSessionFactory会话工厂
3. 由SqlSessionFactory会话工厂生成SqlSession会话对象
4. 通过SqlSession对象执行sql语句
代码如下:
@Test public void testMybatis() throws Exception { //加载核心配置文件 String resource = "sqlMapConfig.xml"; InputStream in = Resources.getResourceAsStream(resource); //创建SqlSessionFactory SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in); //创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); //执行Sql语句 User user = sqlSession.selectOne("test.findUserById", 10); System.out.println(user); } |
7.mybatis中,#{}和${}的区别是什么?
答:#{}是sql的参数占位符,Mybatis会将sql中的#{}替换为?号,#{}可以有效防止sql注入,可自动进行java类型和jdbc类型转换。如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}是Properties文件中的变量占位符,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,如果parameterType传输单个简单类型值,${}括号中只能是value。
7. <select>、<insert>等标签中常用的属性有哪些?
答:id 指定名称
parameterType 传入参数的类型
resultType 返回值的类型
8. mybatis和Hibernate的区别?
答:Mybatis和Hibernate框架都是持久层框架,底层封装的都是jdbc。它们的区别是:
Mybatis是一个不完全的ORM框架,需要程序员自己编写Sql语句;Mybatis无法做到数据库无关性,适合对关系数据模型要求不高的软件开发。
Hibernate是一个完全的ORM框架,不需要程序员自己编写Sql语句;Hibernate数据库无关性好,适合于对关系数据模型要求高的软件开发。
Mybatis和Hibernate框架各自都有非常广泛的应用领域,本身并无好坏之分,适合就是最好的。
9. 当实体类中的属性名和表中的字段名不一样,怎么办?
答:两种方法。
1.通过在查询的sql语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。
2.通过<resultMap>来映射字段名和实体类属性名的一一对应的关系(推荐使用)
10. 模糊查询like语句该怎么写?
答:1.在java代码中添加sql通配符
2. 在sql语句中拼接统配符,防sql语句注入。
<select id="findUserByUsername" parameterType="String" resultType="com.itheima.mybatis.pojo.User"> select * from user where username like "%"#{haha}"%" </select> |
11. 最佳实践中,通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
答:这里的Dao接口实际上指的是Mapper接口,Mapper接口和Mapper.xml文件是对应的。
接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement。
Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略
Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。
12. Mybatis是如何进行分页的?分页插件的原理是什么?
答:
13. Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式?
答:第一种是使用<resultMap>标签,逐一定义列名和对象属性名之间的映射关系,第二种是使用sql列的别名功能,将列别名书写为对象属性名。
有了列名和属性名的映射关系后,Mybatis通过反射创建对象,同时使用反射给对象的属性逐一赋值并返回,那些找不到映射关系的属性,是无法完成赋值的。
14. 如何获取自动生成的(主)键值?
答:在向数据库中插入数据时,我们有时会用自增长的方式自动生成,插入完成后只会返回一个int值,这个值代表的是插入的行数。如果我们想获取到这个键值该怎么办呢?Mybatis给我们提供了非常便捷的方式:通过<selectKey>标签,自动生成的键值在insert方法执行完后可以被设置到传入的参数对象中。
代码如下:
<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User"> <selectKey keyProperty="id" resultType="Integer" order="AFTER"> select LAST_INSERT_ID() </selectKey> insert into user (username,birthday,address,sex) values (#{username},#{birthday},#{address},#{sex}) </insert> |
15.使用mybatis开发Dao层时,我们会选择使用Mapper动态代理方式,这种方式只需要写Mapper接口,而不需要写实现类,那么,Mapper接口开发需要遵循什么规范呢?
答:Mapper接口开发需要遵循以下规范:(4大规范)
1、 Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、 Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、 Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、 Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
17.Mapper动态代理生成的动态代理对象到底是调用selectOne还是selectList是根据什么决定的呢?
答:动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。
mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。
18.Mybatis的核心配置文件叫什么名字?
答:sqlMapConfig.xml。
19.sqlMapConfig.xml的配置一般包含哪些内容呢?
答:SqlMapConfig.xml中配置的内容和顺序如下:(顺序不能颠倒)
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
如下:
<?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> <properties resource="jdbc.properties"/> <!-- 别名 包以其子包下所有类 头字母大小都行--> <typeAliases> <!-- <typeAlias type="com.itheima.mybatis.pojo.User" alias="User"/> --> <package name="com.itheima.mybatis.pojo"/> </typeAliases> <!-- 和spring整合后 environments配置将废除 --> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理 --> <transactionManager type="JDBC" /> <!-- 数据库连接池 --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /> <property name="username" value="root" /> <property name="password" value="root" /> </dataSource> </environment> </environments>
<!-- Mapper的位置 Mapper.xml 写Sql语句的文件的位置 --> <mappers> <!-- <mapper resource="sqlmap/User.xml" class="" url=""/> --> <!-- <mapper resource="sqlmap/User.xml" class="" url=""/> --> <!-- <mapper class="com.itheima.mybatis.mapper.UserMapper" /> --> <!-- <mapper url="" /> --> <package name="com.itheima.mybatis.mapper"/> </mappers> </configuration> |
20. parameterType和resultType
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中
21.Mybatis中的输入类型和输出类型分别用什么属性表示?
答:parameterType和resultType。
22.Mybatis中的Mapper接口遵循的四大原则?
答:1.接口的类路径与mapper.xml中的namespace一致
2.接口中的方法名与mapper.xml中的方法名一致
3.接口中的方法的输入参数类型与mapper.xml中的parameterType一致
4.接口中的方法的返回值类型与mapper.xml中的resultType一致
Mybatis中的动态sql
23、Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?
答:Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功。
Mybatis提供了9种动态sql标签if|otherwise|where|foreach|set|trim|choose|when|bind。
其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
24、where标签的作用?
答:where标签可以自动添加where关键字,同时去掉sql语句中的第一个and关键字。
25.一对一、一对多的关联查询?
答:一对一关联查询会用到<association>标签,一对多关联查询会用到<collection>标签。
26、Mybatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?
答:Mybatis动态sql可以让我们在Xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功。
Mybatis提供了9种动态sql标签if|otherwise|where|foreach|set|trim|choose|when|bind。
其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。
27.如何用Spring框架整合Mybatis框架?
答:
1.1.3. 创建SqlMapConfig.xml配置文件
<?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>
</configuration> |
1.1.4. Spring整合mybatis
创建applicationContext-dao.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
<!-- 数据库连接池 --> <!-- 加载配置文件 --> <context:property-placeholder location="classpath:conf/db.properties" /> <!-- 数据库连接池 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="driverClassName" value="${jdbc.driver}" /> <property name="maxActive" value="10" /> <property name="minIdle" value="5" /> </bean> <!-- 让spring管理sqlsessionfactory 使用mybatis和spring整合包中的 --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 数据库连接池 --> <property name="dataSource" ref="dataSource" /> <!-- 加载mybatis的全局配置文件 --> <property name="configLocation" value="classpath:mybatis/SqlMapConfig.xml" /> </bean> <!-- Mapper动态代理开发 扫描--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.e3mall.mapper" /> </bean> </beans> |
db.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/e3mall?characterEncoding=utf-8 jdbc.username=root jdbc.password=root
|
备注:
Druid是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池,包括DBCP、C3P0、BoneCP、Proxool、JBoss DataSource。
Druid已经在阿里巴巴部署了超过600个应用,经过多年多生产环境大规模部署的严苛考验。