首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在SQLite中存储试题

在SQLite中存储试题
EN

Code Review用户
提问于 2016-11-05 17:24:51
回答 3查看 830关注 0票数 2

我正在创建我的第一个android应用程序。这将是一个小测验。

有40个不同的问题类别,每个类别都有自己的数据库表。

我把所有的问题都写进了这样的sqlite数据库:

代码语言:javascript
复制
private void addQuestions() {
    // Category 1 (ACE) Questions
    // First Question
    String aceQuestion1 = MainActivity.getContext().getResources().getString(R.string.ace_Question1);
    String aceQuestion1a = MainActivity.getContext().getResources().getString(R.string.ace_Question1a);
    String aceQuestion1b = MainActivity.getContext().getResources().getString(R.string.ace_Question1b);
    String aceQuestion1c = MainActivity.getContext().getResources().getString(R.string.ace_Question1c);
    String aceQuestion1d = MainActivity.getContext().getResources().getString(R.string.ace_Question1d);
    Question ace1 = new Question(aceQuestion1, aceQuestion1a, aceQuestion1b, aceQuestion1c, aceQuestion1d, aceQuestion1b);
    this.addACEQuestion(ace1);

    // Second Question
    String aceQuestion2 = MainActivity.getContext().getResources().getString(R.string.ace_Question2);
    String aceQuestion2a = MainActivity.getContext().getResources().getString(R.string.ace_Question2a);
    String aceQuestion2b = MainActivity.getContext().getResources().getString(R.string.ace_Question2b);
    String aceQuestion2c = MainActivity.getContext().getResources().getString(R.string.ace_Question2c);
    String aceQuestion2d = MainActivity.getContext().getResources().getString(R.string.ace_Question2d);
    Question ace2 = new Question(aceQuestion2, aceQuestion2a, aceQuestion2b, aceQuestion2c, aceQuestion2d, aceQuestion2d);
    this.addACEQuestion(ace2);

    // Category 2 (Androgen) Questions
    // First Question
    String androgensQuestion1 = MainActivity.getContext().getResources().getString(R.string.androgens_Question1);
    String androgensQuestion1a = MainActivity.getContext().getResources().getString(R.string.androgens_Question1a);
    String androgensQuestion1b = MainActivity.getContext().getResources().getString(R.string.androgens_Question1b);
    String androgensQuestion1c = MainActivity.getContext().getResources().getString(R.string.androgens_Question1c);
    String androgensQuestion1d = MainActivity.getContext().getResources().getString(R.string.androgens_Question1d);
    Question androgens1 = new Question(androgensQuestion1, androgensQuestion1a, androgensQuestion1b, androgensQuestion1c, androgensQuestion1d, androgensQuestion1c);
    this.addAndrogensQuestion(androgens1);

    // Second Question
    String androgensQuestion2 = MainActivity.getContext().getResources().getString(R.string.androgens_Question2);
    String androgensQuestion2a = MainActivity.getContext().getResources().getString(R.string.androgens_Question2a);
    String androgensQuestion2b = MainActivity.getContext().getResources().getString(R.string.androgens_Question2b);
    String androgensQuestion2c = MainActivity.getContext().getResources().getString(R.string.androgens_Question2c);
    String androgensQuestion2d = MainActivity.getContext().getResources().getString(R.string.androgens_Question2d);
    Question androgens2 = new Question(androgensQuestion2, androgensQuestion2a, androgensQuestion2b, androgensQuestion2c, androgensQuestion2d, androgensQuestion2b);
    this.addAndrogensQuestion(androgens2);
}

// Add Category 1 (ACE) Questions
public void addACEQuestion(Question quest) {
    addQuestion(quest, TABLE_ACE);
}

// Add Category 2 (Androgens) Questions
public void addAndrogensQuestion(Question quest) {
    addQuestion(quest, TABLE_ANDROGENS);
}

public void addQuestion(Question quest, String table) {
    //SQLiteDatabase db = this.getWritableDatabase();
    ContentValues values = new ContentValues();
    values.put(QUES, quest.getQUESTION());
    values.put(OPTA, quest.getOPTA());
    values.put(OPTB, quest.getOPTB());
    values.put(OPTC, quest.getOPTC());
    values.put(OPTD, quest.getOPTD());
    values.put(ANSWER, quest.getANSWER());
    // Inserting Rows
    database.insert(table, null, values);
}

这很好,但是我会为每个类别添加大约30个问题,所以如果我这样实现它,将会有超过1000个问题,并且代码将变得无法管理。

我试图为每个类别实现一个for循环,但不幸的是,没有进行管理。

我如何简化这段代码,使其更少重复?

问题对象

代码语言:javascript
复制
public class Question {
private int ID;
private String QUESTION;
private String OPTA;
private String OPTB;
private String OPTC;
private String OPTD;
private String ANSWER;

public Question() {
    ID=0;
    QUESTION="";
    OPTA="";
    OPTB="";
    OPTC="";
    OPTD="";
    ANSWER="";
}

public Question(String question, String opta, String optb, String optc, String optd, String answer) {
    QUESTION = question;
    OPTA = opta;
    OPTB = optb;
    OPTC = optc;
    OPTD = optd;
    ANSWER = answer;
}

public int getID() { return ID; }
public String getQUESTION() { return QUESTION; }
public String getOPTA() { return OPTA; }
public String getOPTB() { return OPTB; }
public String getOPTC() {
    return OPTC;
}
public String getOPTD() {
    return OPTD;
}
public String getANSWER() { return ANSWER; }

public void setID(int id)
{
    ID=id;
}
public void setQUESTION(String question) {
    QUESTION = question;
}
public void setOPTA(String opta) {
    OPTA = opta;
}
public void setOPTB(String optb) {
    OPTB = optb;
}
public void setOPTC(String optc) { OPTC = optc; }
public void setOPTD(String optd) { OPTD = optd; }
public void setANSWER(String answer) { ANSWER = answer; }
}

我的方法不成功

代码语言:javascript
复制
private void addQuestions() {
    for (int i = 0; i <= 30; i++) {
        // ACE Questions
        String aceQuestioni = MainActivity.getContext().getResources().getString(R.string."ace_Question" + i);
        String aceQuestionia = MainActivity.getContext().getResources().getString(R.string."ace_Question" + i + "a");
        String aceQuestionib = MainActivity.getContext().getResources().getString(R.string."ace_Question" + i + "b");
        String aceQuestionic = MainActivity.getContext().getResources().getString(R.string."ace_Question" + i + "c");
        String aceQuestionid = MainActivity.getContext().getResources().getString(R.string."ace_Question" + i + "d");
        Question ace1 = new Question(aceQuestion1, aceQuestion1a, aceQuestion1b, aceQuestion1c, aceQuestion1d, aceQuestion1b);
        this.addACEQuestion(ace1);
        Question ace2 = new Question(aceQuestion2, aceQuestion2a, aceQuestion2b, aceQuestion2c, aceQuestion2d, aceQuestion2d);
        this.addACEQuestion(ace2);
    }
}
EN

回答 3

Code Review用户

回答已采纳

发布于 2016-11-05 19:07:37

问题在于,R.string.ace_Question2是Java标识符(最可能用于字符串),问题和答案有独立的标识符(我猜)。

R.string中的常数分解为两个enums

代码语言:javascript
复制
class R {
  enum QandAkey {
   KEY_QUESTION, KEY_ANSWER_A, KEY_ANSWER_B /*, ...*/;
  }
  enum QuestionKey { // string is not a good name!!
    ace_Question1,ace_Question1,androgens_Question1,androgens_Question2 /*,...*/;
  }
}

然后,您可以将代码简化为循环:

代码语言:javascript
复制
for(QuestionKey qk : R.QuestionKey.values()) {
  String[] questionAndAnswers = new String[R.QandA.values().length];
  for(QandAkey qak : R.QandAkey.values()){
     questionAndAnswers[qak.ordinal()]
       = MainActivity.getContext().getResources()
               .getString(qk.name()+"."+qak.name());
  }
  // let the Question-constructor deal with the strings array itself 
  addAndrogensQuestion( new Question(questionAndAnswers)); 
}

取消,因为您必须更改Resource属性中条目的键以匹配新模式:

代码语言:javascript
复制
ace_Question1.KEY_QUESTION = dflafDSTDJWEfd
ace_Question1.KEY_ANSWER_A = dflafDSTDJWEfd
ace_Question1.KEY_ANSWER_B = dflafDSTDJWEfd

如果您想要添加更多的问题,您只需要在QuestionKey中为每个问题添加一个新的常量,并在资源文件中添加与QandAkey实体相同的条目。

票数 1
EN

Code Review用户

发布于 2016-11-06 09:30:44

方法中的另一个问题是在运行时选择正确的答案。

应该将答案保存为参考资源中的正确答案,而不是在运行时确定:

代码语言:javascript
复制
ace_Question1.KEY_QUESTION = dflafDSTDJWEfd
ace_Question1.KEY_CORRECT = KEY_ANSWER_A 
ace_Question1.KEY_ANSWER_A = dflafDSTDJWEfd
ace_Question1.KEY_ANSWER_B = dflafDSTDJWEfd

ace_Question2.KEY_QUESTION = dflafDSTDJWEfd
ace_Question2.KEY_CORRECT = KEY_ANSWER_B 
ace_Question2.KEY_ANSWER_A = dflafDSTDJWEfd
ace_Question2.KEY_ANSWER_B = dflafDSTDJWEfd

这需要第一个枚举中的第二个默认条目:

代码语言:javascript
复制
  enum QandAkey {
   KEY_QUESTION, KEY_CORRECT, KEY_ANSWER_A, KEY_ANSWER_B /*, ...*/;
   // the order of entries here does not need to reflect
   // the order of entries in the resource file
   // as long as we can rely on String type keys...
  }

然后,我们必须更改问题构造函数,以处理我的第一个答案(解析Error:(422, 28) error: no suitable constructor found for Question(String[]))中的新方法,以及这个方法中的更改:

代码语言:javascript
复制
public Question(String... questionAndAnswers) {
    QUESTION = questionAndAnswers[QandAkey.KEY_QUESTION.ordinal()];
    OPTA =questionAndAnswers[QandAkey.KEY_ANSWER_A.ordinal();
    OPTB = questionAndAnswers[QandAkey.KEY_ANSWER_B.ordinal();
    OPTC = questionAndAnswers[QandAkey.KEY_ANSWER_C.ordinal();
    OPTD = questionAndAnswers[QandAkey.KEY_ANSWER_A.ordinal();
    ANSWER = questionAndAnswers[QandAkey.valueOf(
                  questionAndAnswers[QandAkey.KEY_CORRECT.ordinal()]
                ).ordinal()
             ];
}

这是对Question类的租约破坏性更改。

当然,更好的解决方案是将ANSWER更改为int并存储索引,但这需要在类中进行更多的更改。

票数 1
EN

Code Review用户

发布于 2016-11-06 10:56:26

由于您的问题和答案存储在XML中,所以可以使用JaxB创建问题的集合。https://docs.oracle.com/javase/tutorial/jaxb/intro/examples.html

首先,您必须使用如下的Question注释增强您的JaxB类:

代码语言:javascript
复制
@XmlElement
public class Question {
    private int ID;
    @XmlElement(name="TheQuestion") // because we need a different Name in XML
    private String QUESTION;
    @XmlElement
    private String OPTA;
    @XmlElement
    private String OPTB;
    @XmlElement
    private String OPTC;
    @XmlElement
    private String OPTD;
    @XmlAttribute(name="answer") // because of case change
    private int ANSWER;

    // could be removed completely...
    public Question() {
    }

然后,您必须使用本教程中提到的jaxb编译器创建映射代码。

您的XML必须从现在的样子更改为(或类似的)

代码语言:javascript
复制
<Questions> <!-- the root element -->
  <Question answer="2">
    <TheQuestion>flaiufdgl</TheQuestion>
    <OPTA>flaiufdgl</OPTA>
    <OPTB>flaiufdgl</OPTB>
    <OPTC>flaiufdgl</OPTC>
    <OPTD>flaiufdgl</OPTD>
  </Question>
</Questions>
票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/146238

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档