SQL缓存导出配置使用指南.md 7.6 KB

SQL缓存导出配置使用指南

🎯 功能概述

SQL缓存导出配置功能允许您在导出Excel时,通过配置SQL语句来加载数据到缓存进行匹配,实现高性能的数据转换。

🚀 核心特性

1. 高性能缓存机制

  • 静态缓存:使用ConcurrentHashMap存储SQL查询结果
  • 预加载机制:导出前批量预加载所有SQL数据
  • 缓存命中优化:从内存缓存获取数据,避免重复数据库查询
  • 线程安全:支持多用户并发导出

2. 灵活的SQL配置

  • 自定义SQL:支持任意SQL查询语句
  • 字段映射:可配置值字段和标签字段
  • 动态参数:支持SQL参数占位符
  • 配置管理:统一的配置注册和管理

3. 简单易用的注解

  • @ExcelSqlCacheFormat:配置SQL缓存转换
  • 自动转换:值到标签的自动转换
  • 反向查找:支持标签到值的反向转换

📋 使用步骤

1. 注册SQL配置

方式一:通过配置初始化器(推荐)

@Component
public class SqlCacheConfigInitializer implements CommandLineRunner {
    
    @Autowired
    private SqlCacheConfigService sqlCacheConfigService;
    
    @Override
    public void run(String... args) throws Exception {
        // 注册SQL配置
        sqlCacheConfigService.registerSqlConfig(
            "student_class_info",  // SQL键
            "SELECT class_id as id, class_name as name FROM xg_class WHERE deleted = 0",  // SQL语句
            "id",  // 值字段
            "name"  // 标签字段
        );
    }
}

方式二:通过服务直接注册

@Autowired
private SqlCacheConfigService sqlCacheConfigService;

public void registerConfig() {
    sqlCacheConfigService.registerSqlConfig(
        "college_info",
        "SELECT college_id as id, college_name as name FROM xg_college WHERE deleted = 0",
        "id",
        "name"
    );
}

2. 在VO类中使用注解

@Data
@ExcelIgnoreUnannotated
public class XgStudentMsgExportVo implements Serializable {
    
    /**
     * 班级名称 - 使用SQL缓存转换
     */
    @ExcelProperty(value = "班级名称", converter = ExcelSqlCacheConvert.class)
    @ExcelSqlCacheFormat(
        sqlKey = "student_class_info",  // 对应注册的SQL键
        valueColumn = "id",             // 值字段名
        labelColumn = "name"            // 标签字段名
    )
    private String className;
    
    /**
     * 学院名称 - 使用SQL缓存转换
     */
    @ExcelProperty(value = "学院名称", converter = ExcelSqlCacheConvert.class)
    @ExcelSqlCacheFormat(
        sqlKey = "college_info",
        valueColumn = "id",
        labelColumn = "name"
    )
    private String collegeName;
}

3. 在Controller中预加载缓存

@RestController
public class XgStudentMsgController extends BaseController {
    
    /**
     * 预加载导出所需的SQL缓存数据
     */
    private void preloadExportSqlData() {
        try {
            SqlCacheConfigService sqlCacheConfigService = SpringUtils.getBean(SqlCacheConfigService.class);
            
            // 预加载SQL配置
            sqlCacheConfigService.preloadSqlData("student_class_info");
            sqlCacheConfigService.preloadSqlData("college_info");
            sqlCacheConfigService.preloadSqlData("major_info");
            
            log.info("SQL缓存预加载完成");
        } catch (Exception e) {
            log.warn("SQL缓存预加载失败,将使用默认处理方式", e);
        }
    }
    
    /**
     * 导出方法
     */
    @PostMapping("/export")
    public void export(HttpServletResponse response) {
        // 预加载缓存
        preloadExportSqlData();
        
        // 执行导出
        List<XgStudentMsgExportVo> list = service.queryExportList();
        ExcelUtil.exportExcel(list, "学生信息", XgStudentMsgExportVo.class, response);
    }
}

🔧 配置示例

1. 基础查询配置

// 班级信息查询
"student_class_info" -> "SELECT class_id as id, class_name as name FROM xg_class WHERE deleted = 0"

// 学院信息查询
"college_info" -> "SELECT college_id as id, college_name as name FROM xg_college WHERE deleted = 0"

// 专业信息查询
"major_info" -> "SELECT major_id as id, major_name as name FROM xg_major WHERE deleted = 0"

2. 复杂查询配置

// 带条件的查询
"active_teachers" -> "SELECT user_id as id, nick_name as name FROM sys_user WHERE deleted = 0 AND user_type = '00' AND status = '0'"

// 关联查询
"class_with_teacher" -> """
    SELECT c.class_id as id, 
           CONCAT(c.class_name, ' (', u.nick_name, ')') as name 
    FROM xg_class c 
    LEFT JOIN sys_user u ON c.class_teacher_id = u.user_id 
    WHERE c.deleted = 0
"""

// 聚合查询
"dept_student_count" -> """
    SELECT dept_id as id, 
           CONCAT(dept_name, ' (', COUNT(*), '人)') as name 
    FROM xg_student_msg 
    WHERE deleted = 0 
    GROUP BY dept_id, dept_name
"""

3. 动态参数查询

// 支持参数的查询(需要特殊处理)
"tenant_college_info" -> "SELECT college_id as id, college_name as name FROM xg_college WHERE deleted = 0 AND tenant_id = ?"

📊 性能优化

1. 缓存策略

  • 预加载:导出前批量加载所有SQL数据
  • 静态缓存:使用ConcurrentHashMap避免重复查询
  • 内存优化:合理控制缓存数据量

2. SQL优化

  • 索引优化:确保查询字段有合适的索引
  • 查询优化:避免复杂的关联查询
  • 数据量控制:限制单次查询的数据量

3. 监控和统计

// 获取缓存统计信息
Map<String, Integer> stats = sqlCacheConfigService.getCacheStats();
log.info("SQL缓存统计: {}", stats);

// 清理缓存
sqlCacheConfigService.clearAllCache();

⚠️ 注意事项

1. SQL安全

  • 参数化查询:避免SQL注入风险
  • 权限控制:确保SQL查询权限合理
  • 数据验证:验证SQL查询结果的正确性

2. 缓存管理

  • 内存使用:监控缓存占用的内存
  • 缓存更新:数据变更时及时清理缓存
  • 缓存失效:设置合理的缓存过期策略

3. 错误处理

  • 异常捕获:妥善处理SQL执行异常
  • 降级策略:SQL失败时的降级处理
  • 日志记录:详细记录错误信息

🔄 与现有功能的对比

1. 与字典转换的对比

特性 字典转换 SQL缓存转换
数据源 字典表 任意表
配置方式 字典类型 SQL语句
灵活性 固定格式 高度灵活
性能 预加载缓存 预加载缓存
适用场景 标准字典 复杂业务数据

2. 使用场景

  • 字典转换:适用于标准的字典数据(性别、状态等)
  • SQL缓存转换:适用于复杂的业务数据(班级、学院、专业等)

📝 最佳实践

1. 配置管理

  • 将SQL配置集中管理
  • 使用有意义的SQL键名
  • 定期检查和优化SQL语句

2. 性能优化

  • 合理使用索引
  • 控制查询数据量
  • 监控缓存使用情况

3. 错误处理

  • 实现降级策略
  • 记录详细日志
  • 定期检查缓存状态

🎉 总结

SQL缓存导出配置功能为Excel导出提供了强大的数据转换能力:

  1. 高性能:通过预加载缓存显著提升导出性能
  2. 灵活性:支持任意SQL查询和字段映射
  3. 易用性:简单的注解配置即可使用
  4. 可扩展性:支持复杂的业务场景

该功能特别适用于需要从多个业务表获取数据进行导出的场景,能够有效解决传统导出方式中的性能瓶颈问题。