MyBatis

  • #{} 和 ${} 的区别是什么?
    • ${} 是 Properties 文件中的变量占位符,可以用于标签属性值和 sql 内部,属于静态文本替换,相当于前后进行了字符串拼接
    • {} 是 sql 的参数占位符,MyBatis 会将 sql 中的 #{} 替换为 ? 号,在 sql 执行前使用 PreparedStatment 来设置参数,按顺序给 sql 中的 ? 号设置参数值

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

    resultMap(数据库字段映射)、sql、include、selectKey 和动态 sql 标签: if、where、set、foreach、trim、choose、when(这三个是多条件判断,相当于 if/else if)、otherwise等

  • Dao 接口的工作原理是什么?Dao 接口中的方法参数不同时,方法能重载吗?

    项目中,通常一个 xml 映射文件,就会写一个 Dao 接口来对应。Dao 接口也就是 Mapper 接口,接口的全限名映射的就是文件中的 namespace 值,接口的方法名映射的就是文件中 MappedStatement 的 id 值,接口方法的参数就是传递 sql 的参数。Mapper 接口没有实现类,当调用接口方法的时候,接口全限名 + 方法名拼接字符串作为 key,可以定位一个 MappedStatment。每一个增删改查的标签都会被解析为一个 MappedStatment 对象【比如 com.mhn.mapper. StudentDao.findStudentById,就是找 namespace 为 com.mhn.mapper. StudentDao 下面 id = findStudentById 的 MappedStatement】Dao 接口里的方法可以重载,但映射的 xml 中 ID 是不可重复的

  • MyBatis 是如何进行分页的?分页插件的原理是什么?
    • MyBatis 使用 RowBounds 对象进行分页,是根据 ResultSet 结果集进行的逻辑分页。也可以在 sql 直接写物理分页的参数来完成物理分页。也可以使用分页插件来完成物理分页
    • 分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截执行的 sql,然后重写 sql
  • MyBatis 是如何吧 sql 执行结果封装为目标对象返回的?都有哪些映射方式?

    第一种使用 resultMap 标签,逐个定义列名与对象属性名之间的映射关系。第二种使用 sql 别名的功能,设置别名与对象属性名对应。存在列名和属性名的映射关系后,MyBatis 通过反射创建对象,同时使用反射给对象的属性逐个赋值并返回

  • MyBatis 是否支持延迟加载?如果支持,实现原理是什么?

    MyBatis 只支持 assocation(一对一)关联对象和 collection(一对多)关联集合对象的延迟加载,可以通过配置文件 lazyLoadingEnableed = true/false 来开启关闭延迟加载

    原理是,使用 CGLIB 创建目标的代理对象,当调用目标方法的时候,进入拦截器方法,比如调用了 a.getB().getName(),拦截器发现 a.getB() 是 null 值,那么就会单独发送保存好的查询关联 B 对象的 sql,吧 B 查询出来,然后调用 a.setB(b),这样 a 对象的 b 属性就存在值了,然后再完成 a.getB().getName() 方法的调用

  • 延迟加载是什么?作用是什么?

    为了提高数据库查询性能,尽量使用单表查询,因为单表查询要比多表查询更快,一开始先查询单表,当需要关联信息,再进行关联查询就叫做延迟加载

  • MyBatis 的 xml 映射文件中,不同的 xml 映射文件,id 是否可以重复?

    不同的 xml 映射文件,如果配置了 namespace 那么 id 可以重复,如果没有配置 namespace 那么 id 不能重复。

  • MyBatis 映射文件中,如果 A 标签通过了 include 引用了 B 标签的内容,那么 B 标签能否定义在 A 标签后面,还是必须定义在 A 标签的前面?

    虽然解析 xml 映射文件是按照顺序解析的,但被引用的 B 标签依然可以定义在任何地方,MyBatis 都可以正确识别。因为 MyBatis 解析 A 标签,发现 A 标签引用了 B 标签,但是 B 标签还没被解析到,那么会吧 A 标签标记为未解析状态,继续解析剩下的标签包含 B 标签,当所有标签解析完以后,会重新解析被标记未解析状态的标签,这时候再解析 A 标签的时候,B 标签就已经存在,A 标签也就可以正常解析了

  • 为什么说 MyBatis 是半自动的?与全自动的区别在哪儿?

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

results matching ""

    No results matching ""