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

MyBatis联合查询 - 注解篇

文章目录

  • 前言
  • 数据库表
  • 一对一关联查询
    • 方式一:
    • 方式二:
  • 一对多关联查询
    • 使用@Many注解
  • 多对多关联查询
    • 方式一:
    • 方式二:
  • 总结

前言

在日常开发中,我们经常需要查询多张表的数据,传统的XML配置方式虽然功能强大,但有时候显得比较繁琐。MyBatis的注解方式为我们提供了一种更简洁、更直观的解决方案 - 注解

数据库表

-- 用户表
CREATE TABLE user (id BIGINT PRIMARY KEY,name VARCHAR(50),email VARCHAR(100),dept_id BIGINT
);-- 部门表  
CREATE TABLE department (id BIGINT PRIMARY KEY,dept_name VARCHAR(50),location VARCHAR(100)
);

对应的实体类:

@Data
public class User {private Long id;private String name;private String email;private Long deptId;private Department department; 
}@Data
public class Department {private Long id;private String deptName;private String location;
}

一对一关联查询

方式一:

最常用的方式是直接在SQL中进行关联查询:

@Mapper
public interface UserMapper {@Select("SELECT *" + "FROM user u LEFT JOIN department d ON u.dept_id = d.id " +"WHERE u.id = #{id}")@Results({@Result(property = "id", column = "id"),@Result(property = "name", column = "name"),@Result(property = "email", column = "email"),@Result(property = "deptId", column = "dept_id"),@Result(property = "department.id", column = "dept_id"),@Result(property = "department.deptName", column = "dept_name"),@Result(property = "department.location", column = "location")})User getUserWithDept(Long id);
}

这种方式简单直接,一次查询就能获取所有需要的数据,性能比较好。

方式二:

如果你更喜欢分步查询的方式,可以使用@One注解:

@Mapper
public interface UserMapper {@Select("SELECT * FROM user WHERE id = #{id}")@Results({@Result(property = "id", column = "id"),@Result(property = "name", column = "name"),@Result(property = "email", column = "email"),@Result(property = "deptId", column = "dept_id"),@Result(property = "department", column = "dept_id",one = @One(select = "com.example.mapper.DepartmentMapper.getDeptById"))})User getUserWithDept2(Long id);
}@Mapper
public interface DepartmentMapper {@Select("SELECT * FROM department WHERE id = #{id}")Department getDeptById(Long id);
}

这种方式会执行两次SQL查询,先查用户信息,再根据部门ID查询部门信息。虽然查询次数多了,但逻辑更清晰,复用性也更好。

一对多关联查询

假设我们要查询部门及其下属的所有员工:

@Data
public class Department {private Long id;private String deptName;private String location;private List<User> users; 
}

使用@Many注解

@Mapper
public interface DepartmentMapper {@Select("SELECT * FROM department WHERE id = #{id}")@Results({@Result(property = "id", column = "id"),@Result(property = "deptName", column = "dept_name"),@Result(property = "location", column = "location"),@Result(property = "users", column = "id",many = @Many(select = "com.example.mapper.UserMapper.getUsersByDeptId"))})Department getDeptWithUsers(Long id);
}@Mapper
public interface UserMapper {@Select("SELECT * FROM user WHERE dept_id = #{deptId}")List<User> getUsersByDeptId(Long deptId);
}

多对多关联查询

多对多关系是最复杂的关联关系,通常需要一张中间表来维护关系。我们以用户和角色的关系为例:

-- 角色表
CREATE TABLE role (id BIGINT PRIMARY KEY,role_name VARCHAR(50),description VARCHAR(200)
);-- 用户角色关联表
CREATE TABLE user_role (user_id BIGINT,role_id BIGINT,PRIMARY KEY (user_id, role_id)
);

对应的实体类:

@Data
public class User {private Long id;private String name;private String email;private Long deptId;private Department department;private List<Role> roles; 
}@Data
public class Role {private Long id;private String roleName;private String description;private List<User> users;
}

方式一:

@Mapper
public interface UserMapper {@Select("SELECT * " +"FROM user u " +"LEFT JOIN user_role ur ON u.id = ur.user_id " +"LEFT JOIN role r ON ur.role_id = r.id " +"WHERE u.id = #{userId}")@Results({@Result(property = "id", column = "id"),@Result(property = "name", column = "name"),@Result(property = "email", column = "email"),@Result(property = "roles", column = "id",many = @Many(select = "com.example.mapper.RoleMapper.getRolesByUserId"))})User getUserWithRoles(Long userId);
}@Mapper
public interface RoleMapper {@Select("SELECT r.* FROM role r " +"INNER JOIN user_role ur ON r.id = ur.role_id " +"WHERE ur.user_id = #{userId}")List<Role> getRolesByUserId(Long userId);
}

方式二:

@Mapper
public interface RoleMapper {@Select("SELECT r.id, r.role_name, r.description " +"FROM role r WHERE r.id = #{roleId}")@Results({@Result(property = "id", column = "id"),@Result(property = "roleName", column = "role_name"),@Result(property = "description", column = "description"),@Result(property = "users", column = "id",many = @Many(select = "com.example.mapper.UserMapper.getUsersWithDeptByRoleId"))})Role getRoleWithUsersAndDept(Long roleId);
}@Mapper 
public interface UserMapper {@Select("SELECT * "+"FROM user u " +"INNER JOIN user_role ur ON u.id = ur.user_id " +"LEFT JOIN department d ON u.dept_id = d.id " +"WHERE ur.role_id = #{roleId}")@Results({@Result(property = "id", column = "id"),@Result(property = "name", column = "name"),@Result(property = "email", column = "email"),@Result(property = "deptId", column = "dept_id"),@Result(property = "department.deptName", column = "dept_name"),@Result(property = "department.location", column = "location")})List<User> getUsersWithDeptByRoleId(Long roleId);
}

总结

MyBatis的注解方式为我们提供了灵活的联合查询解决方案。虽然在复杂查询方面可能不如XML配置那样强大,但对于大部分常见场景来说已经足够了。

http://www.dtcms.com/a/322996.html

相关文章:

  • QT系统相关
  • gpt-oss 全量技术解读
  • Alibaba Cloud Linux 3 安装 git
  • 【Spring Boot启动流程底层源码详解】
  • kubectl get node k8s-node01 -o yaml | grep taint -B 5 -A 5
  • 如何理解SA_RESTART”被信号中断的系统调用自动重启“?
  • 腾讯COS云存储入门
  • 笔试——Day33
  • 基于遗传优化的稀疏线阵最优排布算法matlab仿真
  • Java面向对象编程(OOP)全面解析:从基础到实践
  • 关于城市农村创业的一点构想
  • 自动生成视频的AI大模型高效创作指南
  • mac安装node.js
  • 【GPT入门】第41课 Model Scope在线平台部署Llama3
  • Serper注册无反应
  • Numpy基础(通用函数)
  • 游游的数组染色
  • 洛谷 滑动窗口 /【模板】单调队列
  • 揭秘MyBatis核心类MappedStatement
  • Java异常:认识异常、异常的作用、自定义异常
  • ChatGPT 5的编程能力宣传言过其实
  • 97-基于Python的大众点评数据分析预测系统
  • 七、《Serverless架构:按毫秒计费的成本革命》--从新浪AI推理平台50%效能提升看无服务器本质
  • 数据结构——优先级队列(PriorityQueue):一文解决 Top K 问题!
  • 可视化大屏 SDK 数据结构设计:从拖拽组件到最终渲染的全链路
  • 2025-08-09 李沐深度学习13——经典卷积神经网络 (1)
  • 嵌入式知识日常问题记录及用法总结(一)
  • C++2024 年一级
  • Vue3 学习教程,从入门到精通,Vue 3 + Tailwind CSS 全面知识点与案例详解(31)
  • buuctf:inndy_echo、actf_2019_babystack