Skip to main content

数据API服务

架构图

前端层

interface ChartProps {
dateRange: [string, string];
metrics: string[];
}

const MetricsChart: React.FC<ChartProps> = ({ dateRange, metrics }) => {
const [data, setData] = useState<any>(null);

useEffect(() => {
// 获取数据
const fetchData = async () => {
try {
const response = await axios.get('/api/metrics', {
params: { startDate: dateRange[0], endDate: dateRange[1] }
});
setData(response.data);
} catch (error) {
console.error('Error fetching data:', error);
}
};

fetchData();
}, [dateRange]);

return (
<div className="chart-container">
<EChartsReact
option={getChartOption(data, metrics)}
style={{ height: '400px' }}
/>
</div>
);
};

后端-Controller层

@RestController
@RequestMapping("/api/metrics")
public class MetricsController {

@Autowired
private MetricsService metricsService;

@GetMapping
// A指标统计接口
public ResponseEntity<List<MetricsDTO>> getMetrics(
@RequestParam String startDate,
@RequestParam String endDate) {
return ResponseEntity.ok(
metricsService.getMetricsData(startDate, endDate)
);
}
}

后端-Service层

@Service
@Slf4j
public class MetricsServiceImpl implements MetricsService {

@Autowired
private MetricsMapper metricsMapper;

@Autowired
private RedisTemplate<String, Object> redisTemplate;

@Cacheable(value = "metrics", key = "#startDate + '-' + #endDate")
public List<MetricsDTO> getMetricsData(String startDate, String endDate) {
String cacheKey = "metrics:" + startDate + "-" + endDate;

// 0.配置缓存配置
// @Configuration 配置 class RedisConfig , @Bean 实现 public RedisTemplate<String, Object> redisTemplate


// 1. 尝试从缓存获取
List<MetricsDTO> cachedData = (List<MetricsDTO>)
redisTemplate.opsForValue().get(cacheKey);

if (cachedData != null) {
return cachedData;
}

// 2. 缓存未命中,从数据库查询
List<MetricsDTO> data = metricsMapper.queryMetrics(startDate, endDate);

// 3. 设置缓存,1天过期
redisTemplate.opsForValue().set(
cacheKey,
data,
24,
TimeUnit.HOURS
);

return data;
}
}

MyBatis Mapper 层

@Mapper
public interface MetricsMapper {

// 从mysql统计指标
@Select("""
SELECT
date,
SUM(value) as total,
AVG(value) as average,
COUNT(*) as count
FROM metrics
WHERE date BETWEEN #{startDate} AND #{endDate}
GROUP BY date
ORDER BY date
""")
List<MetricsDTO> queryMetrics(
@Param("startDate") String startDate,
@Param("endDate") String endDate
);
}

定时任务层

@Component
@EnableScheduling
public class MetricsScheduler {

@Autowired
private MetricsService metricsService;

@Scheduled(cron = "0 0 1 * * *") // 每天凌晨1点执行,同步mysql的数据,日批
public void updateMetrics() {
String today = LocalDate.now().toString();
metricsService.refreshMetrics(today);
}
}