Springboot04 - Mybatis 多表查询中的多对一(注解方式)

在开发中,我遇到这样一种情况:每个种类(Categoy)中有多个属性(Property),每个Category和Property都拥有自己的id属性。这种时候,我就需要使用到多对一的方式:多个属性对应一个种类(种类 为 属性对象 的属性)。

以下为开发中的相关记录(注解方式实现)

一、相关注解

1. @Results

  • 代替映射文件中的
  • 当做select语句时,返回一个多对一的JavaBean时,需要用到Results来将数据库的相关id映射成对象保存在Bean中(后面有实例)
  • 该注解中可以使用单个 @Result 注解,也可以使用一个 @Result注解集合
  • 用法:@Results( {@Result( ), @Result( ) } )

2. @Result

  • 代替了映射文件中中的

  • 属性介绍:

    • property:字符串,JavaBean中需要映射的属性,这里是 "Category"
    • column:字符串,数据库的列名,可以看做 @One 中sql语句的参数,这里是 "cid"
    • one:需要使用 @One ,one = @One( )
    • many: 需要使用 @Many ,many=@Many( )
  • 用于实现Results中的具体映射:什么映射成什么,使用了什么Sql语句

3. @One (一对一)

  • 代替了, 多表查询的关键,在注解中用来指定子查询返回舱单一对象给@Result前面的 property

  • 属性介绍

    • select:指定用来多表查询的 SqlMapper,mapper包路径+方法名
  • 使用:@Result(column=" ",property="",one=@One(select="") )

4. @Many (多对一)

  • 代替了
  • 和@One用法类似,例如:一个Categorry 中包含很多个Property
  • 使用:@Result(property="",column="",many=@Many(select=""))

二、运行原理

从SQL查询结果集到JavaBean或POJO实体的过程:

  1. 通过JDBC查询得到一个ResultSet对象,里面包含了数据库表的item
  2. 遍历ResultSet对象,并将每行item保存到HashMap实例中,以数据库中的字段名或设置的字段别名为键,以字段值为值
  3. 根据ResultMap(在注解中就是这里的Results)中的类型,这里是应用注解时下方的函数返回类型,通过反射实例化数据模型,即实例化一个Property对象
  4. Property对象中的Category对象,通过@Result中的属性实例化。这里是将参数column="cid"传递到@One中的sql语句中,返回的对象实例赋给category ( 通过 property="category" 设置 )

三、具体实现

@Select("select * from property where cid=#{category.id}")
    @Results({
            @Result(property = "category", column = "cid",
                    one = @One(select = "com.shan.tianmao.mapper.CategoryMapper.get"))
    })
    List findByCategory(@Param("category") Category category);
  • 此为PropertyMapper中的findByCategory方法,用于利用Category查找对应的Property

  • java类结构为:Property中有一个Category属性

    表结构为:Property中有一个cid属性

  • 特别注意:当向函数传递对象参数时,需要使用@Param( " 别名")注解,同时使用 category.id 调用

  • 原理讲解:

    1. 通过JDBC查询得到一个ResultSet对象,里面包含了数据库表的property{id, cid, name },cid为Category的id

      @Select("select * from property where cid=#{category.id}")
      
    2. 通过遍历ResultSet对象,并将每行property保存到HashMap实例中,以数据库中的字段名或设置的字段别名为键,以字段值为值

    3. 根据下方的函数返回类型 List,通过反射实例化Property模型

    4. Property对象中的category属性,通过@Result中的属性实例化。这里是将参数column="cid"传递到@One中的sql语句中,返回的对象实例赋给category ( 通过 property="category" 设置 )

      @Result(property = "category", column = "cid",
                          one = @One(select = "com.shan.tianmao.mapper.CategoryMapper.get"))
      

附两个实体类代码:

  • Category

    package com.shan.tianmao.pojo;
    
    public class Category {
        private int id;
        private String name;
    
        public Category() {
        }
    
        public Category(int id, String name) {
            this.id = id;
            this.name = name;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    }
    
    
  • Property

    package com.shan.tianmao.pojo;
    
    public class Property {
        private int id;
        private String name;
        private Category category;
    
        public Property() {
        }
    
        public Property(int id, String name, Category category) {
            this.id = id;
            this.name = name;
            this.category = category;
        }
    
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Category getCategory() {
            return category;
        }
    
        public void setCategory(Category category) {
            this.category = category;
        }
    }
    
    

你可能感兴趣的:(Springboot04 - Mybatis 多表查询中的多对一(注解方式))