当前位置: 首页 > news >正文

初始MyBatis

MyBatis 核心概念

  • ORM 工具: Object-Relational Mapping (对象关系映射) 工具。
  • 半自动化: 开发者需要手动编写 SQL 和结果映射,MyBatis 负责执行 SQL 并将结果集转换为对象。
  • 轻量级: 框架本身小巧,依赖少,学习曲线相对平缓,易于集成。

Spring Boot 整合 MyBatis 步骤

  1. 添加依赖:

    <dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>{latest-version}</version> <!-- 替换为实际版本号 -->
    </dependency>
    
  2. 配置 (application.yml / application.properties):

    mybatis:# 配置 XML Mapper 文件的位置mapper-locations: classpath:mapper/*.xml# 配置实体类别名所在的包 (可选,简化 XML 中类型写全限定类名)type-aliases-package: com.example.demo.model# 开启驼峰命名自动映射 (数据库下划线字段 -> Java 驼峰属性)configuration:map-underscore-to-camel-case: true
    # 配置数据源 (通常使用 spring.datasource.*)
    spring:datasource:url: jdbc:mysql://localhost:3306/your_db?useSSL=false&serverTimezone=UTCusername: rootpassword: your_passworddriver-class-name: com.mysql.cj.jdbc.Driver
    
  3. 编写 Mapper 接口:

    • 定义数据库操作方法。
    • 在接口上添加 @Mapper 注解,标记该接口为 MyBatis Mapper。
    • (替代方案:) 在启动类上添加 @MapperScan("com.example.demo.mapper") 扫描指定包下的所有 Mapper 接口,避免在每个接口上加 @Mapper
  4. 编写 SQL 映射文件 (Mapper XML):

    • 通常放在 resources/mapper/ 目录下。
    • 文件名建议与 Mapper 接口名一致 (如 UserMapper.xml)。
    • 在 XML 文件中编写动态 SQL (<select>, <insert>, <update>, <delete> 等标签)。
    • 关键: 每个 SQL 语句标签的 id 属性必须与其对应的 Mapper 接口方法名严格一致
  5. 工具推荐 (可选但实用):

    • 安装 MyBatisX 插件 (IDEA/Eclipse),提供强大的 Mapper 接口与 XML 文件间跳转、代码提示、生成等功能。

动态 SQL 参数使用

  • 核心机制: 使用 OGNL (Object-Graph Navigation Language) 表达式,通过反射机制获取参数对象的属性值。
  • 参数传递方式:
    1. 单个参数 (JavaBean 或 Map 类型):
      • 在 XML 中直接通过属性名 (JavaBean) 或键名 (Map) 访问。
      • 示例 (JavaBean): #{propertyName}
      • 示例 (Map): #{key}
    2. 多个参数:
      • 默认方式 (不推荐): MyBatis 会将多个参数放入一个 Map 中,键为 param1, param2, … 或 arg0, arg1, …。在 XML 中使用 #{param1}, #{param2} 等访问。
      • 推荐方式 - @Param 注解: 在 Mapper 接口方法参数前使用 @Param("name") 注解显式指定参数名称。
        User selectUser(@Param("username") String username, @Param("status") Integer status);
        
      • 在 XML 中通过 @Param 指定的名称访问:#{username}, #{status}
  • 重要规则: 如果使用了 @Param 注解指定了参数名,必须在 XML 中使用该指定的名称引用参数。

模型查询示例 (模糊查询)

  • 安全方式 (推荐 - 使用 #{}<bind> 或 CONCAT):

    <!-- 方式1: 使用 <bind> 预拼接 -->
    <select id="findByName" resultType="User"><bind name="nameLike" value="'%' + name + '%'" />SELECT * FROM userWHERE name LIKE #{nameLike}
    </select><!-- 方式2: 使用数据库 CONCAT 函数 (数据库相关) -->
    <select id="findByName" resultType="User">SELECT * FROM userWHERE name LIKE CONCAT('%', #{name}, '%')
    </select>
    
    • 优点: 使用 #{}预编译的,能有效防止 SQL 注入<bind>CONCAT 在 SQL 执行前完成字符串拼接。
  • 不安全方式 (不推荐 - 使用 ${} 直接拼接):

    <select id="findByName" resultType="User">SELECT * FROM userWHERE name LIKE '%${name}%'
    </select>
    
    • 缺点: 使用 ${}字符串替换,直接将参数值嵌入 SQL 语句。如果 name 来自用户输入且未经过滤,存在严重的 SQL 注入风险。应避免使用。

手动映射 (Result Maps)

  1. 类型处理器 (Type Handler):

    • 用于处理 Java 类型和 JDBC 类型之间的转换。
    • MyBatis 内置了常用类型的处理器 (如 String, Integer, Date 等)。
    • 可自定义处理器来处理特殊类型 (如枚举、自定义对象、数据库特定类型如 PostgreSQL 的 jsonb)。
  2. 关联查询 (Result Maps with Associations/Collections):

    • 一对一 (<association>): 表示一个对象嵌套另一个对象。
      <resultMap id="orderWithUserMap" type="Order"><id property="id" column="order_id"/><!-- ... other order columns ... --><association property="user" javaType="User"><id property="id" column="user_id"/><result property="username" column="username"/><!-- ... other user columns ... --></association>
      </resultMap>
      
    • 一对多 (<collection>): 表示一个对象包含一个集合 (通常是另一个对象的列表)。
      <resultMap id="userWithOrdersMap" type="User"><id property="id" column="user_id"/><!-- ... other user columns ... --><collection property="orders" ofType="Order"><id property="id" column="order_id"/><!-- ... other order columns ... --></collection>
      </resultMap>
      

解决 N+1 查询性能问题

关联查询(尤其是一对多)容易引发 N+1 问题(查询主对象 1 次,再查询每个主对象的关联对象 N 次)。MyBatis 提供以下机制优化:

  1. 一级缓存 (SqlSession 级别):

    • 同一个 SqlSession 会话内有效。
    • 执行相同的 SQL 查询(相同的 SQL 语句和参数)时,会直接返回缓存的结果,避免再次访问数据库。
    • 作用范围小:SqlSession 关闭或执行了更新操作(INSERT/UPDATE/DELETE)、调用 clearCache() 或设置了不同的环境,缓存会失效。
      在这里插入图片描述
      在这里插入图片描述
  2. 延迟加载 (懒加载 - Lazy Loading):
    创建实体类的子类,每次在子类上进行操作,所以要加上@JsonIgnoreProperties("handler")来防止子类中的handler无法序列化,导致无法进行网络传输给前端。

    • 核心思想:用到时才加载。查询主对象时,不立即查询其关联对象。只有当代码真正访问关联对象(或集合)的属性时,MyBatis 才发出 SQL 查询加载关联数据。
    • 配置:mybatis.configuration 或全局 <settings> 中开启:
      mybatis:configuration:lazy-loading-enabled: true       # 开启全局延迟加载aggressive-lazy-loading: false   # 禁用"侵略性"延迟加载 (重要)
      
    • 注意: 每次触发关联对象的延迟加载,MyBatis 会使用一个全新的 SqlSession (除非配置了其他拦截机制)。这意味着:
      • 一级缓存无法跨延迟加载的查询生效(因为每次是新会话)。
      • 延迟加载操作需要确保新的 SqlSession 能正确获取(例如在事务管理下或使用 OpenSessionInView 模式 - 后者需谨慎评估)。
  3. 二级缓存 (Application 级别 / Mapper 级别):
    在这里插入图片描述

    • 作用范围比一级缓存大,在整个应用同一个 Mapper 内有效(跨 SqlSession)。
    • 开启步骤:
      1. 全局开关 (通常默认开启): 确保 mybatis.configuration.cache-enabled=true (默认值通常就是 true)。

      2. 序列化支持 (可选但推荐): 如果缓存的对象需要序列化(例如使用分布式缓存),确保它们实现了 Serializable 接口。

      3. Mapper XML 中声明:
        在这里插入图片描述

      4. 缓存行为控制 (在 SQL 标签上):

        • <select> 标签:设置 useCache="true" (默认) 表示该查询结果可存入二级缓存;useCache="false" 表示不缓存。
        • <insert>, <update>, <delete> 标签:执行后会**自动刷新(清空)**其所属 Mapper 的二级缓存 (flushCache="true" 是默认值)。设置为 flushCache="false" 可阻止刷新(慎用,可能导致脏读)。
    • 特点:
      • 作用域大: 数据在整个应用运行期间(或 Mapper 作用域内)有效。
      • 需要管理: 需注意缓存一致性(更新操作会自动刷新对应 Mapper 缓存),以及缓存策略(大小、过期时间等 - 需要集成第三方缓存如 Ehcache, Redis 来实现更复杂策略)。

关于 @RestController

  • @RestController@Controller@ResponseBody 的组合注解。
  • 作用: 标记一个类为 Web 控制器 (Controller)。
  • 关键特性: 该注解下的所有方法默认都添加了 @ResponseBody 注解。这意味着方法的返回值会直接写入 HTTP 响应体中(通常被序列化为 JSON/XML),而不是被解析为视图名称去寻找模板页面。这是构建 RESTful Web 服务的标准方式。
http://www.lryc.cn/news/610980.html

相关文章:

  • LabVIEW 2025 安装攻略(附图文教程)适用于测试与自动控制领域
  • MySQL 查询性能优化与索引失效问题全解析
  • 使用公众号的消息模板给关注用户发消息
  • MySQL CONV()函数
  • spring webflux链路跟踪【traceId日志自动打印】
  • 移动端 WebView 调试实战 深色模式样式失效与主题切换异常排查指南
  • 前端1.0
  • Lua语言程序设计1:基础知识、数值、字符串与表
  • 针对软件定义车载网络的动态服务导向机制
  • linux_https,udp,tcp协议(更新中)
  • 实战项目3-工控软件-2.0- 自定义控件HMILabel的创建
  • 漏洞分析:90分钟安全革命
  • 赛灵思ZYNQ官方文档UG585自学翻译笔记:Quad-SPl Flash 闪存控制器
  • 信息系统项目管理中的沟通管理实战精解
  • 智慧油站误报率↓77%:陌讯多模态融合算法实战解析
  • 【Git】git提交代码报错Git: husky > pre-commit
  • 【Java面试题】注解,异常相关知识
  • 二维数点问题 1
  • Dell电脑Windows系统更新后声卡驱动无法识别插线耳机问题
  • 第13届蓝桥杯Scratch_选拔赛_初级组_真题2022年1月22日
  • leetcode-python-删除链表的倒数第 N 个结点
  • Leetcode 13 java
  • Linux网络编程:TCP初体验
  • 从递归到动态规划-解码方法Ⅱ
  • 【IDEA】IntelliJ IDEA 中文官方文档全面介绍与总结
  • 以Linux为例补充内存管理基础知识
  • 2025年服务器僵尸攻防战:从AI勒索到量子免疫,构建下一代“数字抗体”
  • Linux 常用命令大全
  • 基于vscode连接服务器实现远程开发
  • vi编辑器makefile的使用以及双向链表