
背景扫地僧转眼间你跟我学习有一段时间了Mybatis这块我暂时也没有想出有什么可以教你的了为了巩固这段时间来的所学收获你要试炼一番。小白如何试炼扫地僧我以前面所学所练做成了十八罗汉阵你通过十八罗汉阵就可以认为Mybatis学成了。去试试下面的连环十八罗汉阵吧十八罗汉阵1、通常一个Xml映射文件都会写一个Dao接口与之对应请问这个Dao接口的工作原理是什么Dao接口里的方法参数不同时方法能重载吗 答Dao接口就是人们常说的Mapper接口它一般分四部分接口的全限名是映射文件中的namespace的值接口的方法名是映射文件中MappedStatement的id值接口方法内的参数就是传递给sql的参数parameterType。接口的返回值就是返回类型ResultType或者ResultMap。举例com.mybatis3.mappers.StudentDao.findStudentById可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id findStudentById的MappedStatement。在Mybatis中每一个、、、标签都会被解析为一个MappedStatement对象。Mapper接口是没有实现类的当调用接口方法时接口全限名方法名拼接字符串作为key值可唯一定位一个MappedStatementDao接口里的方法是不能重载的因为是全限名方法名的保存和寻找策略。Dao接口的工作原理是JDK动态代理Mybatis运行时会使用JDK动态代理为Dao接口生成代理proxy对象代理对象proxy会拦截接口方法转而执行MappedStatement所代表的sql然后将sql执行结果返回。2、Mybatis和JDBC有什么不同 答Mybatis是一个封装了JDBC的框架它简化了JDBC的很多复杂步骤可以大大提升操作jdbc的效率。Mybatis的出现让你只需要关注业务的开发底层的jdbc则交给Mybatis即可。3、为什么说Mybatis是半自动ORM映射工具它与全自动Hiberante的区别在哪里 答Hibernate属于全自动ORM映射工具使用Hibernate查询关联对象或者关联集合对象时可以根据对象关系模型直接获取所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时需要手动编写sql来完成所以称之为半自动ORM映射工具。4、#{}和${}的区别是什么答是 P r o p e r t i e s 文件中的变量占位符它可以用于标签属性值和 s q l 内部属于静态文本替换比如 {}是Properties文件中的变量占位符它可以用于标签属性值和sql内部属于静态文本替换比如是Properties文件中的变量占位符它可以用于标签属性值和sql内部属于静态文本替换比如{driver}会被静态替换为com.mysql.jdbc.Driver。#{}是sql的参数占位符Mybatis会将sql中的#{}替换为?号在sql执行前会使用PreparedStatement的参数设置方法按序给sql的?号占位符设置参数值比如ps.setInt(0, parameterValue)#{item.name}的取值方式为使用反射从参数对象中获取item对象的name属性值相当于param.getItem().getName()。5、Mybatis中如何执行批处理Mybatis执行批量插入能返回数据库主键列表吗 答使用BatchExecutor完成批处理。能JDBC都能Mybatis当然也能。6、Mybatis中如何让like查询走索引答Mysql支持前缀索引7、Mybatis如何实现列的动态排序 答使用order by 占位符${sort} ${orderBy}注意此时必须限制传入的参数即需要先做参数校验然后才能使用这些字段。注意使用ordery by 替换符#{sort} #{orderBy}无法完成排序功能原因1. 排序字段是有类型必须满足类型 2.顺序 ASC或者DESC在mysql里是枚举值不能识别字符串。8、大批量并发插入情况下自增主键会不会冲突 答大批量并发插入的情况下自增主键不会冲突只可能会产生空洞这个是mysql的锁机制决定的。9、Mybatis碰到这些特殊字符改怎么处理 答使用配置文件xml时要考虑特殊字符的解析问题。特殊字符的处理有两种方式使用![CDATA[ ]]符号进行说明将此类符号不进行解析特殊字符进行转义处理注意xml版本有xml1.0和xml1.1的不同转义字符也有差异StringEscapeUtils还定义了javaEcmaScript/JavaScriptJSONHTML3HTML4CSV等格式的转移字符处理。10、如何处理Blob/Clob字段不同数据库中对应clob,blob的类型不同在mysql中Clob对应类型为Text,用于存储大量的文本数据Blob对应类型为Blob,用于存储二进制数据常常为图片或音频他们的存储大小如下TINYBLOB,TINYTEXTL 1 bytes, whereL 2^8BLOB,TEXTL 2 bytes, whereL 2^16MEDIUMBLOB,MEDIUMTEXTL 3 bytes, whereL 2^24LONGBLOB,LONGTEXTL 4 bytes, whereL 2^32即TinyBlobTinytext最多存储256个字节blob和text存储不超过64Kb2字节mediumblob和mediumtext存储不超过16MB3字节LongBlob和longtext存储不超过4GB4字节.11、mybatis如何预防sql注入问题 答1.尽量使用预处理替换符#{}尽量避免使用${}替换符2、无法避免使用${}替换符时使用应特别注意能不使用拼接就不要使用拼接这应该也是避免 SQL 注入最基本的原则在使用${}传入变量的时候一定要注意变量的引入和过滤避免直接通过${}传入外部变量。在mybatis-generator自动生成的SQL语句中order by使用的是$也就是简单的字符串拼接这种情况下极易产生SQL注入。需要开发者特别注意。12、Mybatis中多个实体之间存在一对多或者多对多关系怎么实现 答一对多关联查询使用xml配置文件和注解都可以实现一对多关联查询内部实现方式有两种单步使用表JOIN方式多步分开查询使用多对多关联需要借助一个起中介作用的连接表完成。示例学生student和老师teacher的关系一个学生可以拥有多个老师一个老师也可以拥有多个学生他们是多对多的关系。设计数据库表时除了student和teacher表外还会定义一个student_teacher_relation表。这样一个多对多的关联通常可以分拆成两个一对多的关联。13、Mybatis是否支持注解形式如果支持注解可以和xml配置文件方式一起使用吗 答MyBatis 3提供了新的基于注解的配置在MyBatis 3的版本中是支持XML配置和注解一起使用的。虽然Mybatis支持XML配置和注解的方式但对于一些复杂的功能官方推荐使用XML配置原因是XML的一些功能在注解里还没有完全实现比如SQL片段复用。14、Mybatis是否可以映射Enum枚举类 答Mybatis可以映射枚举类不但可以映射枚举类Mybatis可以映射任何对象到表的一列上。映射方式为自定义一个TypeHandler实现TypeHandler的setParameter()和getResult()接口方法。TypeHandler有两个作用一是完成从javaType至jdbcType的转换二是完成jdbcType至javaType的转换体现为setParameter()和getResult()两个方法分别代表设置sql问号占位符参数和获取列查询结果。15、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的功能。16、Mybatis是如何进行分页的分页插件的原理是什么答Mybatis使用RowBounds对象进行分页它是针对ResultSet结果集执行的内存分页而非物理分页可以在sql内直接书写带有物理分页的参数来完成物理分页功能也可以使用分页插件来完成物理分页。分页插件的基本原理是使用Mybatis提供的插件接口实现自定义插件在插件的拦截方法内拦截待执行的sql然后重写sql根据dialect方言添加对应的物理分页语句和物理分页参数。举例select * from student拦截sql后重写为select t.* from select * from studentt limit 01017、简述Mybatis的插件运行原理以及如何编写一个插件。答Mybatis仅可以编写针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口的插件Mybatis使用JDK的动态代理为需要拦截的接口生成代理对象以实现接口方法拦截功能每当执行这4种接口对象的方法时就会进入拦截方法具体就是InvocationHandler的invoke()方法当然只会拦截那些你指定需要拦截的方法。实现Mybatis的Interceptor接口并复写intercept()方法然后在给插件编写注解指定要拦截哪一个接口的哪些方法即可记住别忘了在配置文件中配置你编写的插件。18、mybatis什么时候要用到一级缓存一级缓存会碰到什么问题什么时候要用到二级缓存二级缓存会碰到什么问题 答Mybatis对缓存提供支持但是在没有配置的默认情况下它只开启一级缓存且缓存级别为SqlSession。在参数和SQL完全一样的情况下我们使用同一个SqlSession对象调用一个Mapper方法往往只执行一次SQL因为使用SelSession第一次查询后MyBatis会将其放在缓存中以后再查询的时候如果没有声明需要刷新并且缓存没有超时的情况下SqlSession都会取出当前缓存的数据而不会再次发送SQL到数据库。默认情况下二级缓存是不开启的开启需要配置一级二级缓存的总开关的设置为 默认开启。默认配置一级缓存的生命周期在一个session内生效超过这个就不会生效了。也可以配置为STATEMENT级别。对于数据变化频率很大并且需要高时效准确性的数据要求我们使用SqlSession查询的时候要控制好SqlSession的生存时间SqlSession的生存时间越长它其中缓存的数据有可能就越旧从而造成和真实数据库的误差同时对于这种情况用户也可以手动地适时清空SqlSession中的缓存防止查询过大导致内存溢出若内存过大则可以通过配合第三方的二级缓存。Mybatis提供了二级缓存机制二级缓存是Application级别可以让session共享缓存。二级缓存只要有两种形式一种方式是使用本地缓存适用于应用仅部署一个当应用部署多个时存在不能保证缓存的一致性问题另外一种形式是使用第三方缓存系统将缓存数据存储到第三方可以保证整个系统的缓存是一致的。不管是一级缓存还是二级缓存使用都要非常谨慎。对于极少修改的数据可以使用缓存而对于频繁修改的数据则禁用缓存。后续小白关于Mybatis的专栏已经结束了谢谢朋友们的陪伴。后续小白关于springspring bootspring cloud及微服务的系列专栏也逐渐完成请喜欢小白专栏的朋友继续支持延伸阅读与资源Java 工程师进阶从 JVM 生产排障到OpenJDK原理NumPy 从入门到生产落地全链路实战指南科学计算/向量化Redis 8 实战精讲从 CRUD 到源码构建高可用缓存系统Redis 实战修炼与原理进阶Python 3实战精进从脚本到高并发订单引擎python入门Rquests从菜鸟脚本到企业级SDK的网络实战圣经Milvus向量数据库实战修炼从 0 到 1精通向量检索与生产落地MongoDB 实战进阶与内核修炼后端工程师的 AI 转型第一课Ollama 与私有化大模型实战10倍开发者的 Dify 魔法书从零构建全栈 AI 应用后端工程师转型AI第一课-Ollama 与私有化大模型实战大型语言模型(LLM) vLLM 高性能推理落地实战Agent开发之LlamaIndex 实战修炼与源码进阶大语言模型Transformers 实战修炼与源码剖析