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;
就这样搞定了
作者:隔壁老郭
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
Java入门到入坟
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!