13 mybatis 中的关系映射

张创琦 2022.03.13

1 对一关系的映射

  1. sql建表
    多对一关系
  1. 多对一关系的映射
    方式1:通过关联对象打点调用属性的方式
    要求:两表的连接查询
    方式2:直接引用关联对象的Mapper映射
    要求:1、两表的连接查询
    2、关联对象中已经存在被引用的resultMap
    方式3:直接引用关联对象的单独查询的方法
    要求:1、不需要两表的连接查询
    2、关联对象中已经存在被引用的查询方法

代码示例:

  1. 新建实体类 player
  1. package com.kkb.pojo;
  2. public class Player {
  3. private Integer playerId;
  4. private String playerName;
  5. private Integer playerNum;
  6. private Integer teamId;
  7. //多对一的体现:多方持有一方的对象 要有get方法
  8. private Team team1;//关联对象--多个球员可以属于同一个球队;
  9. private Team team2;//关联对象--多个球员可以属于同一个球队.
  10. private Team team3;//关联对象--多个球员可以属于同一个球队;
  11. @Override
  12. public String toString() {
  13. return "Player{" +
  14. "playerId=" + playerId +
  15. ", playerName='" + playerName + '\'' +
  16. ", playerNum=" + playerNum +
  17. ", teamId=" + teamId +
  18. ", team1=" + team1 +
  19. ", team2=" + team2 +
  20. ", team3=" + team3 +
  21. '}';
  22. }
  23. public Integer getPlayerId() {
  24. return playerId;
  25. }
  26. public void setPlayerId(Integer playerId) {
  27. this.playerId = playerId;
  28. }
  29. public String getPlayerName() {
  30. return playerName;
  31. }
  32. public void setPlayerName(String playerName) {
  33. this.playerName = playerName;
  34. }
  35. public Integer getPlayerNum() {
  36. return playerNum;
  37. }
  38. public void setPlayerNum(Integer playerNum) {
  39. this.playerNum = playerNum;
  40. }
  41. public Integer getTeamId() {
  42. return teamId;
  43. }
  44. public void setTeamId(Integer teamId) {
  45. this.teamId = teamId;
  46. }
  47. public Team getTeam1() {
  48. return team1;
  49. }
  50. public void setTeam1(Team team1) {
  51. this.team1 = team1;
  52. }
  53. public Team getTeam2() {
  54. return team2;
  55. }
  56. public void setTeam2(Team team2) {
  57. this.team2 = team2;
  58. }
  59. public Team getTeam3() {
  60. return team3;
  61. }
  62. public void setTeam3(Team team3) {
  63. this.team3 = team3;
  64. }
  65. }
  1. mapper 接口
  1. package com.kkb.mapper;
  2. import com.kkb.pojo.Player;
  3. public interface PlayerMapper {
  4. Player queryById(int playerId);
  5. Player queryById1(int playerId);
  6. Player queryById2(int playerId);
  7. Player queryById3(int playerId);
  8. }
  1. xml 映射文件
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.kkb.mapper.PlayerMapper">
  4. <select id="queryById" resultType="Player">
  5. select * from player where playerId=#{id}
  6. </select>
  7. <select id="queryById1" resultMap="JoinTeamResult1">
  8. select * from player p inner join team t on p.teamId=t.teamId where playerId=#{id}
  9. </select>
  10. <select id="queryById2" resultMap="JoinTeamResult2">
  11. select * from player p inner join team t on p.teamId=t.teamId where playerId=#{id}
  12. </select>
  13. <select id="queryById3" resultMap="JoinTeamResult3">
  14. select * from player where playerId=#{id}
  15. </select>
  16. <resultMap id="baseResultMap" type="com.kkb.pojo.Player">
  17. <id column="playerId" property="playerId"></id>
  18. <result column="playerName" property="playerName"></result>
  19. <result column="playerNum" property="playerNum"></result>
  20. <result column="teamId" property="teamId"></result>
  21. </resultMap>
  22. <!-- 方式1:通过关联对象打点调用属性的方式要求:连接查询
  23. 如果连接查询,一般单独定义resultMap extends="表示继承的其他的resultMap的id"
  24. -->
  25. <resultMap id="JoinTeamResult1" type="Player" extends="baseResultMap">
  26. <id column="teamId" property="team1.teamId"></id>
  27. <result column="teamName" property="team1.teamName"></result>
  28. <result column="location" property="team1.location"></result>
  29. <result column="teamName" property="team1.teamName"></result>
  30. <result column="createTime" property="team1.createTime"></result>
  31. </resultMap>
  32. <!--方式2:直接引用关联对象的Mapper映射:要求连接查询property=" 关 联 对 象 的 属 性 名 " javaType="关联对象的类型"
  33. resultMap="关联对象的命名空间中的resultMap"
  34. -->
  35. <resultMap id="JoinTeamResult2" type="Player" extends="baseResultMap">
  36. <association property="team2" javaType="Team" resultMap="com.kkb.mapper.TeamMapper.baseResultMap"></association>
  37. </resultMap>
  38. <!--方式3:直接引用关联对象的单独查询的方法:要求:关联对象的Maper中必须要求有单独的查询方法property="关联对象的属性名"
  39. javaType="关联对象的类型" select="关联对象的单独查询的语句" column="外键列"
  40. -->
  41. <resultMap id="JoinTeamResult3" type="Player" extends="baseResultMap">
  42. <association property="team3" javaType="Team" select="com.kkb.mapper.TeamMapper.queryById" column="teamId"></association>
  43. </resultMap>
  44. </mapper>
  1. 测试代码
  1. package com.kkb.test;
  2. import com.kkb.mapper.PlayerMapper;
  3. import com.kkb.mapper.TeamMapper;
  4. import com.kkb.pojo.Player;
  5. import com.kkb.pojo.Team;
  6. import com.kkb.utils.MybatisUtil;
  7. import org.junit.Test;
  8. import java.util.List;
  9. /**
  10. *ClassName: TestPlayerMapper
  11. *测试类
  12. *@author wanglina
  13. *@version 1.0
  14. */
  15. public class TestPlayerMapper {
  16. PlayerMapper playerMapper = MybatisUtil.getSqlSession().getMapper(PlayerMapper.class);
  17. // 测试成功
  18. @Test
  19. public void test01() {
  20. Player player = playerMapper.queryById1(1);
  21. System.out.println(player);
  22. }
  23. // 测试成功
  24. @Test
  25. public void test02() {
  26. Player player = playerMapper.queryById2(1);
  27. System.out.println(player);
  28. }
  29. // 测试成功
  30. @Test
  31. public void test03() {
  32. Player player = playerMapper.queryById3(1);
  33. System.out.println(player);
  34. }
  35. }

2 对多关系的映射

代码示例:

  1. 修改Team 实体类
  1. package com.kkb.pojo;
  2. import java.util.Date;
  3. import java.util.List;
  4. public class Team {
  5. private Integer teamId;
  6. private String teamName;
  7. private String location;
  8. private Date createTime;
  9. //一对多的体现:一方持有多方的对象
  10. private List<Player> playerList1;//关联对象--一个球队可以拥有多个球员
  11. private List<Player> playerList2;//关联对象--一个球队可以拥有多个球员
  12. @Override
  13. public String toString() {
  14. return "Team{" +
  15. "teamId=" + teamId +
  16. ", teamName='" + teamName + '\'' +
  17. ", location='" + location + '\'' +
  18. ", createTime=" + createTime +
  19. ", playerList1=" + playerList1 +
  20. ", playerList2=" + playerList2 +
  21. '}';
  22. }
  23. public Integer getTeamId() {
  24. return teamId;
  25. }
  26. public void setTeamId(Integer teamId) {
  27. this.teamId = teamId;
  28. }
  29. public String getTeamName() {
  30. return teamName;
  31. }
  32. public void setTeamName(String teamName) {
  33. this.teamName = teamName;
  34. }
  35. public String getLocation() {
  36. return location;
  37. }
  38. public void setLocation(String location) {
  39. this.location = location;
  40. }
  41. public Date getCreateTime() {
  42. return createTime;
  43. }
  44. public void setCreateTime(Date createTime) {
  45. this.createTime = createTime;
  46. }
  47. public List<Player> getPlayerList1() {
  48. return playerList1;
  49. }
  50. public void setPlayerList1(List<Player> playerList1) {
  51. this.playerList1 = playerList1;
  52. }
  53. public List<Player> getPlayerList2() {
  54. return playerList2;
  55. }
  56. public void setPlayerList2(List<Player> playerList2) {
  57. this.playerList2 = playerList2;
  58. }
  59. }
  1. TeamMapper 中添加方法
  1. public interface TeamMapper {
  2. Team queryById1(int teamId);
  3. Team queryById2(int teamId);
  4. }
  1. PlayerMapper 中添加方法
  1. public interface PlayerMapper {
  2. List<Player> queryByTeamId(int teamId);
  3. }

方式1:连接查询+引用关联对象的结果映射

方式2:引用关联对象的单独查询的方法

TeamMapper.xml 中添加

  1. <select id="queryById1" resultMap="joinResult1">
  2. select * from team t join player p on t.teamId=p.teamId where t.teamId=#{id};
  3. </select>
  4. <select id="queryById2" resultMap="joinResult2">
  5. select * from team where teamId=#{id};
  6. </select>
  7. <!--方式1:
  8. 对多的连接查询:对多使用collection property="关联对象的集合名称" javaType="关联对象的集合类型" ofType="关联对象的集合的泛型" resultMap="引用关联对象的结果映射"
  9. -->
  10. <resultMap id="joinResult1" type="Team" extends="baseResultMap">
  11. <collection property="playerList1" javaType="java.util.ArrayList" ofType="Player" resultMap="com.kkb.mapper.PlayerMapper.baseResultMap"></collection>
  12. </resultMap>
  13. <!--方式2:
  14. 对多的连接查询:对多使用collection property="关联对象的集合名称" javaType="关联对象的集合类型" ofType="关联对象的集合的泛型"
  15. select="引用关联对象的单独查询的方法":使用的前提是关联对象中该方法可用column="引用关联对象的单独查询的方法的参数,一般是外键"
  16. -->
  17. <resultMap id="joinResult2" type="Team" extends="baseResultMap">
  18. <collection property="playerList2" javaType="java.util.ArrayList" select="com.kkb.mapper.PlayerMapper.queryByTeamId" column="teamId"></collection>
  19. </resultMap>

PlayerMapper.xml 中添加

  1. <select id="queryByTeamId" resultType="Player">
  2. select * from player where teamId=#{id}
  3. </select>

TestPlayerMapper.java 中添加

  1. public class TestPlayerMapper {
  2. TeamMapper teamMapper=MybatisUtil.getSqlSession().getMapper(TeamMapper.class);
  3. // 测试成功
  4. @Test
  5. public void test04(){
  6. Team team = teamMapper.queryById1(1025);
  7. System.out.println(team);
  8. }
  9. // 测试成功
  10. @Test
  11. public void test05(){
  12. Team team = teamMapper.queryById2(1025);
  13. System.out.println(team);
  14. }
  15. @Test
  16. public void test01(){
  17. Player player = playerMapper.queryById1(1); System.out.println(player);
  18. }
  19. }