You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在类中存储60个射箭得分整数以实现SQLite数据库读写?

射箭比赛得分应用的类设计与SQLite存储优化方案

我正在搭建一款记录射箭比赛得分的应用。每场比赛包含60支箭,得分范围为0-10。请问如何最优设计类来存储每支箭的得分,以便写入SQLite数据库?我可为每支箭单独设置变量,但这种方式效率低下,是否有更优方案?示例代码:

public class Portsmouth { 
    private int id; 
    Date date; 
    private int arrow1; 
    private int arrow2; 
    private int arrow3; 
    ... 
    private int arrow60; 
}

完全理解你的困扰——用60个单独的arrowX变量确实太冗余了,不仅写起来费劲,后续维护(比如统计总分、修改某支箭得分)也会格外麻烦。下面给你几个更优的设计思路,完美适配SQLite的存储需求:

方案一:用集合存储单场得分(轻量易用)

如果你的核心需求只是单场比赛对应一组得分,且不需要做太细粒度的历史统计(比如单独查所有比赛第10支箭的平均得分),用集合替代60个变量是最省心的选择。比如用List<Integer>或者数组,然后把这组得分序列化后存入数据库(转成JSON字符串就很方便)。

示例Java代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

public class Portsmouth {
    private int id;
    private Date date;
    // 专门存储60支箭的得分,默认初始化为0分
    private List<Integer> arrowScores;

    // 构造方法:初始化时确保是60个元素的列表
    public Portsmouth() {
        this.arrowScores = new ArrayList<>(Collections.nCopies(60, 0));
    }

    // 设置某支箭的得分(索引建议从0或1开始,自己调整)
    public void setArrowScore(int index, int score) {
        // 校验索引和得分合法性
        if (index >= 0 && index < 60 && score >= 0 && score <= 10) {
            arrowScores.set(index, score);
        } else {
            throw new IllegalArgumentException("无效的箭支索引或得分范围");
        }
    }

    // 获取某支箭的得分
    public int getArrowScore(int index) {
        if (index >= 0 && index < 60) {
            return arrowScores.get(index);
        }
        throw new IllegalArgumentException("无效的箭支索引");
    }

    // 快捷计算总分
    public int getTotalScore() {
        return arrowScores.stream().mapToInt(Integer::intValue).sum();
    }

    // 省略id、date、arrowScores的getter/setter
}

SQLite存储适配:

给Portsmouth表加一个arrow_scores字段,类型设为TEXT。存储时用Gson或Jackson把List<Integer>转成JSON数组字符串(比如[9,10,8,...]);读取时再反序列化为列表即可。


方案二:拆分两张表(规范化设计,适合复杂统计)

如果后续需要做精细化统计(比如统计某运动员所有比赛前10箭的得分趋势、所有比赛第5支箭的平均得分),数据库规范化设计才是长久之计。我们可以把比赛信息和箭支得分拆成两张表:

  1. 主表:matches(比赛表)

    • 字段:id(主键,自增)、date(比赛日期)、athlete_id(关联运动员ID,可选)、match_type(比赛类型,比如Portsmouth)
  2. 子表:arrow_scores(箭支得分表)

    • 字段:id(主键,自增)、match_id(外键,关联matches表的id)、arrow_number(箭支序号,1-60)、score(得分0-10)

对应的Java实体类设计:

import java.util.Date;

// 比赛主表实体
public class Match {
    private int id;
    private Date date;
    private int athleteId; // 可选,关联运动员信息
    private String matchType; // 比如"Portsmouth"

    // 构造方法、getter/setter省略
}

// 箭支得分实体
public class ArrowScore {
    private int id;
    private int matchId; // 关联的比赛ID
    private int arrowNumber; // 1-60
    private int score; // 0-10

    // 构造方法、getter/setter省略
}

核心优势:

  • 完全符合数据库范式,没有冗余数据
  • 支持各种复杂查询:比如SELECT AVG(score) FROM arrow_scores WHERE arrow_number = 5就能轻松得到所有比赛第5支箭的平均得分
  • 扩展性极强:以后如果比赛箭数变了(比如改成36支),根本不用修改表结构,只要调整业务逻辑就行

方案三:混合模式(兼顾易用性和扩展性)

要是你既想在业务代码里方便地操作单场比赛的所有得分,又想保留数据库的可查询性,可以试试混合模式:

  • 业务层用List<Integer>来管理单场得分,方便操作
  • DAO层做转换:保存比赛时,把List<Integer>拆成60条ArrowScore记录插入子表;查询时,根据match_id把所有箭支得分查出来,再组装成List<Integer>返回给业务层

这样业务层用起来省心,数据库层面也能支持所有统计需求,算是个折衷的最优解。

最后提个小建议:不管选哪种方案,一定要给得分加合法性校验(确保是0-10的整数),别让无效数据混进数据库里。

内容的提问来源于stack exchange,提问作者Mooney_S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 08:23:07