前言

创建数据库表(user和message),并插入数据:

  1. CREATE TABLE `user` (
  2. `id` varchar(64) NOT NULL ,
  3. `name` varchar(64) NULL ,
  4. PRIMARY KEY (`id`)
  5. );
  6. CREATE TABLE `info` (
  7. `id` varchar(64) NOT NULL ,
  8. `uid` varchar(64) NULL ,
  9. `msg` varchar(255) NULL ,
  10. PRIMARY KEY (`id`)
  11. );
  12. INSERT INTO `user` (`id`, `name`) VALUES ('1001', 'ahzoo');
  13. INSERT INTO `user` (`id`, `name`) VALUES ('1002', 'ouo');
  14. INSERT INTO `info` (`id`, `uid`, `msg`) VALUES ('2001', '1001', '测试信息');
  15. INSERT INTO `info` (`id`, `uid`, `msg`) VALUES ('2002', '1001', '第二条信息');

再创建两个数据库表(role和user_role),并插入数据,用于多对多操作:

  1. CREATE TABLE `role` (
  2. `id` varchar(64) NOT NULL ,
  3. `name` varchar(64) NULL ,
  4. PRIMARY KEY (`id`)
  5. );
  6. CREATE TABLE `user_role` (
  7. `user_id` varchar(64) NOT NULL ,
  8. `role_id` varchar(64) NOT NULL
  9. );
  10. INSERT INTO `role` (`id`, `name`) VALUES ('3001', '用户');
  11. INSERT INTO `role` (`id`, `name`) VALUES ('3002', '管理员');
  12. INSERT INTO `user_role` (`user_id`, `role_id`) VALUES ('1001', '3001');
  13. INSERT INTO `user_role` (`user_id`, `role_id`) VALUES ('1001', '3002');
  14. INSERT INTO `user_role` (`user_id`, `role_id`) VALUES ('1002', '3002');

创建一个springboot项目,并生成增删改查,快速开始。
项目结构:
image.png
依赖:

  1. <dependencies>
  2. <dependency>
  3. <groupId>mysql</groupId>
  4. <artifactId>mysql-connector-java</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.mybatis.spring.boot</groupId>
  8. <artifactId>mybatis-spring-boot-starter</artifactId>
  9. <version>2.2.2</version>
  10. </dependency>
  11. <dependency>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter</artifactId>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.projectlombok</groupId>
  17. <artifactId>lombok</artifactId>
  18. <optional>true</optional>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-test</artifactId>
  23. <scope>test</scope>
  24. </dependency>
  25. </dependencies>

一对一

一条信息对应一个发送者,查询信息的发送者。
Info实体类中增加User对象,这样在对user和info进行联查时,将User对象一起返回:
entity/Info

  1. import lombok.Data;
  2. @Data
  3. public class Info {
  4. private String id;
  5. private String uid;
  6. private String msg;
  7. // 接收一对一查询到的User对象
  8. private User user;
  9. }

映射文件:
mapper/InfoDao.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.example.demo.mapper.InfoMapper">
  6. <!-- 使用Map对象作为返回结果-->
  7. <select id="selectListToMap" resultType="Map">
  8. SELECT u.id,u.name,i.id,i.uid,i.msg
  9. FROM user u,info i
  10. WHERE u.id=i.uid
  11. </select>
  12. <resultMap id="BaseResultMap" type="com.example.demo.entity.Info">
  13. <id property="id" column="id" jdbcType="VARCHAR"/>
  14. <result property="uid" column="uid" jdbcType="VARCHAR"/>
  15. <result property="msg" column="msg" jdbcType="VARCHAR"/>
  16. <association property="user" javaType="com.example.demo.entity.User">
  17. <!-- 这里为id字段取个别名(user_id),方便与上面的表的id字段进行区分,然后在下面对别名使用AS进行映射即可-->
  18. <id property="id" column="user_id" jdbcType="VARCHAR"/>
  19. <result property="name" column="name" jdbcType="VARCHAR"/>
  20. </association>
  21. </resultMap>
  22. <!-- 使用Info对象作为返回结果-->
  23. <select id="selectListByMap" resultMap="BaseResultMap">
  24. SELECT u.id AS user_id,u.name,i.id,i.uid,i.msg
  25. FROM user u,info i
  26. WHERE u.id=i.uid
  27. </select>
  28. </mapper>

持久层:
mapper/InfoMapper

  1. import com.example.demo.entity.Info;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import java.util.List;
  4. import java.util.Map;
  5. @Mapper
  6. public interface InfoMapper {
  7. List<Map<String,String>> selectListToMap();
  8. List<Info> selectListByMap();
  9. }

测试:
查询目标信息对应的用户信息

  1. import com.example.demo.entity.Info;
  2. import com.example.demo.mapper.InfoMapper;
  3. import org.junit.jupiter.api.Test;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import java.util.List;
  7. import java.util.Map;
  8. @SpringBootTest
  9. class InfoTests {
  10. @Autowired
  11. InfoMapper infoMapper;
  12. /**
  13. * 使用Map对象作为返回结果
  14. */
  15. @Test
  16. public void toGetMapResult(){
  17. List<Map<String, String>> infos = infoMapper.selectListToMap();
  18. infos.forEach(System.out::println);
  19. /*
  20. {msg=测试信息, uid=1001, name=ahzoo, id=1001}
  21. {msg=第二条信息, uid=1001, name=ahzoo, id=1001}
  22. */
  23. }
  24. /**
  25. * 使用Info对象作为返回结果
  26. */
  27. @Test
  28. public void toGetInfoResult(){
  29. List<Info> infos = infoMapper.selectListByMap();
  30. infos.forEach(System.out::println);
  31. /*
  32. Info(id=2001, uid=1001, msg=测试信息, user=User(id=1001, name=ahzoo))
  33. Info(id=2002, uid=1001, msg=第二条信息, user=User(id=1001, name=ahzoo))
  34. */
  35. }
  36. }

image.png

一对多

一个用户可以发送多条信息,查询用户下的所有信息。
User实体类中增加Info的List对象,用于返回查询到的多个Info对象:
entity/User

  1. import lombok.Data;
  2. import java.util.List;
  3. @Data
  4. public class User{
  5. private String id;
  6. private String name;
  7. // 接收一对多查询到的Info对象集合
  8. private List<Info> infos;
  9. }

持久层:
mapper/UserMapper

  1. import com.example.demo.entity.User;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import java.util.List;
  4. @Mapper
  5. public interface UserMapper {
  6. List<User> findAllByMap();
  7. }

映射文件:
mapper/UserMapper.xml

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.example.demo.mapper.UserMapper">
  6. <resultMap id="BaseResultMap" type="com.example.demo.entity.User">
  7. <id property="id" column="id" jdbcType="VARCHAR"/>
  8. <result property="name" column="name" jdbcType="VARCHAR"/>
  9. <!--配置集合信息
  10. property:自定义集合的名称
  11. ofType:集合的数据类型
  12. -->
  13. <collection property="infos" ofType="com.example.demo.entity.Info">
  14. <result property="id" column="info_id" jdbcType="VARCHAR"/>
  15. <result property="uid" column="uid" jdbcType="VARCHAR"/>
  16. <result property="msg" column="msg" jdbcType="VARCHAR"/>
  17. </collection>
  18. </resultMap>
  19. <!-- 查询目标用户所有发布的信息(这里使用左外连接查询) -->
  20. <select id="findAllByMap" resultMap="BaseResultMap">
  21. SELECT u.id,u.name,i.id AS info_id,i.uid,i.msg
  22. FROM user u
  23. LEFT OUTER JOIN info i
  24. ON u.id = i.uid;
  25. </select>
  26. </mapper>

测试:

  1. import com.example.demo.entity.User;
  2. import com.example.demo.mapper.UserMapper;
  3. import org.junit.jupiter.api.Test;
  4. import org.springframework.beans.factory.annotation.Autowired;
  5. import org.springframework.boot.test.context.SpringBootTest;
  6. import java.util.List;
  7. @SpringBootTest
  8. public class UserTests {
  9. @Autowired
  10. UserMapper userMapper;
  11. @Test
  12. public void toGetAll(){
  13. List<User> allByMap = userMapper.findAllByMap();
  14. allByMap.forEach(System.out::println);
  15. /*
  16. User(id=1001, name=ahzoo, infos=[Info(id=2001, uid=1001, msg=测试信息, user=null), Info(id=2002, uid=1001, msg=第二条信息, user=null)])
  17. */
  18. }
  19. }

可以看到所有用户下的所有信息都被查询到

image.png

多对多

一个用户可以有多个角色,一个角色可以属于多个用户,查询用户对应的角色,及角色对应的用户。
User实体类中增加Role的List对象,用于返回查询到的多个Role对象:
entity/User

  1. import lombok.Data;
  2. import java.util.List;
  3. @Data
  4. public class User{
  5. private String id;
  6. private String name;
  7. private List<Role> roles;
  8. }

同理:
entity/Role

  1. import lombok.Data;
  2. import java.util.List;
  3. @Data
  4. public class Role {
  5. private String id;
  6. private String name;
  7. private List<User> users;
  8. }

持久层:
mapper/RoleMapper

  1. import com.example.demo.entity.Role;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import java.util.List;
  4. @Mapper
  5. public interface RoleMapper {
  6. List<Role> getAllUser();
  7. }

mapper/UserMapper

  1. import com.example.demo.entity.User;
  2. import org.apache.ibatis.annotations.Mapper;
  3. import java.util.List;
  4. @Mapper
  5. public interface UserMapper {
  6. List<User> getAllRole();
  7. }

映射文件:
mapper/RoleMapper

  1. <resultMap id="roleMap" type="com.example.demo.entity.Role">
  2. <id property="id" column="id" jdbcType="VARCHAR"/>
  3. <result property="name" column="name" jdbcType="VARCHAR"/>
  4. <collection property="users" ofType="com.example.demo.entity.User">
  5. <result property="id" column="role_id" jdbcType="VARCHAR"/>
  6. <result property="name" column="name" jdbcType="VARCHAR"/>
  7. </collection>
  8. </resultMap>
  9. <select id="getAllUser" resultMap="roleMap">
  10. SELECT u.id,u.name,r.id AS role_id,r.name
  11. FROM user u
  12. LEFT OUTER JOIN user_role ur ON u.id = ur.user_id
  13. LEFT OUTER JOIN role r ON r.id = ur.role_id
  14. </select>

mapper/UserMapper

  1. <resultMap id="userMap" type="com.example.demo.entity.User">
  2. <id property="id" column="id" jdbcType="VARCHAR"/>
  3. <result property="name" column="name" jdbcType="VARCHAR"/>
  4. <collection property="roles" ofType="com.example.demo.entity.Role">
  5. <result property="id" column="role_id" jdbcType="VARCHAR"/>
  6. <result property="name" column="name" jdbcType="VARCHAR"/>
  7. </collection>
  8. </resultMap>
  9. <select id="getAllRole" resultMap="userMap">
  10. SELECT u.id,u.name,r.id AS role_id,r.name
  11. FROM user u
  12. LEFT OUTER JOIN user_role ur ON u.id = ur.user_id
  13. LEFT OUTER JOIN role r ON r.id = ur.role_id
  14. </select>

测试:

  1. @Autowired
  2. RoleMapper roleMapper;
  3. @Autowired
  4. UserMapper userMapper;
  5. @Test
  6. public void toGetAllUser(){
  7. List<Role> allUser = roleMapper.getAllUser();
  8. allUser.forEach(System.out::println);
  9. /*
  10. Role(id=1001, name=ahzoo, users=[User(id=3001, name=ahzoo, roles=null), User(id=3002, name=ahzoo, roles=null)])
  11. Role(id=1002, name=ouo, users=[User(id=null, name=ouo, roles=null)])
  12. */
  13. }
  14. @Test
  15. public void toGetAllRole(){
  16. List<User> allRole = userMapper.getAllRole();
  17. allRole.forEach(System.out::println);
  18. /*
  19. User(id=1001, name=ahzoo, roles=[Role(id=3001, name=ahzoo, users=null), Role(id=3002, name=ahzoo, users=null)])
  20. User(id=1002, name=ouo, roles=[Role(id=null, name=ouo, users=null)])
  21. */
  22. }

image.png
image.png