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包中创建实体类Type.javaProductInfo.java

    1、Type.java
    /**
     * @Author: LOMTOM
     * @Date: 2020/4/26
     * @Time: 17:48
     * @Email: lomtom@qq.com
     */
    @Data
    public class Type {
        private int id;
    
        private String name;
    
        private List<ProductInfo> pis;
    
        public Type() {
        }
    
        public Type(String name) {
            this.name = name;
        }
    }
    
    2、ProductInfo.java
    /**
     * @Author: LOMTOM
     * @Date: 2020/4/26
     * @Time: 17:48
     * @Email: lomtom@qq.com
     */
    @Data
    public class ProductInfo {
        private int id;
    
        private String code;
    
        private String name;
    
        private Type t;
    
        public ProductInfo() {
        }
    
        public ProductInfo(String code, String name) {
            this.code = code;
            this.name = name;
        }
    }
    
    

    2、创建SQL映射的XML文件

    创建SQL映射的XML文件typeMapper.xmlproductInfoMapper.xml

    1、typeMapper.xml
    	<mapper namespace="com.lomtom.mybatis.mapper.typeMapper">
    	    <!--插入数据-->
    	    <insert id="addType" parameterType="Type">
    	        <!--获得刚插入数据表type的记录id-->
    	        <selectKey keyProperty="id" resultType="int" order="AFTER">
    	            SELECT LAST_INSERT_ID() AS ID
    	        </selectKey>
    	        insert into type(name) values(#{name})
    	    </insert>
    	
    	    <!--加载数据(方式1)-->
    	    <select id="getType" parameterType="int" resultMap="getTypeMap">
    	        select t.id tid, t.name tname, pi.* from type t, product_info pi
    	        where pi.tid=t.id and t.id=#{id}
    	    </select>
    	    <resultMap type="Type" id="getTypeMap">
    	        <id property="id" column="tid"/>
    	        <result property="name" column="tname"/>
    	        <collection property="pis" ofType= "ProductInfo">
    	            <id property="id" column="id"/>
    	            <result property="code" column="code"/>
    	            <result property="name" column="name"/>
    	        </collection>
    	    </resultMap>
    	
    	
    	
    	    <!--加载数据(方式2)-->
    	    <select id="getType2" resultMap="getType2Map">
    	        select * from type where id=#{id}
    	    </select>
    	    <resultMap type="Type" id="getType2Map">
    	        <id property="id" column="id"/>
    	        <result property="name" column="name"/>
    	        <collection property="pis" column="id" select="getProductInfo"/>
    	    </resultMap>
    	    <select id="getProductInfo" resultMap="getProductInfoMap">
    	        select from product info where tid=#{id}
    	    </select>
    	    <resultMap type="ProductInfo" id="getProductInfoMap">
    	    <id property="id" column="id"/>
    	    <result property="code" column="code"/>
    	    <result property="name" column="name"/>
    	    </resultMap>
    	</mapper>
    
    
    2、productInfoMapper.xml
    	<mapper namespace="com.lomtom.mybatis.mapper.productInfoMapper">
    	    <insert id="addProductInfo" parameterMap="addProductInfoPMap">
    	        insert into product_info(code, name, tid) values(#{code},
    	        #{name}, #{t.id})
    	    </insert>
    	    <parameterMap type="ProductInfo" id="addProductInfoPMap">
    	        <parameter property="code"/>
    	        <parameter property="name"/>
    	        <parameter property="t.id"/>
    	    </parameterMap>
    	</mapper>
    

    3、注册SQL映射的XML文件

    在XML配置文件mybatis-config.xml中注册typeMapper.xml和productInfoMapper.xml。

        <mappers>
            <mapper resource="com/lomtom/mybatis/mapper/productInfoMapper.xml"/>
            <mapper resource="com/lomtom/mybatis/mapper/typeMapper.xml"/>
        </mappers>
    

    4、创建表格

    创建typeproduct_info两个表

    1、type
    	SET NAMES utf8mb4;
    	SET FOREIGN_KEY_CHECKS = 0;
    	
    	-- ----------------------------
    	-- Table structure for type
    	-- ----------------------------
    	DROP TABLE IF EXISTS `type`;
    	CREATE TABLE `type`  (
    	  `id` int(0) NOT NULL AUTO_INCREMENT,
    	  `name` 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、product_info
    	SET NAMES utf8mb4;
    	SET FOREIGN_KEY_CHECKS = 0;
    	
    	-- ----------------------------
    	-- Table structure for product_info
    	-- ----------------------------
    	DROP TABLE IF EXISTS `product_info`;
    	CREATE TABLE `product_info`  (
    	  `id` int(0) NOT NULL AUTO_INCREMENT,
    	  `code` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
    	  `name` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
    	  `tid` int(0) NULL DEFAULT NULL,
    	  PRIMARY KEY (`id`) USING BTREE,
    	  INDEX `fk_product_type_idx`(`tid`) USING BTREE,
    	  CONSTRAINT `product_info_ibfk_1` FOREIGN KEY (`tid`) REFERENCES `type` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
    	) ENGINE = InnoDB AUTO_INCREMENT = 16 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
    	
    	SET FOREIGN_KEY_CHECKS = 1;
    
    

    5、测试一对一关联映射

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

      @Test
        public void testAddType(){
            SqlSession sqlSession= MybatisUtils.getSession();
            //创建Type对象
            Type type = new Type("打印机");
            //保存Type对象
            sqlSession.insert("addType", type);
            //创建两个 ProductInfo对象
            ProductInfo productInfo1=new ProductInfo( "111111", "HP1306");
            ProductInfo productInfo2=new ProductInfo( "222222","HP11103");
            //设置 ProductInfo对象与Type的关联
            productInfo1.setT(type);
            productInfo2.setT(type);
            //保存两个 ProductInfo对象
            sqlSession.insert("addProductInfo", productInfo1);
            sqlSession.insert("addProductInfo", productInfo2);
            sqlSession.commit();
            sqlSession.close();
        }
    
        @Test
        public void testGetTypeById() {
            SqlSession sqlSession= MybatisUtils.getSession();
            Type t = sqlSession.selectOne("getType", 1);
            System.out.println(t);
            sqlSession.commit();
            sqlSession.close();
        }
    
    
        @Test
        public void testGetTypeById2() {
            SqlSession sqlSession= MybatisUtils.getSession();
            Type t = sqlSession.selectOne(" getType2", 1);
            System.out.println(t);
            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创造空的构造函数

    写在最后

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

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

  • 相关阅读:
    oracle 第12章 归档日志文件
    oracle 第09章 参数文件
    oracle 第11章 重做日志文件
    oracle 第10章 控制文件
    oracle 第14章 表空间管理
    linux yum源配置
    oracle 第08章 用户、权限、角色管理
    oracle 第07章 网络配置管理
    第二阶段冲刺-06
    第二阶段冲刺-05
  • 原文地址:https://www.cnblogs.com/lomtom/p/12822953.html
Copyright © 2011-2022 走看看