Spring Boot + MyBatis Plus 最佳实践:从代码生成到数据库优化的全流程指南

Arthur481
Arthur481 2026-02-07T22:03:09+08:00
0 0 0

引言

在现代Java企业级应用开发中,Spring Boot与MyBatis Plus的组合已经成为主流的技术栈选择。Spring Boot凭借其"约定优于配置"的理念,极大地简化了Spring应用的初始搭建和开发过程;而MyBatis Plus作为MyBatis的增强工具,在保留MyBatis原有特性的同时,提供了更加便捷的CRUD操作和丰富的插件功能。

本文将从实际项目需求出发,系统性地介绍Spring Boot与MyBatis Plus的最佳实践方案,涵盖代码自动生成、SQL优化、分页查询、事务管理等核心功能,为开发者提供一套完整的开发指南。

环境准备与依赖配置

项目基础环境

在开始之前,我们需要准备以下开发环境:

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <!-- MyBatis Plus Starter -->
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.5.3.1</version>
    </dependency>
    
    <!-- 数据库驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    
    <!-- 数据库连接池 -->
    <dependency>
        <groupId>com.zaxxer</groupId>
        <artifactId>HikariCP</artifactId>
    </dependency>
    
    <!-- Lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

配置文件设置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000

mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  global-config:
    db-config:
      id-type: auto

代码自动生成实践

MyBatis Plus Generator核心配置

MyBatis Plus提供了强大的代码生成器,可以快速生成Mapper、Entity、Service等基础代码:

@Configuration
public class CodeGenerator {
    
    public static void main(String[] args) {
        AutoGenerator mpg = new AutoGenerator();
        
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("author");
        gc.setOpen(false);
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);
        
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/test_db?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("password");
        mpg.setDataSource(dSource);
        
        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName("user");
        pc.setParent("com.example.demo");
        mpg.setPackageInfo(pc);
        
        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setInclude("user_info");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        
        mpg.execute();
    }
}

自定义代码生成模板

为了满足特定需求,我们可以自定义代码生成模板:

public class CustomCodeGenerator {
    
    public static void generateCustomCode() {
        AutoGenerator mpg = new AutoGenerator();
        
        // 设置自定义模板
        TemplateConfig templateConfig = new TemplateConfig();
        templateConfig.setEntity("/templates/entity.java.vm");
        templateConfig.setMapper("/templates/mapper.java.vm");
        templateConfig.setService("/templates/service.java.vm");
        templateConfig.setServiceImpl("/templates/serviceImpl.java.vm");
        templateConfig.setController("/templates/controller.java.vm");
        mpg.setTemplate(templateConfig);
        
        // 其他配置...
        mpg.execute();
    }
}

实体类设计与注解使用

基础实体类结构

@TableName("user_info")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 主键ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    
    /**
     * 用户名
     */
    @TableField("user_name")
    private String userName;
    
    /**
     * 邮箱
     */
    private String email;
    
    /**
     * 创建时间
     */
    @TableField("create_time")
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    @TableField("update_time")
    private LocalDateTime updateTime;
    
    /**
     * 状态:0-禁用,1-启用
     */
    private Integer status;
}

高级注解使用

@TableName("user_info")
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class UserInfo extends Model<UserInfo> {
    
    /**
     * 主键ID
     */
    @TableId(value = "id", type = IdType.ASSIGN_ID)
    private Long id;
    
    /**
     * 用户名(唯一)
     */
    @TableField("user_name")
    @NotBlank(message = "用户名不能为空")
    @Size(min = 3, max = 20, message = "用户名长度必须在3-20之间")
    private String userName;
    
    /**
     * 邮箱
     */
    @Email(message = "邮箱格式不正确")
    private String email;
    
    /**
     * 密码
     */
    @TableField(exist = false)
    private String password;
    
    /**
     * 创建时间
     */
    @TableField("create_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime createTime;
    
    /**
     * 更新时间
     */
    @TableField("update_time")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private LocalDateTime updateTime;
    
    /**
     * 版本号(用于乐观锁)
     */
    @Version
    @TableField("version")
    private Integer version;
    
    /**
     * 逻辑删除字段
     */
    @TableLogic
    @TableField("deleted")
    private Integer deleted;
}

Mapper层设计与使用

基础Mapper接口

@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
    
    /**
     * 根据用户名查询用户信息
     */
    UserInfo selectByUsername(@Param("username") String username);
    
    /**
     * 批量插入用户
     */
    int insertBatchSomeColumn(List<UserInfo> entityList);
    
    /**
     * 分页查询用户列表
     */
    IPage<UserInfo> selectUserPage(Page<UserInfo> page, @Param("status") Integer status);
}

自定义SQL方法

@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
    
    /**
     * 复杂条件查询
     */
    @Select("SELECT * FROM user_info WHERE status = #{status} AND create_time >= #{startTime}")
    List<UserInfo> selectByStatusAndTime(@Param("status") Integer status, 
                                       @Param("startTime") LocalDateTime startTime);
    
    /**
     * 使用XML配置复杂SQL
     */
    List<UserInfo> selectUserWithRole(@Param("userId") Long userId);
}

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.demo.mapper.UserInfoMapper">
    
    <select id="selectUserWithRole" resultType="com.example.demo.entity.UserInfo">
        SELECT u.*, r.role_name 
        FROM user_info u
        LEFT JOIN user_role ur ON u.id = ur.user_id
        LEFT JOIN role r ON ur.role_id = r.id
        WHERE u.id = #{userId}
    </select>
    
    <select id="selectUserPage" resultType="com.example.demo.entity.UserInfo">
        SELECT * FROM user_info 
        <where>
            <if test="status != null">
                status = #{status}
            </if>
        </where>
        ORDER BY create_time DESC
    </select>
</mapper>

Service层最佳实践

基础Service实现

@Service
@Transactional(rollbackFor = Exception.class)
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    /**
     * 根据用户名获取用户信息
     */
    @Override
    public UserInfo getUserByUsername(String username) {
        return userInfoMapper.selectByUsername(username);
    }
    
    /**
     * 分页查询用户列表
     */
    @Override
    public IPage<UserInfo> getUserPage(int current, int size, Integer status) {
        Page<UserInfo> page = new Page<>(current, size);
        return userInfoMapper.selectUserPage(page, status);
    }
    
    /**
     * 批量删除用户(逻辑删除)
     */
    @Override
    public boolean deleteBatchByIds(List<Long> ids) {
        List<UserInfo> updateList = ids.stream()
            .map(id -> {
                UserInfo user = new UserInfo();
                user.setId(id);
                user.setDeleted(1);
                return user;
            })
            .collect(Collectors.toList());
        
        return this.updateBatchById(updateList);
    }
}

高级Service功能

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    /**
     * 带缓存的用户查询
     */
    @Override
    public UserInfo getUserWithCache(Long userId) {
        String cacheKey = "user_info:" + userId;
        UserInfo user = (UserInfo) redisTemplate.opsForValue().get(cacheKey);
        
        if (user == null) {
            user = this.getById(userId);
            if (user != null) {
                redisTemplate.opsForValue().set(cacheKey, user, 30, TimeUnit.MINUTES);
            }
        }
        
        return user;
    }
    
    /**
     * 事务管理的复杂业务逻辑
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createUserWithRole(UserInfo userInfo, Long roleId) {
        try {
            // 插入用户
            this.save(userInfo);
            
            // 关联角色
            UserRole userRole = new UserRole();
            userRole.setUserId(userInfo.getId());
            userRole.setRoleId(roleId);
            userRole.setCreateTime(LocalDateTime.now());
            
            // 这里需要注入UserRoleMapper
            // userRoleMapper.insert(userRole);
            
            return true;
        } catch (Exception e) {
            log.error("创建用户失败", e);
            throw new RuntimeException("创建用户失败");
        }
    }
    
    /**
     * 批量操作优化
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchUpdateStatus(List<Long> ids, Integer status) {
        List<UserInfo> updateList = ids.stream()
            .map(id -> {
                UserInfo user = new UserInfo();
                user.setId(id);
                user.setStatus(status);
                user.setUpdateTime(LocalDateTime.now());
                return user;
            })
            .collect(Collectors.toList());
        
        return this.updateBatchById(updateList, 1000);
    }
}

分页查询优化

基础分页查询

@RestController
@RequestMapping("/user")
public class UserInfoController {
    
    @Autowired
    private UserInfoService userInfoService;
    
    /**
     * 分页查询用户列表
     */
    @GetMapping("/page")
    public Result<IPage<UserInfo>> getUserPage(
            @RequestParam(defaultValue = "1") int current,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) Integer status) {
        
        IPage<UserInfo> page = userInfoService.getUserPage(current, size, status);
        return Result.success(page);
    }
}

高级分页查询优化

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> implements UserInfoService {
    
    /**
     * 复杂条件分页查询
     */
    @Override
    public IPage<UserInfo> getUserPageWithCondition(Page<UserInfo> page, 
                                                   String keyword, 
                                                   Integer status,
                                                   LocalDateTime startTime,
                                                   LocalDateTime endTime) {
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        
        if (StringUtils.hasText(keyword)) {
            wrapper.like("user_name", keyword).or().like("email", keyword);
        }
        
        if (status != null) {
            wrapper.eq("status", status);
        }
        
        if (startTime != null && endTime != null) {
            wrapper.between("create_time", startTime, endTime);
        }
        
        return this.page(page, wrapper);
    }
    
    /**
     * 性能优化的分页查询
     */
    @Override
    public IPage<UserInfo> getOptimizedUserPage(Page<UserInfo> page, 
                                               String keyword, 
                                               Integer status) {
        // 使用select()只查询需要的字段,减少网络传输
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.select("id", "user_name", "email", "create_time", "status");
        
        if (StringUtils.hasText(keyword)) {
            wrapper.like("user_name", keyword);
        }
        
        if (status != null) {
            wrapper.eq("status", status);
        }
        
        return this.page(page, wrapper);
    }
}

分页查询性能优化策略

@Component
public class PageQueryOptimizer {
    
    /**
     * 大数据量分页优化
     */
    public IPage<UserInfo> optimizeLargeDataPage(Page<UserInfo> page, 
                                                String keyword, 
                                                Integer status) {
        // 1. 使用索引优化
        // 确保查询字段有合适的索引
        
        // 2. 限制查询范围
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        
        if (StringUtils.hasText(keyword)) {
            wrapper.like("user_name", keyword);
        }
        
        if (status != null) {
            wrapper.eq("status", status);
        }
        
        // 3. 使用游标分页优化大数据量
        return this.page(page, wrapper);
    }
    
    /**
     * 分页查询缓存策略
     */
    public IPage<UserInfo> getCachedPageResult(Page<UserInfo> page, 
                                              String cacheKey) {
        String redisKey = "page_cache:" + cacheKey;
        String cachedResult = (String) redisTemplate.opsForValue().get(redisKey);
        
        if (cachedResult != null) {
            // 反序列化缓存结果
            return JSON.parseObject(cachedResult, new TypeReference<IPage<UserInfo>>() {});
        }
        
        // 执行查询并缓存
        IPage<UserInfo> result = this.page(page);
        redisTemplate.opsForValue().set(redisKey, JSON.toJSONString(result), 5, TimeUnit.MINUTES);
        
        return result;
    }
}

SQL优化策略

基础SQL优化原则

@Service
public class UserInfoServiceImpl extends ServiceImpl<UserInfoMapper, UserInfo> {
    
    /**
     * 优化前的查询(存在性能问题)
     */
    public List<UserInfo> getOptimizationBefore() {
        // 不好的写法:全表扫描 + 多次查询
        return this.list();
    }
    
    /**
     * 优化后的查询
     */
    public List<UserInfo> getOptimizationAfter() {
        // 好的写法:只查询需要的字段,使用索引
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        wrapper.select("id", "user_name", "email") // 只选择必要字段
               .eq("status", 1)                   // 添加过滤条件
               .orderByDesc("create_time");       // 按时间倒序
        
        return this.list(wrapper);
    }
}

索引优化实践

@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
    
    /**
     * 带索引的查询方法
     */
    @Select("SELECT id, user_name, email FROM user_info WHERE status = #{status} AND create_time >= #{date}")
    List<UserInfo> selectByStatusAndDate(@Param("status") Integer status, 
                                       @Param("date") LocalDateTime date);
}

批量操作优化

@Service
public class UserInfoBatchService {
    
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    /**
     * 优化前的批量插入
     */
    public void batchInsertBefore(List<UserInfo> userList) {
        for (UserInfo user : userList) {
            userInfoMapper.insert(user);
        }
    }
    
    /**
     * 优化后的批量插入
     */
    public void batchInsertAfter(List<UserInfo> userList) {
        // 使用MyBatis Plus提供的批量插入方法
        if (CollectionUtils.isNotEmpty(userList)) {
            userInfoMapper.insertBatchSomeColumn(userList);
        }
    }
    
    /**
     * 分批处理大数据量
     */
    public void batchProcessInChunks(List<UserInfo> userList, int chunkSize) {
        List<List<UserInfo>> chunks = Lists.partition(userList, chunkSize);
        
        for (List<UserInfo> chunk : chunks) {
            userInfoMapper.insertBatchSomeColumn(chunk);
            // 添加适当的休眠,避免数据库压力过大
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
    }
}

事务管理最佳实践

基础事务配置

@Service
@Transactional(rollbackFor = Exception.class)
public class UserService {
    
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    @Autowired
    private UserRoleMapper userRoleMapper;
    
    /**
     * 用户注册事务
     */
    public boolean registerUser(UserInfo userInfo, List<Long> roleIds) {
        try {
            // 1. 插入用户
            userInfoMapper.insert(userInfo);
            
            // 2. 关联角色
            for (Long roleId : roleIds) {
                UserRole userRole = new UserRole();
                userRole.setUserId(userInfo.getId());
                userRole.setRoleId(roleId);
                userRoleMapper.insert(userRole);
            }
            
            return true;
        } catch (Exception e) {
            log.error("用户注册失败", e);
            throw new RuntimeException("用户注册失败");
        }
    }
}

事务传播行为使用

@Service
public class UserService {
    
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    /**
     * 外部调用,使用REQUIRED传播行为
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateUserWithRoles(Long userId, String userName, List<Long> roleIds) {
        // 更新用户信息
        UserInfo user = new UserInfo();
        user.setId(userId);
        user.setUserName(userName);
        userInfoMapper.updateById(user);
        
        // 更新角色关联(可能抛出异常)
        updateRoleAssociations(userId, roleIds);
    }
    
    /**
     * 内部方法,使用REQUIRES_NEW传播行为
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    private void updateRoleAssociations(Long userId, List<Long> roleIds) {
        // 删除旧关联
        userRoleMapper.deleteByUserId(userId);
        
        // 插入新关联
        for (Long roleId : roleIds) {
            UserRole userRole = new UserRole();
            userRole.setUserId(userId);
            userRole.setRoleId(roleId);
            userRoleMapper.insert(userRole);
        }
    }
}

异常处理与事务回滚

@Service
public class UserService {
    
    @Transactional(rollbackFor = Exception.class)
    public boolean complexBusinessOperation(UserInfo userInfo, List<Role> roles) {
        try {
            // 1. 验证用户信息
            validateUserInfo(userInfo);
            
            // 2. 插入用户
            userInfoMapper.insert(userInfo);
            
            // 3. 处理角色关联
            handleRoleAssociations(userInfo.getId(), roles);
            
            // 4. 记录操作日志
            logUserOperation(userInfo.getId(), "CREATE");
            
            return true;
        } catch (BusinessException e) {
            // 业务异常,记录日志但不回滚事务
            log.warn("业务异常: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            // 系统异常,回滚事务
            log.error("系统异常", e);
            throw new RuntimeException("操作失败");
        }
    }
    
    private void validateUserInfo(UserInfo userInfo) throws BusinessException {
        if (userInfo.getUserName() == null || userInfo.getUserName().isEmpty()) {
            throw new BusinessException("用户名不能为空");
        }
        
        if (userInfo.getEmail() == null || !isValidEmail(userInfo.getEmail())) {
            throw new BusinessException("邮箱格式不正确");
        }
    }
}

数据库连接池优化

HikariCP配置优化

spring:
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      # 连接池名称
      pool-name: MyHikariCP
      # 最小空闲连接数
      minimum-idle: 5
      # 最大连接数
      maximum-pool-size: 20
      # 连接超时时间(毫秒)
      connection-timeout: 30000
      # 空闲连接超时时间(毫秒)
      idle-timeout: 600000
      # 连接最大存活时间(毫秒)
      max-lifetime: 1800000
      # 自动提交
      auto-commit: true
      # 连接测试查询
      connection-test-query: SELECT 1
      # 验证连接有效性的时间间隔
      validation-timeout: 5000

连接池监控配置

@Configuration
public class DataSourceConfig {
    
    @Bean
    @Primary
    public HikariDataSource dataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/test_db");
        config.setUsername("root");
        config.setPassword("password");
        config.setMaximumPoolSize(20);
        config.setMinimumIdle(5);
        config.setConnectionTimeout(30000);
        config.setIdleTimeout(600000);
        config.setMaxLifetime(1800000);
        
        // 添加监控配置
        config.setPoolName("MyHikariCP");
        config.addDataSourceProperty("cachePrepStmts", "true");
        config.addDataSourceProperty("prepStmtCacheSize", "250");
        config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
        config.addDataSourceProperty("useServerPrepStmts", "true");
        
        return new HikariDataSource(config);
    }
}

缓存策略与性能优化

Redis缓存集成

@Service
public class UserInfoCacheService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    @Autowired
    private UserInfoMapper userInfoMapper;
    
    /**
     * 带缓存的用户查询
     */
    public UserInfo getUserByIdWithCache(Long userId) {
        String cacheKey = "user_info:" + userId;
        
        // 先从缓存获取
        UserInfo user = (UserInfo) redisTemplate.opsForValue().get(cacheKey);
        if (user != null) {
            log.debug("从缓存获取用户信息: {}", userId);
            return user;
        }
        
        // 缓存未命中,查询数据库
        log.debug("从数据库获取用户信息: {}", userId);
        user = userInfoMapper.selectById(userId);
        
        if (user != null) {
            // 设置缓存(5分钟过期)
            redisTemplate.opsForValue().set(cacheKey, user, 5, TimeUnit.MINUTES);
        }
        
        return user;
    }
    
    /**
     * 缓存更新策略
     */
    public void updateUserCache(UserInfo userInfo) {
        String cacheKey = "user_info:" + userInfo.getId();
        redisTemplate.opsForValue().set(cacheKey, userInfo, 5, TimeUnit.MINUTES);
    }
    
    /**
     * 缓存删除策略
     */
    public void deleteUserCache(Long userId) {
        String cacheKey = "user_info:" + userId;
        redisTemplate.delete(cacheKey);
    }
}

查询缓存优化

@Service
public class CachedQueryService {
    
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    /**
     * 分页查询缓存
     */
    public IPage<UserInfo> getCachedUserPage(int current, int size, Integer status) {
        String cacheKey = "user_page:" + current + ":" + size + ":" + status;
        
        // 尝试从缓存获取
        String cachedResult = (String) redisTemplate.opsForValue().get(cacheKey);
        if (cachedResult != null) {
            return JSON.parseObject(cachedResult, new TypeReference<IPage<UserInfo>>() {});
        }
        
        // 缓存未命中,执行查询
        Page<UserInfo> page = new Page<>(current, size);
        IPage<UserInfo> result = userInfoMapper.selectUserPage(page, status);
        
        // 缓存结果
        redisTemplate.opsForValue().set(cacheKey, JSON.toJSONString(result), 10, TimeUnit.MINUTES);
        
        return result;
    }
}

监控与日志管理

SQL执行监控

@Component
public class SqlMonitor {
    
    private static final Logger logger = LoggerFactory.getLogger(SqlMonitor.class);
    
    /**
     * SQL执行时间监控
     */
    public void monitorSqlExecution(String sql, long executionTime) {
        if (executionTime > 1000) { // 超过1秒的SQL记录警告日志
            logger.warn("SQL执行时间过长: {}ms", executionTime);
            logger.warn("SQL内容: {}", sql);
        } else if (executionTime > 500) {
            logger.info("SQL执行时间较长: {}ms",
相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000