Mybatis-plus3.x一对多发送额外sql分页查询的完整可运行案例

一、前言

本案例主要是20 Mybatis-plus3.x一对多发送额外sql分页查询的案例,下面是本文重点,熟悉的人可以只是看重点。不熟悉的人可以看后面的完整的案例

1.1 mybatis-plus自定义xml结合自动生成分页查询

利用 mybatis-plus的分页插件,自动进行分页
仔细观察写法,pageForRegin是我自定义的,但是pageRequest是由mybatis-plus自动注入的

Page<Traveller> pageRequest = new Page<>(travellerDto.getCurrent(),travellerDto.getSize());

***

IPage<Traveller> page = travellerMapper.pageForRegin(pageRequest,travellerDto.getUserName(),

1.2 数据库结构

在这里插入图片描述

功能,可以利用地点进行过滤,查谁去过天河区,谁去过花都区

1.3 传统mybatis的in写法

<if test="travellerIds.size != 0">
    and id in <foreach  item="travellerId" collection="travellerIds" open="(" separator="," close=")">#{travellerId}</foreach>
</if>

1.4 思考 分页插件 和 xml编译后的位置

二、具体案例

2.1、案例需要的sql语句

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

DROP TABLE IF EXISTS `user_region`;
CREATE TABLE `user_region`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_id` bigint(20) NULL DEFAULT NULL COMMENT '用户id',
  `region_code` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地点code',
  `region_location` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地点名称',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

INSERT INTO `user_region` VALUES (1, 5, '1000', '花都区');
INSERT INTO `user_region` VALUES (2, 5, '1001', '白云区');
INSERT INTO `user_region` VALUES (3, 5, '1002', '增城区');
INSERT INTO `user_region` VALUES (4, 5, '1003', '天河区');
INSERT INTO `user_region` VALUES (5, 5, '1004', '番禺区');
INSERT INTO `user_region` VALUES (6, 19, '1000', '花都区');
INSERT INTO `user_region` VALUES (7, 19, '1001', '白云区');
INSERT INTO `user_region` VALUES (8, 19, '1002', '增城区');

DROP TABLE IF EXISTS `user_traveller`;
CREATE TABLE `user_traveller`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
  `user_sex` tinyint(10) NULL DEFAULT NULL COMMENT '性别',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 34 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;

INSERT INTO `user_traveller` VALUES (5, '大大', 1);
INSERT INTO `user_traveller` VALUES (19, '小明', 1);

SET FOREIGN_KEY_CHECKS = 1;

2.2、新建项目,用mybatis-plus代码生成器生成代码

在这里插入图片描述

2.3 编写具体代码

编写entity层

@Data
@EqualsAndHashCode(callSuper = false)
@TableName("user_traveller")
@ApiModel(value="Traveller对象", description="")
public class Traveller implements Serializable {
    
    

    private static final long serialVersionUID = 1L;

    //省略

    @ApiModelProperty(value = "地址")
    @TableField(exist = false)
    private List<Region> regions;

}

编写Dto传输类

/**
 * 定义传输类,为了方便演示,把 当前页 和 显示多少条信息 都封装在当前。一般都是创建query类
 *
 * @author czchen
 * @version 1.0
 * @date 2020/11/29 20:33
 */
@Data
public class TravellerDto{
    
    

    @ApiModelProperty(value = "显示多少条信息")
    public long size = 10L;

    @ApiModelProperty(value = "当前页")
    public long current = 1L;

    @ApiModelProperty(value = "用户")
    public String userName;

    @ApiModelProperty(value = "去过的地方")
    public String regionLocation;

}

编写controller层

@RestController
@RequestMapping("/user/traveller")
public class TravellerController {
    
    

    @Autowired
    private ITravellerService travellerService;


    @PostMapping("/list")
    public Object list(@RequestBody TravellerDto travellerDto){
    
    

        //进行查询
        Object obejct = travellerService.pageForRegin(travellerDto);

        return  obejct;
    }

}

编写service层

public interface ITravellerService extends IService<Traveller> {
    
    

    Object pageForRegin(TravellerDto travellerDto);
}


@Service
public class TravellerServiceImpl extends ServiceImpl<TravellerMapper, Traveller> implements ITravellerService {
    
    

    @Autowired
    private TravellerMapper travellerMapper;

    @Autowired
    private RegionMapper regionMapper;

    @Override
    public Object pageForRegin(TravellerDto travellerDto) {
    
    

        Page<Traveller> pageRequest = new Page<>(travellerDto.getCurrent(),travellerDto.getSize());


        List<Object> travellerIds = new ArrayList<>();

        //如果有地址,查出对应地址对应的id
        if(travellerDto.getRegionLocation()!=null && !"".equals(travellerDto.getRegionLocation())){
    
    
            travellerIds = regionMapper.selectObjs(new LambdaQueryWrapper<Region>().eq(Region::getRegionLocation, travellerDto.getRegionLocation()).select(Region::getUserId));
        }

        return travellerMapper.pageForRegin(pageRequest,travellerDto.getUserName(),travellerIds);
    }
}

编写mapper层

public interface TravellerMapper extends BaseMapper<Traveller> {
    
    

    IPage<Traveller> pageForRegin(Page<Traveller> pageRequest, @Param("username") String username, @Param("travellerIds") List<Object> travellerIds);
}

编写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.cancan.mp.user.mapper.TravellerMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.cancan.mp.user.entity.Traveller">
        <id column="id" property="id" />
        <result column="user_name" property="userName" />
        <result column="user_sex" property="userSex" />

        <collection property="regions" column="id"
                    select="com.cancan.mp.user.mapper.RegionMapper.listById">
        </collection>

    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, user_name, user_sex
    </sql>



    <select id="pageForRegin" resultMap="BaseResultMap">
        select
            id,
            user_name,
            user_sex
        from
            user_traveller
        <where>
            <if test="username != null and username !=''">
                and user_name = #{username}
            </if>
            <if test="travellerIds.size != 0">
                and id in <foreach  item="travellerId" collection="travellerIds" open="(" separator="," close=")">#{travellerId}</foreach>
            </if>
        </where>


    </select>

</mapper>
<?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.cancan.mp.user.mapper.RegionMapper">

    <!-- 通用查询映射结果 -->
    <resultMap id="BaseResultMap" type="com.cancan.mp.user.entity.Region">
        <id column="id" property="id" />
        <result column="user_id" property="userId" />
        <result column="region_code" property="regionCode" />
        <result column="region_location" property="regionLocation" />
    </resultMap>

    <!-- 通用查询结果列 -->
    <sql id="Base_Column_List">
        id, user_id, region_code, region_location
    </sql>

    <select id="listById" resultMap="BaseResultMap">
        select
            region_code,
            region_location
        from user_region
        where user_id = #{id}
    </select>

</mapper>

2.4 细节(分页插件和mapper扫描)

@SpringBootApplication
@MapperScan("com.cancan.mp.*.mapper")
public class MpApplication {
    
    

	public static void main(String[] args) {
    
    
		SpringApplication.run(MpApplication.class, args);
	}



	@Bean
	public PaginationInterceptor paginationInterceptor() {
    
    
		PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
		// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
		// paginationInterceptor.setOverflow(false);
		// 设置最大单页限制数量,默认 500 条,-1 不受限制
		// paginationInterceptor.setLimit(500);
		// 开启 count 的 join 优化,只针对部分 left join
		paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
		return paginationInterceptor;
	}

}

依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.pci.mp_demo02</groupId>
    <artifactId>mp_demo02</artifactId>
    <version>1.0.0</version>


    <properties>
        <mybatisplus.version>3.2.0</mybatisplus.version>
        <mybatis-plus-generator.version>3.3.1.tmp</mybatis-plus-generator.version>
        <commons-beanutils.version>1.9.3</commons-beanutils.version>
        <alibaba.druid.version>1.0.29</alibaba.druid.version>
        <mysql.connector.version>5.1.38</mysql.connector.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.3.1.tmp</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.7.0</version>
        </dependency>
        <!-- 引入Druid依赖,阿里巴巴所提供的数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${alibaba.druid.version}</version>
        </dependency>
        <!-- 提供mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.connector.version}</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*</include>
                </includes>
                <filtering>false</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

</project>

三、结尾

大部分的程序员,都是面向百度或者谷歌进行编程的,而网上的资料乱七八糟,有时候找起来让人难受,于是本人无偿进行资料收集的工作,大部分资料都是本人实打实收集的而且测试过,大家不用怀疑准确性,奈何能力有限,免于遗漏,希望读者可以在评论或者私信我,进行改正,大家一起为互联网技术做贡献。


收集资料枯燥无味,如果本文对你有帮助,可以点个赞,这个也是对我最大的鼓励和赞许。

本人行不改名坐不改姓,潮汕的灿灿展

立志在互联网这一行,做出自己的贡献


猜你喜欢

转载自blog.csdn.net/qq_34168515/article/details/110354851