如何在Java应用程序中从SQlite的机会不同的两个表中获得随机空闲?

时间:2019-01-06 11:23:45

标签: java sqlite javafx scenebuilder

我正在使用Scene Builder用JavaFX编写应用程序。我的数据库是SQlite。要浏览和编辑SQLite,我使用数据库浏览器

我在一个数据库文件中有一个表“ Cards”和表“ sentences”

Table Cards

Table senteces

我有一个按钮“ Random”和两个textArias。当我点击按钮时,该方法被调用。该方法从表“ Cards”中随机抽取对象,并将列中的文本设置为我的应用程序中的textArias。

我想在单击按钮时有一个机会:70%的机会从表“ Cards”中选择随机空闲,30%的机会从表“ Sentences”中选择随机空闲。

示例:如果我单击按钮10次。我的TextArias将显示“卡片”表中的文字-7次

表“句子”中各列的文本-3次

如何从两个表中选择机会百分比为70/30的随机空闲?

我存储查询的类(此查询选择随机idrow并防止出现空行):

package src.card;

public class PersistentQueries {


  private String sqlRandom = "SELECT * FROM Cards where rowid = (ABS(RANDOM()) % (SELECT (SELECT MAX(rowid) from Cards)+1)) or rowid = (SELECT MAX(rowid) FROM Cards) ORDER BY rowid LIMIT 1";


  public String getSqlRandom() {
   return sqlRandom;
  }

  public void setSqlRandom(String sqlRandom) {
   this.sqlRandom = sqlRandom;
  }
}

Class QuestionController:

@FXML  private TextArea ta_questText, ta_answerText;
@FXML  private Button btnRand;

Cards cards = new Cards();
PersistentQueries pq = new PersistentQueries();

ResultSet rs = null;
PreparedStatement pst = null;

@FXML void randomCard(ActionEvent event) {

try {
  Connection conn = DbConnection.getConnection();
  pst = conn.prepareStatement(pq.getSqlRandom());

  rs = pst.executeQuery();
  while (rs.next()) {

    ta_questText.setText(rs.getString("question"));
    ta_answerText.setText(rs.getString("answer"));
  }

  pst.close();
  rs.close();
  conn.close();
    } catch (SQLException e) {
  e.printStackTrace();
   }
  }

编辑:

根据@MikeT的答案,我进行了一个特殊的查询,并将其与所有查询一起放在一个类中:

public class PersistentQueries {

private String sqlRandomCat1 = "SELECT CASE WHEN ((abs(random()) % 10) + 1) > 7 THEN (SELECT 'category1' || rowid FROM category1 ORDER BY random() LIMIT 1) ELSE (SELECT 'sentences' || rowid FROM sentences ORDER BY random() LIMIT 1) END ";

public String getSqlRandomCat1() {
return sqlRandomCat1;
}

 public void setSqlRandomCat1(String sqlRandomCat1) {
this.sqlRandomCat1 = sqlRandomCat1;
 }

}

在我的QuestionController类中,我通过查询创建了该类的对象:

PersistentQueries pq = new PersistentQueries();

然后创建了一种方法,该方法将从表的列中获取文本并将其设置为文本区域:

@FXML void randomCard(ActionEvent event) {

try {
  Connection conn = DbConnection.getConnection();
  pst = conn.prepareStatement(pq.getSqlRandomCat1());

  rs = pst.executeQuery();
  while (rs.next()) {

    ta_questText.setText(rs.getString("question"));
    ta_answerText.setText(rs.getString("answer"));
  }

  conn.close();

   } catch (SQLException e) {
     e.printStackTrace();
    }
  }

我还重复了“句子”表中的“问题”和“答案”列,因为它没有这些列。因此,这些列只是“句子”列中的重复文本

sentences table

但是启动应用程序后,出现以下错误:

java.sql.SQLException: no such column: 'question'
at org.sqlite.jdbc3.JDBC3ResultSet.findColumn(JDBC3ResultSet.java:48)
at org.sqlite.jdbc3.JDBC3ResultSet.getString(JDBC3ResultSet.java:443)
at src.card.QuestController.randomCard(QuestController.java:454)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at 
  ...

有什么想法吗?

编辑2:

如果我使用与以前使用的查询相同的查询从一个表中生成随机idrow并进行如下所示的方法怎么办:

  • 产生一些随机机会

  • 如果机会小于70,则调用一个查询,该查询将从表“ Cards”中获取随机id行,并将列中的文本应用于我的textArea

  • 如果机会是> 70和<100,则调用一个查询,该查询将从表“句子”中随机抽取并应用列中的文本到我的textArea

但是我不知道该怎么做。

你能帮我吗?

2 个答案:

答案 0 :(得分:0)

您可以根据以下条件使用查询:-

SELECT
    CASE
        WHEN ((abs(random()) % 10) + 1) > 7 THEN 
            // 70% chance
            (SELECT rowid FROM cards ORDER BY random() LIMIT 1)  
        ELSE 
            // 30% chance
            (SELECT rowid FROM sentences ORDER BY random() LIMIT 1) 
    END
;

但是,您随后将不知道该rowid来自哪个表,因此也许可以通过使用'c'||rowid's'||rowid来区分这些表。

答案 1 :(得分:0)

找到解决方案!

我在方法中创建了这样的生成随机数:

int n = (int) (Math.random() * 100);

我已经制定了条件:

if(n < 70) {
//70 % chance to set Text from Category 1
}

else if (n < 80) {
//30% chance to set Text from table "sentences"
}

我的完整代码如下:

在我保存所有SQLite查询的课堂上:

public class PersistentQueries {

private String sqlRandomCat1 = "SELECT * FROM Category1 where rowid = (ABS(RANDOM()) % (SELECT (SELECT MAX(rowid) from Category1)+1)) or rowid = (SELECT MAX(rowid) FROM Category1) ORDER BY rowid LIMIT 1";
private String sqlRandomSent = "SELECT * FROM sentences where rowid = (ABS(RANDOM()) % (SELECT (SELECT MAX(rowid) from sentences)+1)) or rowid = (SELECT MAX(rowid) FROM sentences) ORDER BY rowid LIMIT 1";

  public String getSqlRandomCat1() {return sqlRandomCat1;}

  public void setSqlRandomCat1(String sqlRandomCat1) {this.sqlRandomCat1 = sqlRandomCat1;}

  public String getSqlRandomSent() {return sqlRandomSent;}

  public void setSqlRandomSent(String sqlRandomSent) {this.sqlRandomSent = sqlRandomSent;}


}

控制器:

@FXML
  void randomCard(ActionEvent event) throws SQLException {

    int n = (int) (Math.random() * 100);
    if (n < 70) {
      Connection conn = DbConnection.getConnection();
      pst = conn.prepareStatement(pq.getSqlRandomCat1());

      rs = pst.executeQuery();
      while (rs.next()) {

        ta_questText.setText(rs.getString("question"));
        ta_answerText.setText(rs.getString("answer"));

      }
    } else if (n < 80) {
      ta_questText.setText("");
      Connection conn = DbConnection.getConnection();
      pst = conn.prepareStatement(pq.getSqlRandomSent());

      rs = pst.executeQuery();
      while (rs.next()) {

        ta_questText.setText("");
        ta_answerText.setText(rs.getString("sentence"));
      }

    }
  }