1.#{} 和 ${} 区别
- 本质区别
- #{}:预编译、占位符(PreparedStatement)
- ${}:字符串拼接、直接替换
- 是否防SQL注入
- #{}:安全,防SQL注入
- ${}:不安全,会产生注入风险
- 处理字符串
- #{}:自动加单引号
- ${}:不会加引号,纯文本替换
- 使用场景
- #{}:几乎所有参数都有它(where条件、insert值等)
- ${}:只能在不能有占位符的地方,比如:
-
- 表名
-
- 配许字段order by${column}
-
- 关键字(asc/desc)
总结
#{}预编译、安全、自动加引号;${}字符串拼接、不安全、只能由来拼表名/排序字段。
2.MyBatis 优缺点
优点
- SQL手写可控,优化方便,适合复杂查询
- 轻量级,学习成本低,上手快
- 半自动ORM,灵活,不屏蔽SQL细节
- 与Spring整合友好,生态成熟
- 动态SQL方便(if、foreach、choose等)
缺点
- SQL写在XML/注解里,维护量大
- 数据库移植性差(换库要改SQL)
- 简单CRUD也要写SQL,不如JPA省事
- 大型项目XML多,管理麻烦
总结
灵活可控、适合复杂业务、但移植差、简单操作繁琐。
3.MyBatis 一级缓存、二级缓存
一级缓存
- 默认开启,不能关闭
- Sqlsession级别(同一个会话内有效)
- 同参数、同SQL、同会话、查询直接走缓存
- 发生增删改会自动清空缓存
二级缓存
- 默认关闭,需要手动开启
- Mapper级别(跨会话,同一个Mapper namespace共享)
- 多个SQL Session可以共用
- 同样:增删改会清空二级缓存
- 实体类需要实现序列化接口
总结
一级缓存是会话级,默认开;二级缓存是Mapper级,手动开,跨会话共享。
4.MyBatis 怎么处理多表查询
- 手写关联SQL+结果映射
- 直接写join多表查询
- 在里用: :一对一 :一对多
<resultMap id="userMap" type="User">
<id column="id" property="id"/>
<!-- 一对一:用户 → 身份证 -->
<association property="idCard" javaType="IdCard">
<result column="card_no" property="cardNo"/>
</association>
<!-- 一对多:用户 → 多个订单 -->
<collection property="orderList" ofType="Order">
<result column="order_no" property="orderNo"/>
</collection>
</resultMap>
- 分布查询(懒加载)
- 先查主表,再根据外键查子表
- 配置fetchType="lazy"实现懒加载
- 好处:SQL简单,可按需加载
总结
多表查询要么写join配合association/coolection,要么分步骤查询懒加载