簡體   English   中英

如何從SQlite在Java應用程序中從具有不同%機會的兩個表中獲得隨機空閑?

[英]How to get random idrow from two tables with different % chance from SQlite in Java application?

我正在使用Scene Builder在JavaFX中編寫應用程序。 我的數據庫是SQlite。 要瀏覽和編輯SQLite,我使用數據庫瀏覽器

我在一個數據庫文件中有一個表“ Cards”和一個表“ Sentences”

Table Cards

Table senteces

我有一個按鈕“ Random”和兩個textArias。 當我點擊按鈕時,該方法被調用。 該方法從表“ Cards”獲取隨機空閑空間,並將列中的文本設置為我的應用程序中的textArias。

我想在單擊按鈕時獲得一個機會:70%的機會從表“ Cards”中選擇隨機的IDROW,30%的機會從表“ Sentences”中選擇隨機的IDROW。

示例:如果我單擊按鈕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;
  }
}

類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-調用一個查詢,該查詢將從表“句子”中獲取隨機idrow,並將列中的文本應用於我的textArea

但是我不知道該怎么做。

你能幫助我嗎?

您可以根據以下條件使用查詢:

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來區分表。

找到解決方案!

我在方法中創建了這樣的生成的隨機數:

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"));
      }

    }
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM