当前位置:   article > 正文

Mybatis-plus-join连表查询_mybatisplus 连表查询

mybatisplus 连表查询

目录

一、数据库DDL

二、JAVA代码

三、pom依赖和配置文件

     

        最近发现一个好玩的框架,我们知道mybatis-plus在连表查询上是不行的,如果需要连表查询,那么我们就得乖乖的去写xml文件了,但是今天发现一个新的框架 mybatis-plus-join。它既包含了mybatis-plus的所有优点,然后还支持连表查询,还支持对多,对一的查询,行了废话不多说直接看代码吧。

一、数据库DDL

测试的数据库,本测试基于mysql数据库

  1. /*
  2. Navicat Premium Data Transfer
  3. Source Server : 本地数据库
  4. Source Server Type : MySQL
  5. Source Server Version : 50710
  6. Source Host : localhost:3306
  7. Source Schema : test-1
  8. Target Server Type : MySQL
  9. Target Server Version : 50710
  10. File Encoding : 65001
  11. Date: 07/12/2022 15:35:14
  12. */
  13. SET NAMES utf8mb4;
  14. SET FOREIGN_KEY_CHECKS = 0;
  15. -- ----------------------------
  16. -- Table structure for tb_dept
  17. -- ----------------------------
  18. DROP TABLE IF EXISTS `tb_dept`;
  19. CREATE TABLE `tb_dept` (
  20. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  21. `dept_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '部门名称',
  22. `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
  23. `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0),
  24. PRIMARY KEY (`id`) USING BTREE
  25. ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '部门' ROW_FORMAT = Dynamic;
  26. -- ----------------------------
  27. -- Records of tb_dept
  28. -- ----------------------------
  29. INSERT INTO `tb_dept` VALUES (1, '人事部', '2022-12-07 13:06:06', '2022-12-07 13:06:06');
  30. INSERT INTO `tb_dept` VALUES (2, '采购部', '2022-12-07 13:06:13', '2022-12-07 13:06:13');
  31. INSERT INTO `tb_dept` VALUES (3, '开发部', '2022-12-07 13:06:17', '2022-12-07 13:06:17');
  32. -- ----------------------------
  33. -- Table structure for tb_post
  34. -- ----------------------------
  35. DROP TABLE IF EXISTS `tb_post`;
  36. CREATE TABLE `tb_post` (
  37. `id` int(11) NOT NULL AUTO_INCREMENT,
  38. `post_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '职位名称',
  39. PRIMARY KEY (`id`) USING BTREE
  40. ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '职位' ROW_FORMAT = Dynamic;
  41. -- ----------------------------
  42. -- Records of tb_post
  43. -- ----------------------------
  44. INSERT INTO `tb_post` VALUES (1, '人事经理');
  45. INSERT INTO `tb_post` VALUES (2, '人事专员');
  46. INSERT INTO `tb_post` VALUES (3, '采购经理');
  47. INSERT INTO `tb_post` VALUES (4, '采购专员');
  48. INSERT INTO `tb_post` VALUES (5, '技术总监');
  49. INSERT INTO `tb_post` VALUES (6, '技术经理');
  50. -- ----------------------------
  51. -- Table structure for tb_user
  52. -- ----------------------------
  53. DROP TABLE IF EXISTS `tb_user`;
  54. CREATE TABLE `tb_user` (
  55. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
  56. `user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '用户名',
  57. `post_id` int(11) NULL DEFAULT NULL COMMENT '职位id',
  58. `dept_id` int(11) NULL DEFAULT NULL COMMENT '部门id',
  59. `create_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '创建时间',
  60. `update_time` datetime(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0) ON UPDATE CURRENT_TIMESTAMP(0) COMMENT '修改时间',
  61. `created` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT 'snail' COMMENT '创建人',
  62. `updated` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT 'snail' COMMENT '修改人',
  63. PRIMARY KEY (`id`) USING BTREE
  64. ) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '测试用户表' ROW_FORMAT = Dynamic;
  65. -- ----------------------------
  66. -- Records of tb_user
  67. -- ----------------------------
  68. INSERT INTO `tb_user` VALUES (1, 'admin', 1, 1, '2022-12-07 12:03:20', '2022-12-07 12:03:20', 'snail', 'snail');
  69. INSERT INTO `tb_user` VALUES (2, 'test', 2, 1, '2022-12-07 12:03:51', '2022-12-07 12:03:51', 'snail', 'snail');
  70. INSERT INTO `tb_user` VALUES (3, 'test1', 1, 1, '2022-12-07 12:04:03', '2022-12-07 12:04:03', 'snail', 'snail');
  71. SET FOREIGN_KEY_CHECKS = 1;

二、JAVA代码

实体类

  1. package com.wssnail.model;
  2. import com.baomidou.mybatisplus.annotation.TableName;
  3. import com.baomidou.mybatisplus.annotation.IdType;
  4. import com.baomidou.mybatisplus.annotation.TableId;
  5. import java.time.LocalDateTime;
  6. import java.io.Serializable;
  7. import io.swagger.annotations.ApiModel;
  8. import io.swagger.annotations.ApiModelProperty;
  9. import lombok.Data;
  10. import lombok.EqualsAndHashCode;
  11. /**
  12. * <p>
  13. * 测试用户表
  14. * </p>
  15. *
  16. * @author 熟透的蜗牛
  17. * @since 2022-12-07
  18. */
  19. @Data
  20. @EqualsAndHashCode(callSuper = false)
  21. @TableName("tb_user")
  22. @ApiModel(value="User对象", description="测试用户表")
  23. public class User implements Serializable {
  24. private static final long serialVersionUID = 1L;
  25. @ApiModelProperty(value = "主键")
  26. @TableId(value = "id", type = IdType.AUTO)
  27. private Integer id;
  28. @ApiModelProperty(value = "用户名")
  29. private String userName;
  30. @ApiModelProperty(value = "职位id")
  31. private Integer postId;
  32. @ApiModelProperty(value = "部门id")
  33. private Integer deptId;
  34. @ApiModelProperty(value = "创建时间")
  35. private LocalDateTime createTime;
  36. @ApiModelProperty(value = "修改时间")
  37. private LocalDateTime updateTime;
  38. @ApiModelProperty(value = "创建人")
  39. private String created;
  40. @ApiModelProperty(value = "修改人")
  41. private String updated;
  42. }

        

  1. package com.wssnail.model;
  2. import com.baomidou.mybatisplus.annotation.TableName;
  3. import com.baomidou.mybatisplus.annotation.IdType;
  4. import com.baomidou.mybatisplus.annotation.TableId;
  5. import java.io.Serializable;
  6. import io.swagger.annotations.ApiModel;
  7. import io.swagger.annotations.ApiModelProperty;
  8. import lombok.Data;
  9. import lombok.EqualsAndHashCode;
  10. /**
  11. * <p>
  12. * 职位
  13. * </p>
  14. *
  15. * @author 熟透的蜗牛
  16. * @since 2022-12-07
  17. */
  18. @Data
  19. @EqualsAndHashCode(callSuper = false)
  20. @TableName("tb_post")
  21. @ApiModel(value="Post对象", description="职位")
  22. public class Post implements Serializable {
  23. private static final long serialVersionUID = 1L;
  24. @TableId(value = "id", type = IdType.AUTO)
  25. private Integer id;
  26. @ApiModelProperty(value = "职位名称")
  27. private String postName;
  28. }
  1. package com.wssnail.model;
  2. import com.baomidou.mybatisplus.annotation.IdType;
  3. import java.time.LocalDateTime;
  4. import java.io.Serializable;
  5. import com.baomidou.mybatisplus.annotation.TableId;
  6. import com.baomidou.mybatisplus.annotation.TableName;
  7. import io.swagger.annotations.ApiModel;
  8. import io.swagger.annotations.ApiModelProperty;
  9. import lombok.Data;
  10. import lombok.EqualsAndHashCode;
  11. /**
  12. * <p>
  13. * 部门
  14. * </p>
  15. *
  16. * @author 熟透的蜗牛
  17. * @since 2022-12-07
  18. */
  19. @Data
  20. @EqualsAndHashCode(callSuper = false)
  21. @TableName("tb_dept")
  22. @ApiModel(value="Dept对象", description="部门")
  23. public class Dept implements Serializable {
  24. private static final long serialVersionUID = 1L;
  25. @ApiModelProperty(value = "主键")
  26. @TableId(value = "id", type = IdType.AUTO)
  27. private Integer id;
  28. @ApiModelProperty(value = "部门名称")
  29. private String deptName;
  30. private LocalDateTime createTime;
  31. private LocalDateTime updateTime;
  32. }

业务实体类

 

  1. package com.wssnail.model.bo;
  2. import com.wssnail.model.Post;
  3. import com.wssnail.model.User;
  4. import lombok.Data;
  5. import java.util.List;
  6. /**
  7. * @Author: 熟透的蜗牛
  8. * @CreateTime: 2022-12-07 13:57
  9. * @Description: 一个岗位下有多个人
  10. * @Version: 1.0
  11. */
  12. @Data
  13. public class PostUserDo extends Post {
  14. private List<User> userList;
  15. }

 

  1. package com.wssnail.model.bo;
  2. import com.wssnail.model.User;
  3. import lombok.Data;
  4. /**
  5. * @Author: 熟透的蜗牛
  6. * @CreateTime: 2022-12-07 13:57
  7. * @Description: TODO
  8. * @Version: 1.0
  9. */
  10. @Data
  11. public class UserDo extends User {
  12. //岗位名称
  13. private String postName;
  14. //部门名称
  15. private String deptName;
  16. }

mapper接口,注意接口不再继承BaseMapper 而是继承了MPJBaseMapper

  1. @Repository
  2. public interface DeptMapper extends MPJBaseMapper<Dept> {
  3. }
  4. @Repository
  5. public interface PostMapper extends MPJBaseMapper<Post> {
  6. }
  7. @Repository
  8. public interface UserMapper extends MPJBaseMapper<User> {
  9. }

service接口也不是继承BaseService而是继承了MPJBaseService,这个继承不是必须的,我这里实现了继承

  1. public interface UserService extends MPJBaseService<User> {
  2. List<UserDo> listByPage(String postName, String userName);
  3. }
  4. public interface PostService extends MPJBaseService<Post> {
  5. List <PostUserDo> listPostUser();
  6. }
  7. public interface DeptService extends MPJBaseService<Dept> {
  8. }

service接口实现类,代码里有详细注释

简单的连表查询

  1. package com.wssnail.service.impl;
  2. import com.baomidou.mybatisplus.core.metadata.IPage;
  3. import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
  4. import com.github.yulichang.base.MPJBaseServiceImpl;
  5. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  6. import com.wssnail.mapper.UserMapper;
  7. import com.wssnail.model.Dept;
  8. import com.wssnail.model.Post;
  9. import com.wssnail.model.User;
  10. import com.wssnail.model.bo.UserDo;
  11. import com.wssnail.service.UserService;
  12. import org.springframework.beans.factory.annotation.Autowired;
  13. import org.springframework.stereotype.Service;
  14. import java.util.List;
  15. /**
  16. * <p>
  17. * 测试用户表 服务实现类
  18. * </p>
  19. *
  20. * @author 熟透的蜗牛
  21. * @since 2022-12-07
  22. */
  23. @Service
  24. public class UserServiceImpl extends MPJBaseServiceImpl<UserMapper, User> implements UserService {
  25. @Autowired
  26. private UserMapper userMapper; //这里对应主表的mapper
  27. /*
  28. * @description:
  29. * 连表分页查询,以下示例代码为左连接查询
  30. * 内连接方法 innerJoin()
  31. * 右连接方法 rightJoin() 和这个使用方法一样
  32. * @date: 2022/12/7 14:05
  33. * @param postName
  34. * @param userName
  35. * @return: java.util.List<com.wssnail.model.bo.UserDo>
  36. **/
  37. @Override
  38. public List<UserDo> listByPage(String postName, String userName) {
  39. MPJLambdaWrapper<User> userMPJLambdaWrapper = new MPJLambdaWrapper<User>()
  40. .selectAll(User.class) //查询主表所有的字段
  41. .select(Dept::getDeptName) //查询部门表的部门名称
  42. .select(Post::getPostName) //查询岗位表的 岗位名称
  43. .leftJoin(Dept.class, Dept::getId, User::getDeptId) //左连接查询,相当于 left join dept on dept.id=user.dept_id
  44. .leftJoin(Post.class, Post::getId, User::getPostId) // 左连接查询,相当于 left join post on post.id=user.post_id
  45. .eq(Post::getPostName, postName)
  46. .like(User::getUserName, userName);
  47. //返回自定义的数据,相当于执行如下SQL,可以看出主表别名为t 其他表名依次为t1,t2.........
  48. // SELECT
  49. // t.id,
  50. // t.user_name,
  51. // t.post_id,
  52. // t.dept_id,
  53. // t.create_time,
  54. // t.update_time,
  55. // t.created,
  56. // t.updated,
  57. // t1.dept_name,
  58. // t2.post_name
  59. // FROM
  60. // tb_user t
  61. // LEFT JOIN tb_dept t1 ON ( t1.id = t.dept_id )
  62. // LEFT JOIN tb_post t2 ON ( t2.id = t.post_id )
  63. // WHERE
  64. // (
  65. // t2.post_name = ?
  66. // AND t.user_name LIKE ?)
  67. // List<UserDo> userDos = userMapper.selectJoinList(UserDo.class, userMPJLambdaWrapper);
  68. // return userDos;
  69. //分页查询等于执行如下SQL,分页查询需要 配置mybatis plus 分页插件,详情见 com.wssnail.config.MybatisPageConfig 类
  70. // SELECT
  71. // t.id,
  72. // t.user_name,
  73. // t.post_id,
  74. // t.dept_id,
  75. // t.create_time,
  76. // t.update_time,
  77. // t.created,
  78. // t.updated,
  79. // t1.dept_name,
  80. // t2.post_name
  81. // FROM
  82. // tb_user t
  83. // LEFT JOIN tb_dept t1 ON ( t1.id = t.dept_id )
  84. // LEFT JOIN tb_post t2 ON ( t2.id = t.post_id )
  85. // WHERE
  86. // (
  87. // t2.post_name = ?
  88. // AND t.user_name LIKE ?)
  89. // LIMIT ?
  90. Page<User> page = new Page<>();
  91. IPage<UserDo> userDoIPage = userMapper.selectJoinPage(page, UserDo.class, userMPJLambdaWrapper);
  92. return userDoIPage.getRecords();
  93. }
  94. }

对多查询

  1. package com.wssnail.service.impl;
  2. import com.github.yulichang.base.MPJBaseServiceImpl;
  3. import com.github.yulichang.wrapper.MPJLambdaWrapper;
  4. import com.wssnail.mapper.PostMapper;
  5. import com.wssnail.model.Post;
  6. import com.wssnail.model.User;
  7. import com.wssnail.model.bo.PostUserDo;
  8. import com.wssnail.service.PostService;
  9. import org.springframework.beans.factory.annotation.Autowired;
  10. import org.springframework.stereotype.Service;
  11. import java.util.List;
  12. /**
  13. * <p>
  14. * 职位 服务实现类
  15. * </p>
  16. *
  17. * @author 熟透的蜗牛
  18. * @since 2022-12-07
  19. */
  20. @Service
  21. public class PostServiceImpl extends MPJBaseServiceImpl<PostMapper, Post> implements PostService {
  22. @Autowired
  23. private PostMapper postMapper;
  24. @Override
  25. public List<PostUserDo> listPostUser() {
  26. //相当于执行如下SQL ,以下示例代码是对多查询,对一查询使用 selectAssociation()方法,用法与此相同
  27. // SELECT
  28. // t.id,
  29. // t.post_name,
  30. // t1.id AS join_id,
  31. // t1.user_name,
  32. // t1.post_id,
  33. // t1.dept_id,
  34. // t1.create_time,
  35. // t1.update_time,
  36. // t1.created,
  37. // t1.updated
  38. // FROM
  39. // tb_post t
  40. // LEFT JOIN tb_user t1 ON (
  41. // t1.post_id = t.id)
  42. // 等价于 如下的xml配置
  43. // <resultMap id="xxxxxxxx" type="com.wssnail.model.bo.PostUserDo">
  44. // <result property="id" column="id"/>
  45. // <result property="postName" column="post_name"/>
  46. // <!--其他属性省略-->
  47. // <collection property="userList" javaType="java.util.List"
  48. // ofType="com.wssnail.model.User">
  49. // <id property="id" column="id"/>
  50. // <result property="userName" column="user_name"/>
  51. // <!--其他属性省略-->
  52. // </collection>
  53. // </resultMap>
  54. //返回数据如下 ,注意由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。
  55. // [{
  56. // "id": 1,
  57. // "postName": "人事经理",
  58. // "userList": [{
  59. // "id": 1,
  60. // "userName": "admin",
  61. // "postId": 1,
  62. // "deptId": 1,
  63. // "createTime": "2022-12-07T12:03:20",
  64. // "updateTime": "2022-12-07T12:03:20",
  65. // "created": "snail",
  66. // "updated": "snail"
  67. // }, {
  68. // "id": 3,
  69. // "userName": "test1",
  70. // "postId": 1,
  71. // "deptId": 1,
  72. // "createTime": "2022-12-07T12:04:03",
  73. // "updateTime": "2022-12-07T12:04:03",
  74. // "created": "snail",
  75. // "updated": "snail"
  76. // }]
  77. // }, {
  78. // "id": 2,
  79. // "postName": "人事专员",
  80. // "userList": [{
  81. // "id": 2,
  82. // "userName": "test",
  83. // "postId": 2,
  84. // "deptId": 1,
  85. // "createTime": "2022-12-07T12:03:51",
  86. // "updateTime": "2022-12-07T12:03:51",
  87. // "created": "snail",
  88. // "updated": "snail"
  89. // }]
  90. // }, {
  91. // "id": 3,
  92. // "postName": "采购经理",
  93. // "userList": []
  94. // }]
  95. MPJLambdaWrapper<Post> postMPJLambdaWrapper = new MPJLambdaWrapper<Post>().selectAll(Post.class)
  96. .selectCollection(User.class, PostUserDo::getUserList)
  97. .leftJoin(User.class, User::getPostId, Post::getId);//一对多查询
  98. List<PostUserDo> postUserDos = postMapper.selectJoinList(PostUserDo.class, postMPJLambdaWrapper);
  99. return postUserDos;
  100. }
  101. }

分页配置 

  1. package com.wssnail.config;
  2. import com.baomidou.mybatisplus.annotation.DbType;
  3. import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
  4. import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
  5. import org.springframework.context.annotation.Bean;
  6. import org.springframework.context.annotation.Configuration;
  7. @Configuration
  8. public class MybatisPageConfig {
  9. @Bean
  10. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  11. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  12. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  13. return interceptor;
  14. }
  15. }

三、pom依赖和配置文件

  1. server:
  2. port: 8090
  3. spring:
  4. application:
  5. name: test
  6. datasource:
  7. url: jdbc:mysql://127.0.0.1:3306/test-1?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
  8. username: root
  9. password: snail
  10. pagehelper:
  11. helper-dialect: mysql
  12. reasonable: true
  13. support-methods-arguments: false
  14. params: count=countsql
  15. #打印sql
  16. mybatis-plus:
  17. configuration:
  18. mapper-locations: classpath*:mapper/*Mapper.xml
  19. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5. <modelVersion>4.0.0</modelVersion>
  6. <groupId>com.wssnail</groupId>
  7. <artifactId>test-mybatis-plus-join</artifactId>
  8. <version>1.0-SNAPSHOT</version>
  9. <properties>
  10. <maven.compiler.source>8</maven.compiler.source>
  11. <maven.compiler.target>8</maven.compiler.target>
  12. </properties>
  13. <parent>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-starter-parent</artifactId>
  16. <version>2.4.2</version>
  17. <relativePath/>
  18. </parent>
  19. <dependencies>
  20. <dependency>
  21. <groupId>org.springframework.boot</groupId>
  22. <artifactId>spring-boot-starter-web</artifactId>
  23. </dependency>
  24. <dependency>
  25. <groupId>mysql</groupId>
  26. <artifactId>mysql-connector-java</artifactId>
  27. </dependency>
  28. <dependency>
  29. <groupId>org.apache.commons</groupId>
  30. <artifactId>commons-lang3</artifactId>
  31. <version>3.12.0</version>
  32. </dependency>
  33. <dependency>
  34. <groupId>com.baomidou</groupId>
  35. <artifactId>mybatis-plus-boot-starter</artifactId>
  36. <version>3.5.2</version>
  37. </dependency>
  38. <dependency>
  39. <groupId>com.github.yulichang</groupId>
  40. <artifactId>mybatis-plus-join-boot-starter</artifactId>
  41. <version>1.3.8</version>
  42. </dependency>
  43. <!--swagger-->
  44. <dependency>
  45. <groupId>com.spring4all</groupId>
  46. <artifactId>swagger-spring-boot-starter</artifactId>
  47. <version>1.9.1.RELEASE</version>
  48. </dependency>
  49. <dependency>
  50. <groupId>com.github.xiaoymin</groupId>
  51. <artifactId>swagger-bootstrap-ui</artifactId>
  52. <version>1.9.6</version>
  53. </dependency>
  54. <dependency>
  55. <groupId>org.projectlombok</groupId>
  56. <artifactId>lombok</artifactId>
  57. <version>1.18.24</version>
  58. </dependency>
  59. </dependencies>
  60. </project>

以上就是本人测试的结果,还有很多使用方法没有一一验证,如果感兴趣的可以参考源代码,自己动手试试

https://gitee.com/best_handsome/mybatis-plus-join 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/625020
推荐阅读
相关标签
  

闽ICP备14008679号