1. #{} 和 ${} 的区别
{}是properties中的变量占位符,,可以用于标签属性值和SQL内部,属于静态文本替换
- ${driver}会被com.mysql.jdbc.Driver替换
{}是SQL的参数占位符,mybatis会将SQL中的#{}替换为?
是预编译处理,能有效防止SQL注入,提高系统安全性
- $是字符串替换,一般用于传入数据库对象(表名)
2. xml映射文件中的标签有哪些
常见标签
select、insert、update、delete
代码片段标签
sql
结果映射标签
resultMap
缓存标签
cache
动态SQL标签
if:判断标签
choose、when、otherwise:类似java switch
trim、where、set:where整合标签
foreach:循环标签
bind:创建变量标签
3. 通常xml映射文件都会有一个Mapper接口与之对应,这个Mapper接口的工作原理是什么?Mapper接口中的方法,参数不同方法会重载吗?
Mapper接口的全限定名是映射文件中namespace的值,
接口方法就是映射文件中MappedStatement的id值,
接口方法内的参数就是传递给SQL的参数
Mapper接口是没有实现类的,当调用接口方法时,接口全限定名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement findStudentById,可唯一找到namespace为SudentMapper下的 findStudentById的MappedStatement
在mybatis中每一个select、insert、update、delete标签都会分解为MappedStatement对象
Dao接口里的方法不能重载,因为是全限名+方法名的保存和寻找策略
Mapper接口的工作原理是JDK动态代理,Mybatis运行时会 使用jdk动态代理为Dao接口 生成proxy对象
黛米对象proxy会拦截接口方法,转而执行Map碰到Statement所代表的SQL,然后SQL执行结果返回
4. Mybatis执行批量插入,能返回数据库主键课表吗
jdbc能,mybatis也能
- 对于支持生成自增主键的数据库:在insert标签属性增加useGenerateKeys和KeyProperty
- 不支持生成自增主键的数据库使用selectKey
```xml
insert into Author (username, password, email, bio) values (#{item.username}, #{item.password}, #{item.email}, #{item.bio})
INSERT INTO
(relation_id, summary_id, relation_type)
VALUES
(
#{shopResource.relationId}, #{shopResource.summaryId}, #{shopResource.relationType}
)
<a name="cbfaE"></a>
## 5. Mybatis是否支持延迟加载?如果支持它是什么原理
Mybatis仅支持association关联对象和collection关联集合对象的延迟加载,association指的就是一对一,collection指的就是一对多查询。<br />在Mybatis配置文件中,可以配置是否启用延迟加载lazyLoadingEnabled=true|false。
原理是使用CGLIB创建目标对象的代理,当调用目标方法时,拦截器invoke()方法将关联对象的子查询SQL保存起来,在调用子查询时再调用子查询SQL语句
<a name="qnq40"></a>
## 6. mybatis 的xml映射文件中,不同的xml映射文件,id是否相同
不同的xml映射文件如果配置了namespace,那么id就能重复。<br />如果没有配置namespace,id就不能重复<br />当调用映射文件时,在有namespace的情况下,会以namespace+id的形式进行调用,就算id重复也不会有事。当没有namespace时,只剩下id,出现重复id会出现数据互相覆盖的情况
<a name="yRS7J"></a>
## 7. Mybatis映射文件中,如果A标签通过include引用了B标签的内容,请问,B标签能否定义在A标签的后面,还是说必须定义在A标签的前面?
mybatis解析xml映射文件是按照顺序进行解析的,但b标签可以仍然可以定义在任何地方,mybatis都能解析正确<br />因为mybatis会先解析a标签的内容,当遇见b标签会先标记为未解析状态,然后继续解析其他内容。当解析完所有标签时,mybatis会重新再解析那些被标记为未解析状态的标签
<a name="LY2Sr"></a>
## 8. 实体类中的属性名和表中的字段名不一样 ,怎么办 ?
```xml
1. 可以通过AS将表中的字段修改成与属性名相同的名字
<select id=”selectorder” parametertype=”int” resultetype=”me.gacl.domain.order”>
select order_id id, order_no orderno ,order_price price
form orders where order_id=#{id};
</select>
2. 通过resultMap来映射关联表字段名和实体类属性名
9.Mybatis都有哪些Executor执行器?它们之间的区别是什么?
mybatis有三个基础的executor执行器:SimpleExecutor、ReuseExecutor、BatchExecutor
SimpleExecutor:每次使用一次update或select就会开启一个statement对象,用完立刻关闭
ReuseExecutor:执行update或select,以SQL作为key查找Statement对象,存在就使用,不存在就创建。
用完不关闭Statement,而是放到Map
BatchExecutor:执行update时,将所有SQL添加到批处理中,等待统一执行,没有select
10. 一级缓存和二级缓存
一级缓存:基于PerpetualCache的HashMap本地缓存,其存储作用域为Session,
当Session Flush或close后该Session中的所有Cache就将清空,默认开启一级缓存
二级缓存:与一级缓存系统,不同之处在于存储域为Mapper(Namespace)中,并可自定义存储源。
默认不打开二级缓存,打开二级缓存需要时实现serializable序列化接口
11.使用mybatis的Mapper接口调用时有哪些要求?
- Mapper接口方法名和mapper.xml中定义的每个SQL的id相同
- Mapper接口方法的输入参数类型和Mapper.xml中定义的每个SQL的parameterType类型相同
- Mapper接口方法输出参数类型和Mapper.xml中定义的每个SQL的resultType的类型相同
- mapper.xml文件中的namespace即使Mapper接口的类路径