一对一关系映射
一对一关系,我们这里用用户表和用户扩展表来举例。扩展表是对用户表的一些扩展信息补充,他们的关系是一对一。
为此我们创建一个 AccountExtend 表,然后在 Account 表增加一个 ExtendID 字段用来关联到 AccountExtend 表中的 ID。
建表 SQL
SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`Name` varchar(50) NOT NULL,
`Age` int(11) NOT NULL,
`Sex` tinyint(4) NOT NULL,
`AddTime` date NOT NULL,
`ExtendID` int(11) NOT NULL,
PRIMARY KEY (`ID`),
KEY `fk_aid_eid` (`ExtendID`),
CONSTRAINT `fk_aid_eid` FOREIGN KEY (`ExtendID`) REFERENCES `accountextend` (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=35 DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `accountextend`;
CREATE TABLE `accountextend` (
`ID` int(11) NOT NULL AUTO_INCREMENT,
`EnglishName` varchar(30) NOT NULL,
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;Code language: JavaScript (javascript)
添加两条测试数据后,扩展表对应的实体类如下:
package cn.foxdevelop.models;
public class AccountExtend {
private int ID;
private String EnglishName;
public String getEnglishName() {
return EnglishName;
}
public void setEnglishName(String englishName) {
EnglishName = englishName;
}
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
}Code language: PHP (php)
Account 类修改,增加 AccountExtend 对象字段(注意不是 ExtendID,而是直接引用一个对象):
private AccountExtend accountExtend;
public AccountExtend getAccountExtend() {
return accountExtend;
}
public void setAccountExtend(AccountExtend accountExtend) {
this.accountExtend = accountExtend;
}Code language: PHP (php)
方式一:连表查询 + resultMap 映射
SQL 语句:
select * from account a, accountextend ae where a.ExtendID=ae.ID and a.ID = 36Code language: JavaScript (javascript)
映射文件配置:
<select id="getAccountAndExtend" parameterType="int" resultMap="AccountAndExtendResultMap">
select a.*, ae.ID as EID, ae.EnglishName from account a, accountextend ae where a.ExtendID=ae.ID and a.ID = #{id}
</select>
<resultMap type="cn.foxdevelop.models.Account" id="AccountAndExtendResultMap">
<id property="ID" column="ID"/>
<result property="Name" column="Name"/>
<result property="Age" column="Age"/>
<association property="accountExtend" javaType="cn.foxdevelop.models.AccountExtend">
<id property="ID" column="EID"/>
<result property="EnglishName" column="EnglishName"/>
</association>
</resultMap>Code language: HTML, XML (xml)
调用代码:
public static void main(String[] args) throws IOException {
SqlSession session = extracted();
Account account = session.selectOne("cn.foxdevelop.mapper.getAccountAndExtend", 36);
System.out.println(account.getName() + " - " + account.getAccountExtend().getEnglishName());
// 最后关闭session
session.close();
}Code language: JavaScript (javascript)
返回结果:张三 - zhangsan
方式二:嵌套查询(分步查询)
MyBatis 还支持另外一种嵌套的写法,映射文件中配置如下:
<select id="getAccountAndExtend2" parameterType="int" resultMap="AccountAndExtendResultMap2">
select * from Account where id=#{id}
</select>
<resultMap type="cn.foxdevelop.models.Account" id="AccountAndExtendResultMap2">
<association property="accountExtend" column="ExtendID" select="getAccountExtend"/>
</resultMap>
<select id="getAccountExtend" parameterType="int" resultType="cn.foxdevelop.models.AccountExtend">
SELECT * FROM AccountExtend WHERE id=#{id}
</select>Code language: HTML, XML (xml)
这种方式先查 Account 表,再通过 ExtendID 列的值去调用 getAccountExtend 查询扩展表,实现分步加载。
Previous: 使用 resultMap 解决字段名与属性名不一致的问题
Next: 一对多关系映射