一对一关系映射

一对一关系映射

一对一关系,我们这里用用户表和用户扩展表来举例。扩展表是对用户表的一些扩展信息补充,他们的关系是一对一。

为此我们创建一个 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 查询扩展表,实现分步加载。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注