MyBatis常见问题

#{}和${}的区别是什么

  • ${}是Properties文件中的变量占位符,它可以用于标签属性值和sql内部,属于静态文本替换,比如${driver}会被静态替换为com.mysql.jdbc.Driver。${}是字符串替换,Mybatis在处理${}时,就是把${}替换成变量的值
  • #{}是预编译处理,Mybatis在处理时,会将sql中的#{}替换为?,调用PreparedStatement的set方法来赋值,#{}可以有效的防止SQL注入,提高系统安全性

MyBatis都有哪些Executor执行器?它们之间的区别是什么?

MyBatis有三种基本的Executor执行器:

  • SimpleExecutor:没执行一次updata或select,就开启一个statement对象,用完立即关闭Statement对象
  • ReuseExecutor:执行updata或select,以sql作为key查找statement对象,存在就使用,不存在就创建,用完后,不关闭Statement对象,而是放置于Map\内,供下一次使用。简言之,就是重复使用Statement对象。
  • BatchExecutor:执行update,将所有sql都添加到批处理中,等待统一执行,它缓存了多个Statement对象,每个Statement对象都是addBatch()完毕后,等待逐一执行executeBatch()批处理。

Executor这些特点,都严格限制在SqlSession生命周期范围内。

MyBatis中如何指定使用哪一种执行器

在MyBatis配置中,可以指定默认的ExecutorType执行器类型,也可以手动给DefaultSqlSessionFactory的创建sqlSession的方法传递ExecutorType类型参数。

为什么说MyBatis是半自动ORM映射工具?它与全自动的区别在哪里?

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而MyBatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。

XML映射文件中,除了常见的select|insert|update|delete标签之外,还有哪些标签?

例如resultMap、parameterMap、sql、include、selectKey,加上动态sql的9个标签,trim|where|set|foreach|if|choose|when|otherwise|bind等,其中为sql片段标签,通过include标签引入sql片段,selectKey为不支持自增的主键生成策略标签。

最佳实践中,通常一个xml映射文件,都会写一个DAO接口与之对应,DAO接口的工作原理是什么?DAO接口里的方法,参数不同时,方法能重载吗?

DAO接口的工作原理是JDK动态代理,MyBatis运行时会使用JDK动态代理为DAO接口生成代理proxy对象,代理对象proxy会拦截接口方法,转而执行MappedStatement所代表的sql,然后将sql执行结果返回。

DAO接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中namespace的值,接口的方法名,就是映射文件中的MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用方法时,接口名+方法名拼接字符串作为key值,可唯一定位一个MappedStatement。

DAO接口里的方法可以重载,但是Mybatis的XML里面的ID不允许重复。MyBatis的DAO接口可以有多个重载方法,但是多个接口对应的映射必须只有一个,否则启动会报错。

MyBatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?

MyBatis动态sql可以让我们在XML映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,Mybatis提供了9种动态sql标签:trim|where|set|foreach|if|choose|when|otherwise|bind。其执行原理为,使用OGNL从sql参数对象中计算表达式值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。

Donate comment here