MyBatis注解

MyBatis 的注解(Annotations)提供了一种简洁的方式来配置 SQL 映射,而无需使用 XML 文件。通过在 Mapper 接口的方法上使用注解,可以直接在 Java 代码中定义 SQL 语句和相关映射。这种方式使得代码更加集中和易于维护,尤其适合简单的 CRUD 操作。

以下是 MyBatis 注解的详细介绍,包括常用注解的说明、使用示例以及与 XML 配置的对比。

1. 常用注解说明

1.1 @Select

用于定义查询操作。

@Select("SELECT * FROM users WHERE id = #{id}")
User selectUserById(int id);

1.2 @Insert

用于定义插入操作。

@Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")
void insertUser(User user);

1.3 @Update

用于定义更新操作。

@Update("UPDATE users SET name=#{name}, email=#{email} WHERE id=#{id}")
void updateUser(User user);

1.4 @Delete

用于定义删除操作。

@Delete("DELETE FROM users WHERE id=#{id}")
void deleteUser(int id);

1.5 @Results@Result

用于定义复杂的结果映射,尤其是当查询结果需要映射到多个表或多个对象时。

@Select("SELECT u.id, u.name, u.email, o.id as order_id, o.amount as order_amount " +"FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.id=#{id}")
@Results({@Result(property = "id", column = "id"),@Result(property = "name", column = "name"),@Result(property = "email", column = "email"),@Result(property = "orders", column = "id", many = @Many(select = "com.example.mapper.OrderMapper.findOrdersByUserId"))
})
User selectUserWithOrders(int id);

1.6 @Param

当方法的参数超过一个时,使用 @Param 注解为参数命名,以便在 SQL 语句中引用。

@Select("SELECT * FROM users WHERE name = #{name} AND email = #{email}")
User selectUserByNameAndEmail(@Param("name") String name, @Param("email") String email);

1.7 @Options

用于配置 SQL 执行的选项,如是否使用缓存、是否刷新缓存、返回主键等。

@Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")
@Options(useGeneratedKeys = true, keyProperty = "id")
void insertUser(User user);

1.8 @SelectProvider, @InsertProvider, @UpdateProvider, @DeleteProvider

用于动态 SQL,允许将 SQL 语句的构建逻辑委托给一个单独的类。

public class UserSqlProvider {public String selectUserById(int id) {return "SELECT * FROM users WHERE id = " + id;}
}public interface UserMapper {@SelectProvider(type = UserSqlProvider.class, method = "selectUserById")User selectUserById(int id);
}

注意:使用 Provider 注解时,SQL 构建逻辑在外部类中,适用于复杂的动态 SQL 场景。

2. 使用示例

以下是一个完整的示例,展示如何在 MyBatis 中使用注解进行 CRUD 操作。

2.1 实体类

public class User {private Integer id;private String name;private String email;// 构造方法public User() {}public User(Integer id, String name, String email) {this.id = id;this.name = name;this.email = email;}// Getter 和 Setter 方法// ...
}

2.2 Mapper 接口

import org.apache.ibatis.annotations.*;import java.util.List;public interface UserMapper {@Select("SELECT * FROM users WHERE id = #{id}")User selectUserById(int id);@Select("SELECT * FROM users")List<User> selectAllUsers();@Insert("INSERT INTO users (name, email) VALUES (#{name}, #{email})")@Options(useGeneratedKeys = true, keyProperty = "id")void insertUser(User user);@Update("UPDATE users SET name=#{name}, email=#{email} WHERE id=#{id}")void updateUser(User user);@Delete("DELETE FROM users WHERE id=#{id}")void deleteUser(int id);
}

2.3 配置 MyBatis

确保在 MyBatis 的配置文件中正确扫描 Mapper 接口。

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC"/><property name="username" value="your_username"/><property name="password" value="your_password"/></dataSource></environment></environments><mappers><mapper class="com.example.mapper.UserMapper"/></mappers>
</configuration>

2.4 使用 Mapper 接口

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;import java.util.List;public class MyBatisAnnotationExample {public static void main(String[] args) {SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory(); // 获取 SqlSessionFactory 实例try (SqlSession session = sqlSessionFactory.openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);// 插入用户User newUser = new User(null, "张三", "zhangsan@example.com");mapper.insertUser(newUser);session.commit();// 查询用户User user = mapper.selectUserById(newUser.getId());System.out.println(user);// 更新用户user.setName("李四");mapper.updateUser(user);session.commit();// 查询所有用户List<User> users = mapper.selectAllUsers();users.forEach(System.out::println);// 删除用户mapper.deleteUser(user.getId());session.commit();} catch (Exception e) {e.printStackTrace();}}
}

3. 注解与 XML 的对比

特性注解XML
可读性代码即配置,易于阅读和维护SQL 与 Java 代码分离,适合复杂 SQL
维护性对于简单操作更易于维护对于复杂 SQL 和动态 SQL 更灵活
动态 SQL 支持有限,需使用 Provider 注解强大,支持复杂的条件判断和循环
复用性较低,难以复用 SQL 片段高,可以通过 <sql> 标签复用 SQL 片段
性能无显著差异无显著差异

选择建议
• 对于简单的 CRUD 操作,推荐使用注解,因其简洁明了。
• 对于复杂的 SQL 语句或需要动态构建 SQL 的场景,推荐使用 XML 配置。

4. 常见问题及解决方案

4.1 参数映射问题

问题:在使用多个参数时,MyBatis 无法正确识别参数名称。

解决方案:使用 @Param 注解为每个参数命名。

@Select("SELECT * FROM users WHERE name = #{name} AND email = #{email}")
User selectUserByNameAndEmail(@Param("name") String name, @Param("email") String email);

4.2 结果映射复杂

问题:当查询结果需要映射到嵌套对象或多个对象时,注解配置复杂。

解决方案:使用 @Results@Result 注解,或者考虑使用 XML 进行更灵活的结果映射。

@Select("SELECT u.id, u.name, u.email, o.id as order_id, o.amount as order_amount " +"FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.id=#{id}")
@Results({@Result(property = "id", column = "id"),@Result(property = "name", column = "name"),@Result(property = "email", column = "email"),@Result(property = "orders", column = "id", many = @Many(select = "com.example.mapper.OrderMapper.findOrdersByUserId"))
})
User selectUserWithOrders(int id);

4.3 动态 SQL 支持不足

问题:注解对动态 SQL 的支持有限,难以处理复杂的条件逻辑。

解决方案:使用 @SelectProviderProvider 注解,将 SQL 构建逻辑委托给外部类;或者使用 XML 配置以获得更强大的动态 SQL 支持。

public class UserSqlProvider {public String selectUserDynamic(@Param("name") String name, @Param("email") String email) {return new SQL() {{SELECT("*");FROM("users");if (name != null) {WHERE("name = #{name}");}if (email != null) {WHERE("email = #{email}");}}}.toString();}
}public interface UserMapper {@SelectProvider(type = UserSqlProvider.class, method = "selectUserDynamic")List<User> selectUsersDynamic(@Param("name") String name, @Param("email") String email);
}

5. 总结

MyBatis 的注解提供了一种简洁、直观的方式来定义 SQL 映射,适用于简单的 CRUD 操作。通过使用 @Select@Insert@Update@Delete 等注解,可以直接在 Mapper 接口中编写 SQL 语句,减少 XML 配置文件的使用,使代码更加集中和易于维护。

然而,对于复杂的 SQL 语句或需要动态构建 SQL 的场景,XML 配置仍然具有优势。因此,在实际项目中,可以根据具体需求灵活选择使用注解或 XML,甚至在同一个项目中结合两者的优点。

如果你在使用过程中遇到具体问题或需要更详细的示例,请随时提问!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34985.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OrioleDB: 新一代PostgreSQL存储引擎

PostgreSQL 12 引入了可插拔式的表存储方法接口&#xff0c;允许为不同的表选择不同的存储机制&#xff0c;例如用于 OLTP 操作的堆表&#xff08;HEAP、默认&#xff09;、用于 OLAP 操作的列式表&#xff08;Citus&#xff09;&#xff0c;以及用于超快速搜索处理的内存表。 …

1.5 Spring Boot项目打包和运行

本文介绍了如何使用Spring Boot进行项目打包和运行。首先&#xff0c;讲解了如何将Spring Boot项目打包为可执行的JAR包&#xff0c;并直接运行&#xff0c;无需部署到外部Web服务器。接着&#xff0c;介绍了如何将项目打包为WAR包&#xff0c;以便部署到Web容器中&#xff0c;…

2.7 滑动窗口专题:串联所有单词的子串

LeetCode 30. 串联所有单词的子串算法对比分析 1. 题目链接 LeetCode 30. 串联所有单词的子串 2. 题目描述 给定一个字符串 s 和一个字符串数组 words&#xff0c;words 中所有单词长度相同。要求找到 s 中所有起始索引&#xff0c;使得从该位置开始的连续子串包含 words 中所…

vue中,watch里,this为undefined的两种解决办法

提示&#xff1a;vue中&#xff0c;watch里&#xff0c;this为undefined的两种解决办法 文章目录 [TOC](文章目录) 前言一、问题二、方法1——使用function函数代替箭头函数()>{}三、方法2——使用that总结 前言 ‌‌‌‌‌尽量使用方法1——使用function函数代替箭头函数()…

uniapp移动端图片比较器组件,仿英伟达官网rtx光追图片比较器功能

组件下载地址&#xff1a;https://ext.dcloud.net.cn/plugin?id22609 已测试h5和微信小程序&#xff0c;理论支持全平台 亮点&#xff1a; 简单易用 使用js计算而不是resize属性&#xff0c;定制化程度更高 组件挂在后可播放指示线动画&#xff0c;提示用户可以拖拽比较图片…

SDL3 游戏开发 Windows 环境搭建

SDL3 游戏开发 Windows 环境搭建 一、准备工作1.1 必备工具与库安装1.1.1 CMake1.1.2 MinGW-w641.1.3 Ninja1.1.4 Git1.1.5 SDL3 及扩展库1.1.6 VSCode 及插件 二、配置VSCode项目并验证环境2.1 创建测试源文件2.2 编写CMakeLists.txt文件和CMakePresets.json2.2.1 使用VSCode的…

【sql靶场】第13、14、17关-post提交报错注入保姆级教程

目录 【sql靶场】第13、14、17关-post提交报错注入保姆级教程 1.知识回顾 1.报错注入深解 2.报错注入格式 3.使用的函数 4.URL 5.核心组成部分 6.数据编码规范 7.请求方法 2.第十三关 1.测试闭合 2.列数测试 3.测试回显 4.爆出数据库名 5.爆出表名 6.爆出字段 …

esxi,vcenter6.0安装指导

前言 esxi6.0安装和esxi6.7步骤基本一样&#xff0c;可参考vmware esxi vcenter6.7安装教程&#xff08;dell&#xff09; 环境依赖以及安装包 esxi6.0安装包vcenter6.0安装不同于6.7&#xff0c;6.5通过导入ova模版安装&#xff0c;需要安装在windows server 2008或者windo…

BigFoot Decursive lua

BigFoot Decursive lua 一键驱散脚本 国际化 ogg语音提示 初始化

2024山东大学计算机复试上机真题

2024山东大学计算机复试上机真题 2024山东大学计算机复试机试真题 历年山东大学计算机复试上机真题 历年山东大学计算机复试机试真题 在线评测&#xff1a;传动门&#xff1a;pgcode.cn 最长递减子序列 题目描述 输入数字 n&#xff0c;和 n 个整数&#xff0c;输出该数字…

【AI News | 20250316】每日AI进展

AI Repos 1、ReActMCP 将网络搜索能力集成到AI助手中的一个MCP服务&#xff1a;ReActMCP Web Search&#xff0c;相当于给AI装了个搜索引擎&#xff0c;可以实时查找最新的内容。它基于Exa API执行基本和高级网络搜索&#xff0c;高级搜索比如限制搜索的网站范围、指定日期范围…

【大模型实战篇】使用GPTQ量化QwQ-32B微调后的推理模型

1. 量化背景 之所以做量化&#xff0c;就是希望在现有的硬件条件下&#xff0c;提升性能。量化能将模型权重从高精度&#xff08;如FP32&#xff09;转换为低精度&#xff08;如INT8/FP16&#xff09;&#xff0c;内存占用可减少50%~75%。低精度运算&#xff08;如INT8&#xf…

Unity 笔记:在EditorWindow中绘制 Sorting Layer

在Unity开发过程中&#xff0c;可能会对旧资源进行批量修改&#xff0c;一个个手动修改费人费事&#xff0c;所以催生出了一堆批量工具。 分享一下在此过程中绘制 Sorting Layer 面板的代码脚本。 示意图&#xff1a; 在 EditorGUI 和 EditorGUILayer 中内置了 SortingLayerF…

idea更新git代码报错No Git Roots

idea更新git代码报错&#xff1a; No Git Roots None of configured Git roots are under Git. The configured directory must have ".git directory in it.但是本地项目里是存在.git文件的&#xff0c;就是突然间不能更新代码了 然后尝试重新拉新项目代码提示: Git i…

失败的面试经历(ʘ̥∧ʘ̥)

一.面向对象的三大特性 1.封装&#xff1a;将对象内部的属性私有化&#xff0c;外部对象不能够直接访问&#xff0c;但是可以提供一些可以使外部对象操作内部属性的方法。 2.继承&#xff1a;类与类之间会有一些相似之处&#xff0c;但也会有一些异处&#xff0c;使得他们与众…

qt加载VeloView工程

接上一篇点云软件配置与编译&#xff0c;使用qt加载需要先完成编译。编译完成后到编译目录下lidarview-superbuild\common-superbuild\lidarview\build 找到CmakeCache.txt&#xff0c;如下是我的编译目录。 使用QT6.5.3加载了CmakeCache.txt&#xff0c;QT5.14还加载不了cmake…

Windows Qt动态监测系统分辨率及缩放比变化

前言 Windows 显示设置中&#xff0c;可以修改缩放比&#xff0c;所有界面和文字会同比例放大或缩小&#xff0c;在开发桌面程序时&#xff0c; 实时监测Qt应用程序在不同缩放比例下的表现&#xff0c;可以及时调整程序界面以适应不同显示屏幕的需求。 正文 本文通过Qt相关…

CVE-2017-5645(使用 docker 搭建)

介绍: 是一个与 Apache Log4j2 相关的安全漏洞,属于远程代码执行,它可能允许攻击者通过构造恶意的日志信息 在目标系统上执行任意代码 Log4j2 介绍 Log4j2 是 Apache 的一个日志记录工具,属于 Java 应用的日志框架,它是 Log4j 的升级版,性能更好,功能更多.它被广泛的适用于 J…

交互式可视化进阶(Plotly Dash构建疫情仪表盘)

这里写目录标题 交互式可视化进阶(Plotly Dash构建疫情仪表盘)1. 引言2. 项目背景与意义3. 数据集生成与介绍4. GPU加速在数据处理中的应用5. 交互式仪表盘构建与Plotly Dash6. PyQt GUI集成与美化7. 工程整体架构8. 部分代码实现9. 代码自查与BUG排查10. 总结与展望交互式可…