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;
就這樣搞定了