JavaWeb从0到1-DAY11.1-MyBatis入门(ii)

MyBatis入门学习笔记(ii)

一、这一章在讲什么

本章学习 MyBatis 框架的基础用法------如何在 Spring Boot 项目中用 MyBatis 操作 MySQL 数据库。主要讲了两种配置 SQL 的方式:注解方式 (适合简单增删改查)和 XML 映射文件方式 (适合复杂 SQL),以及 application.properties 中 MyBatis 相关的核心配置项。

二、核心概念

1. 注解方式 CRUD

MyBatis 提供了四个常用注解直接在 Mapper 接口上写 SQL:

注解 作用 示例
@Select 查询 @Select("select * from user where id = #{id}")
@Insert 新增 @Insert("insert into user(name, age) values(#{name}, #{age})")
@Update 修改 @Update("update user set name=#{name} where id=#{id}")
@Delete 删除 @Delete("delete from user where id = #{id}")
  • 是什么:把 SQL 直接写在 Java 接口方法上的注解,MyBatis 会自动生成实现类执行 SQL。
  • 为什么引入:避免手写 JDBC 样板代码,一行注解搞定增删改查。
  • 怎么实现:MyBatis 通过 JDK 动态代理,在运行时根据注解中的 SQL 和方法的参数/返回值,自动生成 Mapper 接口的实现对象。
  • 易混淆点 :注解里写的是 SQL 字符串,参数用 #{} 而非 Java 的 + 拼接。

2. #{} 占位符 vs ${} 字符串拼接

  • 是什么:两种在 SQL 中引用 Java 参数的方式。
  • 区别
    • #{}:预编译占位符,SQL 变成 select * from user where id = ?,参数值安全传入,防止 SQL 注入
    • ${}:字符串拼接,直接把参数值拼进 SQL,有 SQL 注入风险
  • 原理#{} 底层走 JDBC 的 PreparedStatement(预编译),${}Statement(字符串拼接)。
  • 易混淆点#{} 只能代替的位置,不能代替表名、列名。

3. DML 语句的返回值

  • 是什么@Update@Delete@Insert 方法返回 int,表示影响了多少行数据
  • 作用:判断操作是否成功------返回 0 说明没删到/没改到,返回 >0 说明生效。
  • 易混淆点 :返回 void 也能执行成功,只是拿不到影响行数。

4. @Param 注解

  • 是什么 :给 Mapper 接口方法的形参起名字,让 #{} 能正确引用。
  • 什么时候必须写:多个参数 + 非 SpringBoot 官方骨架项目。
  • 什么时候可省略:单参数;或 SpringBoot 官方骨架项目(编译时保留参数名)。
  • 建议 :多参数始终写 @Param,代码更清晰。
java 复制代码
@Select("select * from user where username=#{uname} and password=#{pwd}")
User login(@Param("uname") String username, @Param("pwd") String password);

5. XML 映射文件

  • 是什么 :把 SQL 写在 .xml 文件里,与 Java 接口分离。
  • 为什么引入:复杂 SQL(动态条件、多表关联)用 XML 更清晰。
  • 三规则(缺一不可):
规则 说明
同包同名 XML 和 Mapper 接口同一包路径下
namespace XML 的 namespace = Mapper 接口全限定名
id 匹配 XML 中 SQL 标签的 id = 接口方法名
  • 易混淆点resources 下要逐级建文件夹(com/itheima/mapper),不是一个叫 com.itheima.mapper 的文件夹。

6. 注解 vs XML

注解 XML
适用 简单增删改查 复杂 SQL
优点 简洁直观 支持动态 SQL、清晰
缺点 不支持复杂逻辑 配置繁琐

两者可混合使用

7. application.properties 核心配置

properties 复制代码
# 数据源(Druid 连接池)
spring.datasource.url=jdbc:mysql://localhost:3306/web01
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=1234

# SQL 日志(调试必备)
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

# XML 映射文件位置
mybatis.mapper-locations=classpath:mapper/*.xml

# 实体类别名包
mybatis.type-aliases-package=com.itheima.pojo

# 自动驼峰映射(user_name → userName)
mybatis.configuration.map-underscore-to-camel-case=true
配置项 作用
log-impl 打印 SQL 到控制台
mapper-locations 指定 XML 文件路径
type-aliases-package XML 里类名可简写
map-underscore-to-camel-case 自动下划线转驼峰

三、重难点

#{} vs ${} --- 最重要面试题

结论 :永远优先用 #{},只有动态表名/列名等极少数场景才用 ${}

原因#{} 走预编译,参数值被当作"数据"而非"SQL 的一部分",从根本上堵死 SQL 注入。${} 直接把字符串拼进 SQL,攻击者可注入恶意 SQL。

通俗比喻#{} 是银行柜台的防弹玻璃窗口------你递进去的是"数据",柜台里处理;${} 是把陌生人直接放进金库------他可以干任何事。

XML 映射三规则

结论 :三层对应------位置 (同包同名)、身份 (namespace)、方法(id)。

通俗比喻:送快递------地址(同包同名)= 小区,namespace = 楼号,id = 房间号。三层都对才能送到。

四、代码理解

注解方式完整示例

java 复制代码
@Mapper
public interface UserMapper {

    // 查询:多参数 + @Param
    @Select("select * from user where username=#{username} and password=#{password}")
    User findByUsernameAndPassword(@Param("username") String username,
                                   @Param("password") String password);

    // 删除:返回 Integer 判断是否成功
    @Delete("delete from user where id = #{id}")
    Integer deleteById(Integer id);

    // 修改:传对象,自动取属性
    @Update("update user set username=#{username}, password=#{password}, " +
            "name=#{name}, age=#{age} where id=#{id}")
    void update(User user);
}

关键点

  • 多参数用 @Param
  • #{id} 不硬编码,动态传入
  • 传对象时 #{} 写属性名
  • 增删改返回 int 判断影响行数

XML 方式完整示例

UserMapper.java:

java 复制代码
@Mapper
public interface UserMapper {
    List<User> findAll();
}

UserMapper.xml:

xml 复制代码
<mapper namespace="com.itheima.mapper.UserMapper">
    <select id="findAll" resultType="com.itheima.pojo.User">
        select id, username, password, name, age from user
    </select>
</mapper>

五、易错点

  1. SQL 写死值 --- where id = 5 → 应改为 where id = #{id}
  2. 多参数忘了 @Param --- 非官方骨架报错
  3. #{} 里写错名 --- 传对象写属性名,传参数写 @Param
  4. XML 文件夹路径错误 --- resources/com.itheima.mapper → 应为 resources/com/itheima/mapper/
  5. #{}${} 混用 --- 除了动态表名/列名,一律用 #{}
  6. 忘配 mapper-locations --- 用了 XML 但没在 properties 里指定路径

六、记忆口诀

  • 注解三兄弟@Select 查、@Update 改、@Delete
  • #{} vs ${}#{} 防弹玻璃(安全),${} 敞开大门(危险)
  • XML 三规则:同名同包是地址、namespace 是楼号、id 是房间号
  • 返回值 int:增删改后看"动了几行",0 行 = 没效果
  • @Param:一个参数不用管,多个参数起个名
  • 注解 vs XML:简单的用注解,复杂的用 XML------和写文档一个道理

七、应用

  • 登录验证@Select 查用户 → null 则失败
  • 后台管理:列表用 XML(分页搜索),增删改用注解
  • 返回值判断:修改后检查 >0 → 成功;=0 → 用户不存在
  • 日志调试 :开 log-impl,控制台看实际 SQL
  • 驼峰映射create_timecreateTime,开 map-underscore-to-camel-case

八、最终总结

本章核心六个字:"注解 XML 两把刀" 。注解适合简单增删改查,XML 适合复杂 SQL------实际项目混合使用。#{} 是默认选择、安全可靠,${} 只在特殊场景用且严防注入。XML 映射靠三规则精准对应。DML 返回值判断操作是否生效。@Param 帮多参数起名,建议始终写。配置文件开日志、配 XML 路径、开驼峰映射,省去大量麻烦。

相关推荐
day day day ...1 小时前
MyBatis / MyBatis-Plus 动态 SQL 中 OGNL 表达式的常见陷阱与源码分析
java·开发语言·mybatis
biass2 小时前
MyBatis-Plus 实现精准、模糊、批量搜索
mybatis
XiYang-DING5 小时前
【MyBatis】注释方式实现CRUD
mybatis
XiYang-DING5 小时前
【MyBatis】XML方式实现CRUD
xml·mybatis
小饼干在学嘎瓦5 小时前
秒杀场景Redis做预扣减,问题在哪里?
数据库·redis·mybatis
来杯@Java16 小时前
图书管理系统(基于springboot+vue前后端分离的项目)计算机毕业设计java
java·spring boot·spring·vue·毕业设计·mybatis·课程设计
Pluchon1 天前
萌萌技术分享笔记——Java综合项目
java·开发语言·笔记·git·github·mybatis·postman
骄马之死1 天前
MyBatis SqlSession 与缓存机制详解
mysql·mybatis
IronMurphy2 天前
SSM拷打第二讲!!!
java·spring·mybatis