zoukankan      html  css  js  c++  java
  • 【mybatis xml】数据层框架应用--Mybatis(三)关系映射之一对一关系映射

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

    针对多表之间的操作,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

    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>元素向数据表中插入记录。
    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。

        <mappers>
            <mapper resource="com/lomtom/mybatis/mapper/adminDetailMapper.xml"/>
            <mapper resource="com/lomtom/mybatis/mapper/adminInfoMapper.xml"/>
        </mappers>
    

    4、创建表格

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

    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、测试一对一关联映射

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

        @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();
        }
    

    你可能会出现的问题

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

    描述:

    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创造空的构造函数

    写在最后

    关注公众号:博奥思园 ,精彩内容不错失

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

  • 相关阅读:
    flume自定义source
    flume自定义sink之文件
    - Exception follows. org.apache.flume.FlumeException: java.net.BindException: Address already in use
    flume自定义sink之mysql
    Vue 【事件&样式】样式
    选择器
    rem
    表格和表单
    双飞翼布局、圣杯布局
    三栏布局
  • 原文地址:https://www.cnblogs.com/lomtom/p/12822934.html
Copyright © 2011-2022 走看看