13 mybatis 中的关系映射
张创琦 2022.03.13
1 对一关系的映射
- sql建表
多对一关系
- 多对一关系的映射
方式1:通过关联对象打点调用属性的方式
要求:两表的连接查询
方式2:直接引用关联对象的Mapper映射
要求:1、两表的连接查询
2、关联对象中已经存在被引用的resultMap
方式3:直接引用关联对象的单独查询的方法
要求:1、不需要两表的连接查询
2、关联对象中已经存在被引用的查询方法
代码示例:
- 新建实体类 player
package com.kkb.pojo;
public class Player {
private Integer playerId;
private String playerName;
private Integer playerNum;
private Integer teamId;
//多对一的体现:多方持有一方的对象 要有get方法
private Team team1;//关联对象--多个球员可以属于同一个球队;
private Team team2;//关联对象--多个球员可以属于同一个球队.
private Team team3;//关联对象--多个球员可以属于同一个球队;
@Override
public String toString() {
return "Player{" +
"playerId=" + playerId +
", playerName='" + playerName + '\'' +
", playerNum=" + playerNum +
", teamId=" + teamId +
", team1=" + team1 +
", team2=" + team2 +
", team3=" + team3 +
'}';
}
public Integer getPlayerId() {
return playerId;
}
public void setPlayerId(Integer playerId) {
this.playerId = playerId;
}
public String getPlayerName() {
return playerName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
public Integer getPlayerNum() {
return playerNum;
}
public void setPlayerNum(Integer playerNum) {
this.playerNum = playerNum;
}
public Integer getTeamId() {
return teamId;
}
public void setTeamId(Integer teamId) {
this.teamId = teamId;
}
public Team getTeam1() {
return team1;
}
public void setTeam1(Team team1) {
this.team1 = team1;
}
public Team getTeam2() {
return team2;
}
public void setTeam2(Team team2) {
this.team2 = team2;
}
public Team getTeam3() {
return team3;
}
public void setTeam3(Team team3) {
this.team3 = team3;
}
}
- mapper 接口
package com.kkb.mapper;
import com.kkb.pojo.Player;
public interface PlayerMapper {
Player queryById(int playerId);
Player queryById1(int playerId);
Player queryById2(int playerId);
Player queryById3(int playerId);
}
- xml 映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kkb.mapper.PlayerMapper">
<select id="queryById" resultType="Player">
select * from player where playerId=#{id}
</select>
<select id="queryById1" resultMap="JoinTeamResult1">
select * from player p inner join team t on p.teamId=t.teamId where playerId=#{id}
</select>
<select id="queryById2" resultMap="JoinTeamResult2">
select * from player p inner join team t on p.teamId=t.teamId where playerId=#{id}
</select>
<select id="queryById3" resultMap="JoinTeamResult3">
select * from player where playerId=#{id}
</select>
<resultMap id="baseResultMap" type="com.kkb.pojo.Player">
<id column="playerId" property="playerId"></id>
<result column="playerName" property="playerName"></result>
<result column="playerNum" property="playerNum"></result>
<result column="teamId" property="teamId"></result>
</resultMap>
<!-- 方式1:通过关联对象打点调用属性的方式要求:连接查询
如果连接查询,一般单独定义resultMap extends="表示继承的其他的resultMap的id"
-->
<resultMap id="JoinTeamResult1" type="Player" extends="baseResultMap">
<id column="teamId" property="team1.teamId"></id>
<result column="teamName" property="team1.teamName"></result>
<result column="location" property="team1.location"></result>
<result column="teamName" property="team1.teamName"></result>
<result column="createTime" property="team1.createTime"></result>
</resultMap>
<!--方式2:直接引用关联对象的Mapper映射:要求连接查询property=" 关 联 对 象 的 属 性 名 " javaType="关联对象的类型"
resultMap="关联对象的命名空间中的resultMap"
-->
<resultMap id="JoinTeamResult2" type="Player" extends="baseResultMap">
<association property="team2" javaType="Team" resultMap="com.kkb.mapper.TeamMapper.baseResultMap"></association>
</resultMap>
<!--方式3:直接引用关联对象的单独查询的方法:要求:关联对象的Maper中必须要求有单独的查询方法property="关联对象的属性名"
javaType="关联对象的类型" select="关联对象的单独查询的语句" column="外键列"
-->
<resultMap id="JoinTeamResult3" type="Player" extends="baseResultMap">
<association property="team3" javaType="Team" select="com.kkb.mapper.TeamMapper.queryById" column="teamId"></association>
</resultMap>
</mapper>
- 测试代码
package com.kkb.test;
import com.kkb.mapper.PlayerMapper;
import com.kkb.mapper.TeamMapper;
import com.kkb.pojo.Player;
import com.kkb.pojo.Team;
import com.kkb.utils.MybatisUtil;
import org.junit.Test;
import java.util.List;
/**
*ClassName: TestPlayerMapper
*测试类
*@author wanglina
*@version 1.0
*/
public class TestPlayerMapper {
PlayerMapper playerMapper = MybatisUtil.getSqlSession().getMapper(PlayerMapper.class);
// 测试成功
@Test
public void test01() {
Player player = playerMapper.queryById1(1);
System.out.println(player);
}
// 测试成功
@Test
public void test02() {
Player player = playerMapper.queryById2(1);
System.out.println(player);
}
// 测试成功
@Test
public void test03() {
Player player = playerMapper.queryById3(1);
System.out.println(player);
}
}
2 对多关系的映射
代码示例:
- 修改Team 实体类
package com.kkb.pojo;
import java.util.Date;
import java.util.List;
public class Team {
private Integer teamId;
private String teamName;
private String location;
private Date createTime;
//一对多的体现:一方持有多方的对象
private List<Player> playerList1;//关联对象--一个球队可以拥有多个球员
private List<Player> playerList2;//关联对象--一个球队可以拥有多个球员
@Override
public String toString() {
return "Team{" +
"teamId=" + teamId +
", teamName='" + teamName + '\'' +
", location='" + location + '\'' +
", createTime=" + createTime +
", playerList1=" + playerList1 +
", playerList2=" + playerList2 +
'}';
}
public Integer getTeamId() {
return teamId;
}
public void setTeamId(Integer teamId) {
this.teamId = teamId;
}
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public List<Player> getPlayerList1() {
return playerList1;
}
public void setPlayerList1(List<Player> playerList1) {
this.playerList1 = playerList1;
}
public List<Player> getPlayerList2() {
return playerList2;
}
public void setPlayerList2(List<Player> playerList2) {
this.playerList2 = playerList2;
}
}
- TeamMapper 中添加方法
public interface TeamMapper {
Team queryById1(int teamId);
Team queryById2(int teamId);
}
- PlayerMapper 中添加方法
public interface PlayerMapper {
List<Player> queryByTeamId(int teamId);
}
方式1:连接查询+引用关联对象的结果映射
方式2:引用关联对象的单独查询的方法
TeamMapper.xml 中添加
<select id="queryById1" resultMap="joinResult1">
select * from team t join player p on t.teamId=p.teamId where t.teamId=#{id};
</select>
<select id="queryById2" resultMap="joinResult2">
select * from team where teamId=#{id};
</select>
<!--方式1:
对多的连接查询:对多使用collection property="关联对象的集合名称" javaType="关联对象的集合类型" ofType="关联对象的集合的泛型" resultMap="引用关联对象的结果映射"
-->
<resultMap id="joinResult1" type="Team" extends="baseResultMap">
<collection property="playerList1" javaType="java.util.ArrayList" ofType="Player" resultMap="com.kkb.mapper.PlayerMapper.baseResultMap"></collection>
</resultMap>
<!--方式2:
对多的连接查询:对多使用collection property="关联对象的集合名称" javaType="关联对象的集合类型" ofType="关联对象的集合的泛型"
select="引用关联对象的单独查询的方法":使用的前提是关联对象中该方法可用column="引用关联对象的单独查询的方法的参数,一般是外键"
-->
<resultMap id="joinResult2" type="Team" extends="baseResultMap">
<collection property="playerList2" javaType="java.util.ArrayList" select="com.kkb.mapper.PlayerMapper.queryByTeamId" column="teamId"></collection>
</resultMap>
PlayerMapper.xml 中添加
<select id="queryByTeamId" resultType="Player">
select * from player where teamId=#{id}
</select>
TestPlayerMapper.java 中添加
public class TestPlayerMapper {
TeamMapper teamMapper=MybatisUtil.getSqlSession().getMapper(TeamMapper.class);
// 测试成功
@Test
public void test04(){
Team team = teamMapper.queryById1(1025);
System.out.println(team);
}
// 测试成功
@Test
public void test05(){
Team team = teamMapper.queryById2(1025);
System.out.println(team);
}
@Test
public void test01(){
Player player = playerMapper.queryById1(1); System.out.println(player);
}
}