MyBatis-plus は、3 レベルのリンケージ クエリ、ページングを含む結合テーブル クエリ処理、およびファジー クエリを実装します。

1. 3 レベルの連携(省-市-検査室を例に取る)

1) テーブルのデザイン

同じテーブルが州と都市にも存在します。parentId が 0 の場合は州を表し、parentId が 0 以外の場合は対応する州の都市を表します。

package com.example.jiakao.pojo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import javax.persistence.*;

@Entity
@Data
@TableName("plate_region")
@Table(name="plate_region")
public class PlateRegionPo {
    @Id
    @TableId(type = IdType.AUTO)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column( columnDefinition = "int4" )
    private Integer id;
    @Column( columnDefinition = "varchar(64)" )
    private String name;
    @Column( columnDefinition = "varchar(64)" )
    private String plate;
    @Column( columnDefinition = "int4 default 0 " )
    private Integer parentId;
}

 診察室テーブル、parentId は都市 ID に対応

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import javax.persistence.*;

@Entity
@Data
@TableName("exam_place")
@Table(name="exam_place")
public class ExamPlacePo {
    @Id
    @TableId(type = IdType.AUTO)
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column( columnDefinition = "bigint" )
    private Long id;
    @Column( columnDefinition = "varchar(64)" )
    private String name;
    @Column( columnDefinition = "int4" )
    private Integer parentId;
}

2) 戻り値の型 vo を定義します。

package com.example.jiakao.pojo.vo.list;

import lombok.Data;

import java.util.List;

@Data
public class ProvinceVo {
    private Long id;
    private String name;
    private String plate;
    private List<CityVo> children;
}
package com.example.jiakao.pojo.vo.list;

import lombok.Data;

import java.util.List;

@Data
public class CityVo {
    private Long id;
    private String name;
    private String plate;
    private List<ExamPlaceVo> children;
}
package com.example.jiakao.pojo.vo.list;

import lombok.Data;

@Data
public class ExamPlaceVo {
    private Long id;
    private String name;
}

3) Mapper.xml クエリ ステートメント

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.jiakao.mapper.ExamPlacePoMapper">
    <resultMap id="selectRegionExamPlaces" type="com.example.jiakao.pojo.vo.list.ProvinceVo">
        <id column="id" property="id"></id>
        <result column="name" property="name"></result>
        <result column="plate" property="plate"></result>
        <collection property="children" ofType="com.example.jiakao.pojo.vo.list.CityVo">
            <id column="city_id" property="id"></id>
            <result column="city_name" property="name"></result>
            <result column="city_plate" property="plate"></result>
            <collection property="children" ofType="com.example.jiakao.pojo.vo.list.ExamPlaceVo">
                <id column="exam_id" property="id"></id>
                <result column="exam_name" property="name"></result>
            </collection>
        </collection>

    </resultMap>
    <select id="listRegionExamPlaces" resultMap="selectRegionExamPlaces">
        select
            p.id,
            p.name,
            p.plate,
            c.id city_id,
            c.name city_name,
            c.plate city_plate,
            e.id exam_id,
            e.name exam_name
        from plate_region p
            join plate_region c on c.parent_id = p.id
            join exam_place e on e.parent_id = c.id
        where p.parent_id = 0
    </select>
</mapper>

4) クエリ結果

{
    "code": 200,
    "message": "成功",
    "data": [
        {
            "id": 2,
            "name": "湖北",
            "plate": "鄂",
            "children": [
                {
                    "id": 3,
                    "name": "武汉",
                    "plate": "A",
                    "children": [
                        {
                            "id": 1,
                            "name": "hfgg"
                        },
                        {
                            "id": 5,
                            "name": "hgi"
                        }
                    ]
                }
            ]
        },
        {
            "id": 1,
            "name": "广东",
            "plate": "粤",
            "children": [
                {
                    "id": 7,
                    "name": "深圳",
                    "plate": "B",
                    "children": [
                        {
                            "id": 6,
                            "name": "hgiG"
                        }
                    ]
                },
                {
                    "id": 8,
                    "name": "广州",
                    "plate": "A",
                    "children": [
                        {
                            "id": 7,
                            "name": "hgU"
                        },
                        {
                            "id": 8,
                            "name": "hgUU"
                        }
                    ]
                }
            ]
        }
    ]
}

5)注意点

        結合、左結合、および右結合の違いを簡単にまとめます。結合は 2 つのテーブルの交差を取得し、交差エントリのみを保持します。左結合は、交差があるかどうかに関係なく、結合の前のテーブルをメイン テーブルとして使用します。メイン テーブル エントリが存在するかどうかに関係なく、右結合では結合後のテーブルがメイン テーブルとして使用されます。

2. ファジィクエリとページネーションによる結合テーブルのクエリ処理について(診察室・被験者を例に)

1) vo の定義は、データを保存するときに po オブジェクトのフィールドに対応するパラメーターを渡すために使用され、ユーザーの操作を必要としない po オブジェクトのフィールドのみを無視します。

package com.example.jiakao.pojo.vo.req.save;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
@ApiModel("保存考场信息的参数")
public class ExamPlaceReqVo {
    @ApiModelProperty(value = "考场id")
    private Long id;
    @ApiModelProperty(value = "考场名称", required = true)
    @NotBlank(message = "名称不能为空")
    private String name;
    @ApiModelProperty(value = "考场所属城市id", required = true)
    @NotNull(message = "所属城市不能为空")
    private Integer cityId;
    @ApiModelProperty(value = "考场所属省份id", required = true)
    @NotNull(message = "所属省份不能为空")
    private Integer provinceId;
}
package com.example.jiakao.pojo.vo.req.save;

import com.example.jiakao.common.validator.BoolNumber;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;

@Data
@ApiModel("保存课程信息")
public class ExamCourseReqVo {
    @ApiModelProperty("课程id")
    private Long id;
    @ApiModelProperty(value = "课程名称", required = true)
    @NotBlank(message = "课程名不能为空")
    private String name;
    @ApiModelProperty(value = "课程类型",required = true)
    @NotNull(message = "课程类型不能为空")
    @BoolNumber(message = "课程类型值为0或1")
    private Short type;
    @ApiModelProperty(value = "课程价格",required = true)
    @NotNull(message = "课程价格不能为空")
    @Min(value = 0, message = "价格不能为负数")
    private Double price;
    @ApiModelProperty(value = "课程所属考场",required = true)
    @NotNull(message = "所属考场不能为空")
    private Long examPlaceId;
}

 戻りリストの vo 定義は、戻り結果エンティティを構築するために使用されます。

package com.example.jiakao.pojo.vo.list;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel("课程信息返回值")
public class ExamCourseVo {
    @ApiModelProperty("课程id")
    private Long id;
    @ApiModelProperty(value = "课程名称")
    private String name;
    @ApiModelProperty(value = "课程类型")
    private Short type;
    @ApiModelProperty(value = "课程价格")
    private Double price;
    @ApiModelProperty(value = "课程所属考场")
    private Long examPlaceId;
    @ApiModelProperty(value = "考场所属省份")
    private Integer provinceId;
    @ApiModelProperty(value = "考场所属城市")
    private Integer cityId;
}

2) サービスとマッパー

        使用する 2 つのテーブルには名前フィールドがあるため、QueryWrapper を構築するときにどのテーブルの名前フィールドを明確にマークする必要があるため、ここでは LambdaQueryWrapper の代わりに QueryWrapper を使用します。

package com.example.jiakao.service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.jiakao.common.enhance.MpPage;
import com.example.jiakao.common.enhance.MpQueryWrapper;
import com.example.jiakao.mapper.ExamCourseMapper;
import com.example.jiakao.pojo.entity.ExamCoursePo;
import com.example.jiakao.pojo.vo.json.PageVo;
import com.example.jiakao.pojo.vo.list.ExamCourseVo;
import com.example.jiakao.pojo.vo.req.query.KeyWordReqVo;
import org.springframework.stereotype.Service;

@Service
public class ExamCourseService extends ServiceImpl<ExamCourseMapper, ExamCoursePo> {
    public PageVo<ExamCourseVo> listCoursesPage(KeyWordReqVo query) {
        MpPage<ExamCourseVo> mpPage= new MpPage<>(query);
        MpQueryWrapper<ExamCourseVo> wrapper = new MpQueryWrapper<>();
        wrapper.likes(query.getKeyword(),"c.name");
        baseMapper.selectCourses(mpPage,wrapper);
        return mpPage.buildVo();
    }
}  }
}
package com.example.jiakao.mapper;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.example.jiakao.common.enhance.MpPage;
import com.example.jiakao.pojo.entity.ExamCoursePo;
import com.example.jiakao.pojo.vo.list.ExamCourseVo;
import org.apache.ibatis.annotations.Param;

//官方推荐前缀Constants.WRAPPER => ew
public interface ExamCourseMapper extends BaseMapper<ExamCoursePo> {
    public MpPage<ExamCourseVo> selectCourses(MpPage<ExamCourseVo> page,
                                              @Param(Constants.WRAPPER) QueryWrapper wrapper);
}

        Mapper メソッドで渡したり返したりするタイプが IPage インターフェイスの実装である場合、Mybatis-plus は自動的にページネーション、つまりクエリ ステートメントの後に制限を結合するのに役立ちます。ただし、クエリ条件は自動的に実装されないため、QueryWrapper 型のcustomSqlSegment を手動で呼び出して SQL ステートメントを取得し、それを XML に結合する必要があります。${} は #{} の代わりにスプライシングに使用され、$ は直接置換され、# はプリコンパイルされることに注意してください。

        もちろん、必要に応じて BaseMapper 汎用エンティティ以外のカスタム エンティティに対して LambdaQueryWrapper を構築することもできますが、この場合は afterPropertiesSet 設定を追加する必要があります。

public class MyBatisPlusConfig implements InitializingBean {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.POSTGRE_SQL));
        return interceptor;
    }

    /**
     * 拥有lambda cache的实体类,才能使用LambdaQueryWrapper<Entity>
     * 默认情况下只有BaseMapper<Entity>中泛型的entity才拥有lambda cache
     * 其他可以通过TableInfoHelper手动添加lambda cache
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        MapperBuilderAssistant assistant = new MapperBuilderAssistant(new MybatisConfiguration(),"");
        TableInfoHelper.initTableInfo(assistant, ExamCourseVo.class);
    }
}

3)Mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.jiakao.mapper.ExamCourseMapper">
    <resultMap id="selectCourses" type="com.example.jiakao.pojo.vo.list.ExamCourseVo">
    </resultMap>
<!--    ${wrapper.customSqlSegment} 获取自定义SQL-->
    <select id="selectCourses" resultMap="selectCourses">
        select
            c.id,
            c.name,
            c.exam_place_id,
            c.price,
            c.type,
            e.city_id,
            e.province_id
        from exam_course c
            left join exam_place e on c.exam_place_id = e.id
        ${ew.customSqlSegment}
    </select>
</mapper>

おすすめ

転載: blog.csdn.net/qq_33235279/article/details/130319445