在实际项目开发中,经常存在一对一关系,比如一个人只能有一个身份证,一个身份证只能给一个人使用,这就是一对一的关系。一对一关系推荐使用唯一主外键关联,即两张表使用外键关联关系,由于是一对一关联,因此还需要给外键列增加unique 唯一约束。下面我们就用一个简单示例来看看MyBatis怎么处理一对一关系。
首先,在数据库创建两个表tb_card和tb_person,并插入测试数据。
SQL 脚本如下:

CREATE TABLE tb_card (
id INT PRIMARY KEY AUTO_INCREMENT,
CODE VARCHAR (18)
)
INSERT INTO tb_card(CODE) VALUES('432801198009191038);
CREATE TABLE tb person (
id INT PRIMARY KEY AUTO INCREMENT,
NAME VARCHAR(18),
sex VARCHAR(18),
age INT,
card_id INT UNIQUE,
FOREIGN KEY (card_id) REERENCES tb_card(id)
)
INSERT INTO TB_PERSON (NAME,sex,age,card_id) VALUES('jack','男',23,1) ;

提示:
tb_person表的card_id作为外键参照tb_card表的主键id,因为是一对一关系,即一个card只能让一个person使用,所以card_id做成了唯一键约束。如此一来,当一个person使用了一个card之后,其他的person 就不能使用该card了。

接下来,创建一个Card对象和一个Person对象分别映射tb_card和tb_person表。

public class Card implements Serializable {
private Integer id; // 主键id
private String code; // 身份证编号
// 省略构造器和set/get 方法......
}
public class Person implements Serializable {
// 主键id
private Integer id;
// 姓名
private String name; 
// 性别
private String sex;
// 年龄
private Integer age; 
// 人和身份证是一对一的关系,即一个人只有一个身份证
private Card card;
// 省略构造器和set/get 方法.
}

人和身份证是一对一的关系,即一个人只有一个身份证。在Person类中定义了一个card属性,该属性是一个Card类型,用来映射一对一的关联关系,表示这个人的身份证。
再接下来是XML映射文件。

<mapper namespace="cn.mybatis.mapper.CardMapper">
<!-- 根据id查询Card,返回Card对象-->
<select id="selectCardById" parameterType="int" resultType="cn.mybatis.domain.Card">
SELECT * from tb_card where id = #{id}
</select>
</mapper>
<mapper namespace="cn.mybatis.mapper.PersonMapper">
<!-- 根据id查询Person,返回resultMap-->
<select id="selectPersonById" parameterType="int" resultMap="personMapper">
SELECT * from tb_person where id = #{id}
</select>
<!-- 映射Peson 对象的resultMap-->
<resultMap id="personMapper" type="cn.mybatis.domain.Person">
<id property="id" column="id"/>
<result property="name" column= "name" />
<result property="sex" column="sex"/>
<result property="age" column="age"/>
< !--一对一关联映射:association-->
<association property="card" column="card_id" select="cn.mybatis.mapper.CardMapper.selectCardById"
javaType="cn.mybatis.domain.Card"/>
</resultMap>
</mapper>

在PersonMapper.xml中定义了一个<select.../>,其根据id查询Person信息,由于Person类除了简单的属性id、name、sex和age之外,还有一个关联对象card,所以返回的是一个名为personMapper的resultMap。personMapper中使用了<association .../>元素映射一对一的关联关系,
select属性表示会使用column属性的card_id值作为参数执行CardMapper中定义的selectCardById查询对应的Card数据,查询出的数据将被封装到property表示的card对象当中。
我们通常都是使用SqlSession对象调用insert,update,delete和select方法进行测试。实际上,Mybatis官方手册建议通过mapper接口的代理对象访问mybatis,该对象关联了SqlSession对象,开发者可以通过该对象直接调用方法操作数据库。下面定义一个mapper接口对象,需要注意的是,mapper接口对象的类名必须和之前的XML文件中的mapper的namespace一致,而方法名和参数也必须和XML文件中的<select.../>元素的id属性和parameterType属性一致。

<mpper namespace="cn.mybatis.mapper.PersonMapper">
<select id="selectPersonById" parameterType="int".../>
< /mapper>
public interface PersonMapper {
/**
*根据id 查询Person,
*方法名和参数必须和XML文件中的<select.../>元素的id属性和parameterType属性一致
*@param id
*@return Person对象
**/
Person selectPersonById(Integer id) ;
}

最后,完成测试类。

public class OneToOneTest{
public static void main(String [] args) throws Exception { 
// 读取mybatis-config.xml文件
InputStream inputstream = Resources.getResourceAsstream(mybatis-config.xml");
// 初始化mybatis,创建SqlSessionFactory 类的实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream) ;
// 创建Session 实例
SqlSession session = sqlSessionFactory.openSession();
// 获得代理对象接口白mapper
PersonMapper pm = session.getMapper(PersonMapper.class);
// 直接调用接口的方法,查询id为1的Peson数据
Person p = pm.selectPersonById(1);
// 打印Peson对象
System.out.println(p);
// 打印Person对象关联的Card对象
System.out.println(p.getCard( ));
// 提交事务
session.commit() ;
// 关闭Session
session.close() ;
}
}

运行OneToOneTest 类的main 方法,通过SqlSession的getMapper(Class<?> type)方法获得mapper接口的代理对象PersonMapper,调用selectPersonByld方法时会执行ersonMapper.xml中<select.../>元素中定义的sql语句。

标签: none

《收徒公告》已经3人报名,还差2人,报名截止日期:2018年12月15日,请移步:>>>>>>

已有 6 条评论

  1. 互联网微尘 互联网微尘

    感谢分享,同时希望你们可以好好维护这个网站,发表的文章需要进行一些勘误。以上SQL语句出错,另外:网站UI可以优化一下。加油!

    1. 好的。谢谢提醒。

  2. 互联网微尘 互联网微尘

    祝你们的网站越来越好,发表的文章质量逐步提高。作最好的mybatis中国分站。

    1. 谢谢,我们会努力的

      1. memeem memeem

        你们写的SQL语句没有一个是不错的,内容挺好的为何是这种错误呢???????不理解

        1. 网站上线之初,采用人工智能技术生产了一些内容,这些内容可能存在毛刺,后来抽空修订了一部分内容,工作有点忙,还有部分内容没有来得及修订,敬请谅解。

添加新评论