前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >数据层框架应用--Mybatis(三)关系映射之一对一关系映射

数据层框架应用--Mybatis(三)关系映射之一对一关系映射

作者头像
lomtom
发布2021-10-27 15:38:49
1K0
发布2021-10-27 15:38:49
举报
文章被收录于专栏:博思奥园

实际的开发中,对数据库的操作常常会涉及到多张表,这在面向对象中就涉及到了对象与对象之间的关联关系。

针对多表之间的操作,MyBatis提供了关联映射,通过关联映射就可以很好的处理对象与对象之间的关联关系。

你需要了解的知识点

1、关联关系种类

数据库:

在关系型数据库中,多表之间存在着三种关联关系,分别为一对一一对多多对多

  1. 一对一:在任意一方引入对方主键作为外键;
  2. 一对多:在“多”的一方,添加“一”的一方的主键作为外键;
  3. 多对多:产生中间关系表,引入两张表的主键作为外键,两个主键成为联合主键或使用新的字段作为主键。
java
  1. 一对一:在本类中定义对方类型的对象,如A类中定义B类类型的属性b,B类中定义A类类型的属性a;(双向一对一)
  2. 一对多:一个A类类型对应多个B类类型的情况,需要在A类中以集合的方式引入B类类型的对象,在B类中定义A类类型的属性a;
  3. 多对多:在A类中定义B类类型的集合,在B类中定义A类类型的集合。

2、关联查询方式

MyBatis加载关联关系对象主要通过两种方式:嵌套查询嵌套结果

使用

项目目录如图,其中红色标注的为本次所需要的,本次主要讲解一对多关系映射,如果你对mybatis的xml版不熟悉的话请前往数据层框架应用--Mybatis(一) 基于XML映射文件实现数据的CRUD

1、创建实体类

创建实体类:在 com.lomtom.mybaris.entity包中创建实体类 AdminDetail.javaAdminInfo.java

代码语言:javascript
复制
1、AdminDetail.java
/**
 * @Author: LOMTOM
 * @Date: 2020/4/26
 * @Time: 16:43
 * @Email: lomtom@qq.com
 */
@Data
public class AdminInfo {
    private int id;

    private String name;

    private String pwd;

    private AdminDetail ad;

    public AdminInfo() {
    }

    public AdminInfo(String name, String pwd) {
        this.name = name;
        this.pwd = pwd;
    }
}

2、AdminInfo.java
/**
 * @Author: LOMTOM
 * @Date: 2020/4/26
 * @Time: 16:42
 * @Email: lomtom@qq.com
 */
@Data
public class AdminDetail {
    private int id;

    private String address;

    private String realName;

    public AdminDetail() {
    }

    public AdminDetail(String address, String realName) {
        this.address = address;
        this.realName = realName;
    }
}

2、创建SQL映射的XML文件

com.lomtom.mybaris.mapper包中创建SQL映射的XML文件 adminDetailMapper.xmladminInfoMapper.xml

  • 配置 <insert>元素向数据表中插入记录。
  • 配置 <select>元素向数据表中插入记录。
代码语言:javascript
复制
1、adminDetailMapper.xml
<mapper namespace="com.lomtom.mybatis.mapper.adminDetailMapper">
    <insert id="addAdminDetail" parameterType="AdminDetail"
        keyProperty="id" useGeneratedKeys="true">
        insert into admin_detail(address ,realName) values (#{address},#{realName})
    </insert>
</mapper>

2、adminInfoMapper.xml
<mapper namespace="com.lomtom.mybatis.mapper.adminInfoMapper">
    <insert id="addAdminInfo" parameterType="AdminInfo">
        insert into admin_info(id, name, pwd) values( #{ad.id}, #{name}, #{pwd})
    </insert>


    <select id="getAdminInfo" parameterType="int" resultMap="getAdminInfoMap">
        select ai.id, name, pwd, address, realName from admin_info ai, admin_detail ad where ai.id=ad.id and ai.id=#{id}
    </select>
    <!--嵌套结果映射,最后返回的结果,见 select元素的 resultMap属性-->
    <resultMap type="com.lomtom.mybatis.entity.AdminInfo" id="getAdminInfoMap">
        <id property="id" column="id" />
        <result property="name" column="name"/>
        <result property="pwd" column="pwd"/>
        <association property="ad" javaType="com.lomtom.mybatis.entity.AdminDetail">
            <id property="id" column="id"/>
            <result property="address" column="address"/>
            <result property="realName" column="realName"/>
        </association>
    </resultMap>


    <select id="getAdminInfo2" parameterType="int"
            resultMap="getAdminInfo2Map">
        select * from admin_info where id=#{id}
    </select>
    <select id="getAdminDetail" parameterType="int" resultType="AdminDetail">
        select * from admin_detail where id=#{id}
    </select>
    <resultMap type="AdminInfo" id="getAdminInfo2Map">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="pwd" column="pwd"/>
        <association property="ad" column="id" select="getAdminDetail"/>
    </resultMap>
</mapper>

其中,插入 keyProperty="id"useGeneratedKeys="true"实现自增,以上有两种查询方式分别为嵌套查询与嵌套结果

3、注册SQL映射的XML文件

在XML配置文件 mybatis-config.xml中注册 adminDetailMapper.xmladminInfoMapper.xml。

代码语言:javascript
复制
<mappers>
        <mapper resource="com/lomtom/mybatis/mapper/adminDetailMapper.xml"/>
        <mapper resource="com/lomtom/mybatis/mapper/adminInfoMapper.xml"/>
    </mappers>

4、创建表格

创建两个表admindetail和admininfo,注意两个表之间的依赖关系,可以先创建好两个表,在关联两个表

代码语言:javascript
复制
1、admin_detail
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;

    -- ----------------------------
    -- Table structure for admin_detail
    -- ----------------------------
    DROP TABLE IF EXISTS `admin_detail`;
    CREATE TABLE `admin_detail`  (
      `id` int(0) NOT NULL AUTO_INCREMENT,
      `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      `realName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

    SET FOREIGN_KEY_CHECKS = 1;

2、admin_info
    SET NAMES utf8mb4;
    SET FOREIGN_KEY_CHECKS = 0;

    -- ----------------------------
    -- Table structure for admin_info
    -- ----------------------------
    DROP TABLE IF EXISTS `admin_info`;
    CREATE TABLE `admin_info`  (
      `id` int(0) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      `pwd` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE,
      CONSTRAINT `admin_info_ibfk_1` FOREIGN KEY (`id`) REFERENCES `admin_detail` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
    ) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

    SET FOREIGN_KEY_CHECKS = 1;

5、测试一对一关联映射

在测试类里加入以下,用于测试我们刚刚写的插入与查询

代码语言:javascript
复制
@Test
    public void testAddAdminInfo() {
        SqlSession sqlSession= MybatisUtils.getSession();
        //创建 AdminDetail对象
        AdminDetail adminDetail = new AdminDetail("湖南长沙", "杨二蛋子");
        //创建 AdminInfo对象
        AdminInfo adminInfo = new AdminInfo("杨二蛋子", "123456");
        //向数据表 admin_detail插入记录
        sqlSession.insert("addAdminDetail", adminDetail);
        //设置 AdminInfo对象关联的 AdminDetail对象
        adminInfo.setAd(adminDetail);
        //向数据表 admin_info插入记录
        sqlSession.insert("addAdminInfo", adminInfo);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void testGetAdminInfoById(){
        SqlSession sqlSession= MybatisUtils.getSession();
        AdminInfo adminInfo = sqlSession.selectOne("getAdminInfo",4);
        System.out.println(adminInfo);
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void testGetAdminInfoById2(){
        SqlSession sqlSession= MybatisUtils.getSession();
        AdminInfo adminInfo = sqlSession.selectOne("getAdminInfo2",4);
        System.out.println(adminInfo);
        sqlSession.commit();
        sqlSession.close();
    }

你可能会出现的问题

问题一:提示缺少构造函数

描述:

代码语言:javascript
复制
Cause: org.apache.ibatis.executor.ExecutorException: No constructor found in com.lomtom.mybatis.entity.AdminInfo matching [java.lang.Integer, java.lang.String, java.lang.String, java.lang.String, java.lang.String]

分析:我们明明使用了lombok,为啥还会提示缺少构造函数,那是因为我们这里使用复杂的bean,lombok自己识别不出来解决:AdminDetail.javaAdminInfo.java创造空的构造函数

写在最后

你的支持是作者最大的动力

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博思奥园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 你需要了解的知识点
    • 1、关联关系种类
      • 数据库:
      • java
    • 2、关联查询方式
    • 使用
      • 1、创建实体类
        • 2、创建SQL映射的XML文件
          • 3、注册SQL映射的XML文件
            • 4、创建表格
              • 5、测试一对一关联映射
              • 你可能会出现的问题
                • 问题一:提示缺少构造函数
                • 写在最后
                相关产品与服务
                数据库
                云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档