从零开发校园墙微信小程序(5)——Spring Boot+MyBatis Plus后端架构搭建指南


一、技术栈选型

1.1 核心组件

技术版本作用
Spring Boot3.1.5快速构建基础框架
MyBatis Plus3.5.3.1增强ORM操作
MySQL8.0+数据存储
Lombok1.18.28简化POJO编写
Swagger3.0.0API文档生成

二、项目初始化

2.1 使用Spring Initializr创建项目

<!-- pom.xml核心依赖 -->
<dependencies>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    <dependency>
        <groupId>com.github.jsqlparser</groupId>
        <artifactId>jsqlparser</artifactId>
        <version>4.6</version>
    </dependency>
</dependencies>

三、MyBatis Plus集成

3.1 配置数据源

# application.yml
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/campus_wall?useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password: 123456

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      logic-delete-field: deleted  # 逻辑删除字段
      logic-delete-value: 1
      logic-not-delete-value: 0

3.2 代码生成器配置

public class CodeGenerator {
    public static void main(String[] args) {
        AutoGenerator generator = new AutoGenerator();
        
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig.Builder(
            "jdbc:mysql://localhost:3306/campus_wall",
            "root",
            "123456")
            .build();
        
        // 全局配置
        GlobalConfig gc = new GlobalConfig.Builder()
            .outputDir(System.getProperty("user.dir") + "/src/main/java")
            .author("开发者")
            .enableSwagger()
            .build();

        // 包配置
        PackageConfig pc = new PackageConfig.Builder()
            .parent("com.campus.wall")
            .entity("model.entity")
            .mapper("mapper")
            .build();

        // 策略配置
        StrategyConfig strategy = new StrategyConfig.Builder()
            .addInclude("status", "comments") // 生成指定表
            .entityBuilder()
            .enableLombok()
            .enableTableFieldAnnotation()
            .build();

        generator.dataSource(dsc)
            .global(gc)
            .packageInfo(pc)
            .strategy(strategy)
            .execute();
    }
}

四、核心功能实现

4.1 实体类定义(使用MP注解)

@Data
@TableName("status")
public class Status {
    @TableId(type = IdType.AUTO)
    private Long id;
    private String content;
    private String images;
    private String openid;
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    @Version
    private Integer version;
}

4.2 Mapper接口开发

public interface StatusMapper extends BaseMapper<Status> {
    @Select("SELECT * FROM status WHERE content LIKE CONCAT('%',#{keyword},'%')")
    List<Status> searchByKeyword(@Param("keyword") String keyword);
}

4.3 Service层实现

@Service
public class StatusService {

    private final StatusMapper statusMapper;

    // 分页查询(使用MP分页插件)
    public Page<Status> getStatusPage(String keyword, int pageNum, int pageSize) {
        Page<Status> page = new Page<>(pageNum, pageSize);
        QueryWrapper<Status> wrapper = new QueryWrapper<>();
        wrapper.like(StringUtils.isNotBlank(keyword), "content", keyword);
        return statusMapper.selectPage(page, wrapper);
    }

    // 使用Lambda表达式构建查询
    public List<Status> getLatestStatus(int limit) {
        LambdaQueryWrapper<Status> wrapper = Wrappers.lambdaQuery();
        wrapper.orderByDesc(Status::getCreateTime).last("LIMIT " + limit);
        return statusMapper.selectList(wrapper);
    }
}

五、Controller优化实现

5.1 投稿接口优化

@PostMapping("/sendStatus")
public Result sendStatus(@RequestParam MultipartFile file,
                        @RequestParam String text,
                        @RequestParam String openid) {
    try {
        // 1. 文件上传处理
        String imageUrl = fileStorageService.upload(file);
        
        // 2. 构建实体
        Status status = new Status();
        status.setContent(text);
        status.setOpenid(openid);
        status.setImages(imageUrl);

        // 3. 数据库保存(使用MP的save方法)
        statusMapper.insert(status);
        
        return Result.success("投稿成功");
    } catch (Exception e) {
        log.error("投稿失败", e);
        return Result.fail(500, "系统繁忙");
    }
}

5.2 分页查询接口

@GetMapping("/statusList")
public Result getStatusList(
    @RequestParam(required = false) String keyword,
    @RequestParam(defaultValue = "1") Integer page,
    @RequestParam(defaultValue = "10") Integer size) {
    
    Page<Status> pageResult = statusService.getStatusPage(keyword, page, size);
    Map<String, Object> result = new HashMap<>();
    result.put("list", pageResult.getRecords());
    result.put("total", pageResult.getTotal());
    return Result.success(result);
}

六、最佳实践建议

6.1 分页插件配置

@Configuration
public class MybatisPlusConfig {
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        // 乐观锁插件
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
}

6.2 自动填充配置

@Component
public class MetaHandler implements MetaObjectHandler {
    
    @Override
    public void insertFill(MetaObject metaObject) {
        this.strictInsertFill(metaObject, "createTime", LocalDateTime::now, LocalDateTime.class);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime::now, LocalDateTime.class);
    }
}

七、常见问题解决方案

7.1 分页失效排查

  1. 检查是否配置分页插件
  2. 确保Page参数是第一个参数
  3. 验证SQL是否包含LIMIT语句

7.2 逻辑删除实现

// 实体类添加注解
@TableLogic
private Integer deleted;

// 查询自动过滤已删除数据
wrapper.eq(Status::getDeleted, 0);

7.3 多数据源配置

@Configuration
@MapperScan(basePackages = "com.campus.wall.mapper.db1", sqlSessionFactoryRef = "db1SqlSessionFactory")
public class Db1DataSourceConfig {
    // 配置主数据源...
}

@Configuration
@MapperScan(basePackages = "com.campus.wall.mapper.db2", sqlSessionFactoryRef = "db2SqlSessionFactory")
public class Db2DataSourceConfig {
    // 配置从数据源...
}

八、性能优化建议

  1. 二级缓存配置

    mybatis-plus:
      configuration:
     cache-enabled: true
  2. 批量插入优化

    List<Status> batchList = new ArrayList<>();
    // ...填充数据
    statusMapper.insertBatchSomeColumn(batchList);
  3. SQL打印格式化

    @Bean
    public PerformanceInterceptor performanceInterceptor() {
     PerformanceInterceptor interceptor = new PerformanceInterceptor();
     interceptor.setFormat(true);
     return interceptor;
    }

开发心法
使用MyBatis Plus就像获得了一个智能工具箱——它能自动完成80%的常规数据库操作,但关键是要掌握其设计哲学。记住:

  1. 优先使用Lambda表达式构建查询
  2. 合理利用代码生成器
  3. 定期检查官方更新日志
  4. 复杂SQL仍建议使用XML方式管理

下一章预告:《高并发场景下的缓存策略设计》
你将学到:

  • Redis集成与缓存穿透解决方案
  • 二级缓存与本地缓存结合实践
  • 消息队列在异步处理中的应用
最后修改:2025 年 04 月 13 日
如果觉得我的文章对你有用,请随意赞赏