Mybatis——Plus :表與表之間的關系:1對多和多對一


Mybatis——plus我大致整理出兩種方案:

第一種:第三方mybatis-plus 插件,注解式開發

Mybatis-Plus-Relation ( mprelation ) : mybatis-plus 一對一、一對多、多對一、多對多的自動關聯查詢,注解方式。

<dependency>
     <groupId>com.github.dreamyoung</groupId>
     <artifactId>mprelation</artifactId>
     <version>0.0.3.2-RELEASE</version> 
</dependency>
  • 使用簡單,通過在實體類上添加@OneToOne / @OneToMany / @ManyToOne / @ManyToMany 等注解即可*

使用要點

使用注意點:
       非ServiceImpl內置的業務查詢,配置事務管理,減少SqlSession的創建。
       實體上可用注解@AutoLazy(true/false)來標注是否自動觸發延遲加載,該注解只針對需要延遲的屬性。
       ★true或無值的話,則獲取延遲的關聯屬性時自動關聯。但每一個延遲屬性的獲取都消耗一個SqlSession。適合於只有一個延遲屬性的情況。
       ★false或者不標注該注解的話,需要手動通過initialize()方法對延遲的關聯屬性進行獲取,否則不會自動關聯獲取,此時關聯為空。適合於有多個延遲屬性的情況。
       如果可以,不使用延遲加載(延遲加載的使用是在SqlSession關閉后執行的,需要重新創建SqlSession)。
       如果確實需要延遲加載,可使用ServiceImpl 或  AutoMapper 相關的initialize方法一次性加載所有需要的被延遲的屬性(只需要創建額外的一個SqlSession,畢竟SqlSession之前已經關閉)

具體使用

@Data
public class Company {
    @TableId(value = "company_id")
    private Long id;
    private String name;
    
    //一對多
    @TableField(exist = false)
    @OneToMany //一對多默認為延遲加載,即@Lazy/@Lazy(true)/或此時不標注
    @JoinColumn(name="company_id",referencedColumnName = "company_id")//@TableId與一方相關屬性中@TableField名稱保持一致時@JoinColumn可省略
    private Set<Man> employees;
}
@Data
public class Man {

    @TableId(value = "man_id")
    private Long id;
    private String name;

    //多對一
    @TableField("company_id")
    private Long companyId;
    
    @TableField(exist = false)
    @ManyToOne //多對一默認為立即加載,即@Lazy(false)或此時不標注
    @JoinColumn(name = "company_id", referencedColumnName = "company_id") //相關的@TableField與多方的@TableId名稱一致時@JoinColumn可省略
    private Company company;
}

一對多(多對一)表結構: company: (compnay_id, name) man: (man_id, name, company_id)

方式二:java實體類加入 關聯對象(可以是單個,也可以是集合)

package com.gton.person.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 *
 * </p>
 *
 * @author GuoTong
 * @since 2020-12-24
 */
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value = "StudentActivity對象", description = "活動表")
public class StudentActivity implements Serializable {

    private static final long serialVersionUID = 1L;

    @ApiModelProperty(value = "活動表的ID")
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private String id;

    @ApiModelProperty(value = "活動名稱")
    private String activityName;

    /**
     * 在添加的時候插入時間
     */
    @ApiModelProperty(value = "創建時間")
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;

    /**
     * 在修改或者第一次添加的時候自動填充
     */
    @ApiModelProperty(value = "修改時間")
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;

    @ApiModelProperty(value = "活動結束時間")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime endTime;

    @ApiModelProperty(value = "活動詳情")
    private String activityDesc;

    @ApiModelProperty(value = "活動發起人")
    private String openUserId;

    @ApiModelProperty(value = "是否開啟加權投票")
    private Integer isShow;

    @ApiModelProperty(value = "活動LOGO地址")
    private String activityImage;

    /**
     * 參加活動的密碼
     */
    @ApiModelProperty(value = "參加活動的密碼")
    private String activityPassword;

    //:@TableField(exist = false)表示該屬性不為數據庫表字段,但又是必須使用的。反之必須使用
    @ApiModelProperty(value = "關系:1:oo")
    @TableField(exist = false)
    private List<StudentActivityItems> items;
}

通過 collection 就是查詢的幾個表里面的字段名不能有重復的 可以別名
   <!--手動數據庫字段和實體類映射-->
    <resultMap id="resMap" type="com.gton.person.entity.StudentActivity">
        <id column="id" property="id"></id>
        <result property="activityName" column="activity_name"></result>
        <result property="createTime" column="create_time"></result>
        <result property="updateTime" column="update_time"></result>
        <result property="endTime" column="end_time"></result>
        <result property="activityDesc" column="activity_desc"></result>
        <result property="openUserId" column="open_user_id"></result>
        <result property="isShow" column="is_show"></result>
        <result property="activityImage" column="activity_image"></result>
        <!--一對多,方式一{就是查詢的幾個表里面的字段名不能有重復的}-->
        <collection property="items" ofType="com.gton.person.entity.StudentActivityItems">
            <id column="item_id" jdbcType="VARCHAR" property="id"/>
            <result column="activity_id" jdbcType="INTEGER" property="activityId"/>
            <result column="count" jdbcType="VARCHAR" property="count"/>
            <result column="item_desc" jdbcType="VARCHAR" property="itemDesc"/>
            <result column="head_img" jdbcType="VARCHAR" property="headImg"/>
            <result column="item_name" jdbcType="TIMESTAMP" property="itemName"/>
        </collection>
    </resultMap>
<!--one To Many||注意一對多關系不能有相同的列,如果有相同的取別名,然后映射別名就可以了-->
    <select id="getByOneToMany" resultMap="resMap">
         select a.*,i.id as item_id,i.count,i.item_desc,i.item_name,i.head_img
         from student_activity_items i,student_activity a
         where i.activity_id = #{activeId}
         and i.activity_id = a.id
    </select>
然后這樣做會把mybatis-plus原本的自動映射方式破壞:,會報錯壞sql

解決方式 :::忽視該字段與數據庫字段映射, @TableField(exist = false)

  //:@TableField(exist = false)表示該屬性不為數據庫表字段,但又是必須使用的。反之必須使用
    @ApiModelProperty(value = "關系:1:oo")
    @TableField(exist = false)
    private List<StudentActivityItems> items;

就這樣搞定了


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM