Java 将数据从ArrayList插入MySql数据库<;T>;

Java 将数据从ArrayList插入MySql数据库<;T>;,java,mysql,arraylist,Java,Mysql,Arraylist,有人能帮我做得更好一点吗?每次在会话中通过调用方法saveQuestionToPlayersQuestion()回答问题时,我都会添加一个带有数据的ArrayList,在回答所有问题后,会调用savePlayersQuestionsToDB()meth。我在模式中有一个表用于该数据 我有它的工作和保存到数据库,但不认为这是正确的做法 我是否可以立即插入arraylist,这意味着不调用 ConnectionClass.createPlaySessionInDB(pQ.getPlayer_id()

有人能帮我做得更好一点吗?每次在会话中通过调用方法saveQuestionToPlayersQuestion()回答问题时,我都会添加一个带有数据的ArrayList,在回答所有问题后,会调用savePlayersQuestionsToDB()meth。我在模式中有一个表用于该数据

我有它的工作和保存到数据库,但不认为这是正确的做法

我是否可以立即插入arraylist,这意味着不调用

ConnectionClass.createPlaySessionInDB(pQ.getPlayer_id(),
                        pQ.getQuestion_tbl_id(), pQ.getAns(),
                        pQ.getPlayer_score(), pQ.getPlay_session_id());
对于列表中的每个对象,当只回答了3个问题时是可以的,但是如果他们必须回答20或30多个问题,会发生什么呢。有更好的办法吗

我的申报表

private ArrayList<Play_Questions> playQuestionList;


playQuestionList = new ArrayList<Play_Questions>();
下面是Connection类中的方法

    public static void createPlaySessionInDB(int player_id,
        int question_tbl_id, String ans, int player_score,
        int play_session_id) throws SQLException {
    String sql = "INSERT INTO player_questions (id, player_id, question_tbl_id, ans, player_score, play_session_id ) VALUES (null,?,?,?,?,?)";
    try {
        preparedStatement = preparedStatement(sql);
        preparedStatement.setInt(1, player_id);
        preparedStatement.setInt(2, question_tbl_id);
        preparedStatement.setString(3, ans);
        preparedStatement.setInt(4, player_score);
        preparedStatement.setInt(5, play_session_id);

        // execute the SQL statement
        preparedStatement.executeUpdate();

    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        System.out
                .println("Problem with ConnectionClass createPlaySessionInDB method: "
                        + e.getMessage());
    } finally {
        // close the connection
        getConnection().close();
    }
}
这是戏剧问题课

public class Play_Questions {
private int player_id; 
private int question_tbl_id; 
private String ans;
private int player_score; 
private int play_session_id;

/**
 * Default Constructor
 */
public Play_Questions(){
    this(0,0,null,0,0);
}

/**
 * @param player_id: 
 *      the players id
 * @param question_tbl_id: 
 *      the question id from question table
 * @param ans: 
 *      the answer selected by player
 * @param player_score: 
 *      the score they achieved for answering
 * @param play_session_id: 
 *      the play session id
 */
public Play_Questions(int player_id, int question_tbl_id, String ans,
        int player_score, int play_session_id) {
    this.player_id = player_id;
    this.question_tbl_id = question_tbl_id;
    this.ans = ans;
    this.player_score = player_score;
    this.play_session_id = play_session_id;
}

/**
 * @return the player_id
 */
public int getPlayer_id() {
    return player_id;
}

/**
 * @param player_id the player_id to set
 */
public void setPlayer_id(int player_id) {
    this.player_id = player_id;
}

/**
 * @return the question_tbl_id
 */
public int getQuestion_tbl_id() {
    return question_tbl_id;
}

/**
 * @param question_tbl_id the question_tbl_id to set
 */
public void setQuestion_tbl_id(int question_tbl_id) {
    this.question_tbl_id = question_tbl_id;
}

/**
 * @return the ans
 */
public String getAns() {
    return ans;
}

/**
 * @param ans the ans to set
 */
public void setAns(String ans) {
    this.ans = ans;
}

/**
 * @return the player_score
 */
public int getPlayer_score() {
    return player_score;
}

/**
 * @param player_score the player_score to set
 */
public void setPlayer_score(int player_score) {
    this.player_score = player_score;
}

/**
 * @return the play_session_id
 */
public int getPlay_session_id() {
    return play_session_id;
}

/**
 * @param play_session_id the play_session_id to set
 */
public void setPlay_session_id(int play_session_id) {
    this.play_session_id = play_session_id;
}
如果你能帮我把代码写得更好,我将不胜感激


Gman这是我的方法,最好使用一种非常透明的方法,将问题建模为接近真实生活场景的模型

 public class Question
{
     private int question_no ;
     // The right answer for this question may be a , b or c 
     private String question_answer ;
     private int question_point ;

    public Question()
    {

    }

    /**
     * @return the question_id
     */
    public int getQuestion_id() {
        return question_no;
    }

    /**
     * @param question_id the question_id to set
     */
    public void setQuestion_id(int question_id) {
        this.question_no = question_id;
    }

    /**
     * @return the question_answer
     */
    public String getQuestion_answer() {
        return question_answer;
    }

    /**
     * @param question_answer the question_answer to set
     */
    public void setQuestion_answer(String question_answer) {
        this.question_answer = question_answer;
    }

    /**
     * @return the question_point
     */
    public int getQuestion_point() {
        return question_point;
    }

    /**
     * @param question_point the question_point to set
     */
    public void setQuestion_point(int question_point) {
        this.question_point = question_point;
    }
}
现在是答案课

 /**
 * 
 *    Track an answer 
 */
public class Answer
{

    private String answer ;
    // correct or failed 
    private String status ;
    public Answer()
    {

    }

    /**
     * @return the answer
     */
    public String getAnswer() {
        return answer;
    }

    /**
     * @param answer the answer to set
     */
    public void setAnswer(String answer) {
        this.answer = answer;
    }

    /**
     * @return the status
     */
    public String getStatus() {
        return status;
    }

    /**
     * @param status the status to set
     */
    public void setStatus(String status) {
        this.status = status;
    }




}
现在,成功登录到一个player对象后,封装每个player的所有操作的player类被添加到会话中,它处理诸如标记、保存到db等操作

/**
 * 
 *  encapsulates a player 
 * Class should be placed in session for web applications 
 */
public class Player
{
    String username ;
    String password ;

    // holds all the questions arranged for this player without allowing duplicates in questions 
    Set questions = new HashSet<Question>();

    // map this players question and answer 
    Map question_answers = new HashMap<Question, Answer>();


    /**
     * 
     *   Allows you to dynamically set questions for players 
     * @param questions_ 
     */
    public Player(Set questions_ )
    {
        this.questions = questions_;
    }


    // if you want the same set of questions for all players 
    public Player()
    {

     }

    /**
     * Question answered for this particular user 
     * please note that the player object is in session if it is a web application 
     * @param q
     * @param a 
     */
    public void answerQuestion(Question q , Answer a)
    {
        question_answers.put(q, a);
    }

    /**
     * 
     *  The user might go back to a previous question to change an answer 
     * @param q
     * @param a 
     */
   public void updateAnswer(Question q, Answer a)
    {
       // remove the question and update it with 
        if(question_answers.containsKey(q))
        {
            question_answers.remove(q);
        }


        // add the new q & a 
        answerQuestion(q, a);
    }

   /**
     * 
     *   finally save the players data 
     *   here your db model counts it would have to cater for 
     *  each players question and answer , send the batch update using batch prepared statements 
     */
    public void savePlayerData()
    {
        // db code is commented because i didnt write db codes 
        // status int the column will stand for correct or fail 
       // String save_sql =insert into results(player_id , question_id , answer , status) values(?,?,?,?)
        // PreparedStatement pstat = dbConnection.prepareStatement(save_sql);
        //dbConnection.setAutoCommit(false);
        // if automark is enabled 
        autoMark();
        Iterator it = question_answers.values().iterator();
        while(it.hasNext())
        {
            // fetch each question 
            Question q = (Question)it.next();
            // Fetch each answer based on the question 
            Answer a = (Answer)question_answers.get(q);

            int question_id = q.getQuestion_id();
            String answer = a.getAnswer();
            String answer_status = a.getStatus();
            /**
             *    
             *    
             *   commented cause i would have to write db backing code , lol !
             *    
             *    pstat.setInt(1, getUsername());
             *   pstat.setInt(2, question_id);
             *   pstat.setString(3 , answer);
             *  pstat.setString(4 , answer_status)
             * pstat.addBatch();
             * pstat.executeBatch();
             * 
             */

        }
        //dbConnection.setAutoCommit(false);

    }


    /**
     * 
     *   This method can allow your program to auto mark if 
     *   the question and answer  if it is based on a , b , c 
     */
    public void autoMark()
    {
        Iterator it = question_answers.values().iterator();
        while(it.hasNext())
        {
            // fetch each question 
            Question q = (Question)it.next();
            // Fetch each answer based on the question 
            Answer a = (Answer)question_answers.get(q);

            if(q.getQuestion_answer().equalsIgnoreCase(a.getAnswer()))
            {
                a.setStatus("Correct");
            }
            else
            {
                a.setStatus("Failed");
            }
            updateAnswer(q, a);
        }
    }

}
问题对象是已回答的特定问题,而答案对象的创建是为了匹配问题。 您还可以通过在带有getter和setter(问题对象)的player类上添加一个名为current_question的值来跟踪用户当前的问题,以防用户返回到您可以调用的前一个问题

p.updateAnswer(Question q, Answer a)
同样的事情,你通过特定的问题和新的答案对象

p.savePlayerData()
将数据保存到数据库

p.autoMark()

此方法在保存记录之前在
p.savePlayerData()
方法中调用,因此db只保存最终评估和标记的记录,这对于智能报告(如谁的分数最高)非常有用。如果您有其他问题,请与我联系tyger2007@gmail.com.

好的,我确实设法实现了我想做的事情,下面是修改后的代码,以帮助其他有同样问题的人。这不是一个明确的方法,只是我现在知道的唯一方法,来实现我所需要的。如果有人有一个好的,更快的方法来做这件事,我很想知道。从这条线索中得到了一些灵感

下面是我调用的方法,用于将回答的每个问题保存到playQuestionList,下一个方法是SavePlayerQuestionStoDB(),我将Arraylist传递给Connection类,并在其中循环

/**
 * add the question to playQuestionList
 */
public void saveQuestionToPlayersQuestion() {
    Play_Questions temp = new Play_Questions(playerId, question_tbl_id,
            choosenAnswer, scorePerQuestion, nextPlaySessionId);
    playQuestionList.add(temp);
}

/**
 * save the playQuestion to DataBase
 */
public void savePlayersQuestionsToDB() {
    try {
        ConnectionClass.savePlaySessionInDB(playQuestionList);
        System.out.println("Worked check DB --->>");
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        System.out
                .println("Error with ElbtView savePlayersQuestionsToDB()");
    }
}
这是ConnectionClass中的方法

/**
 * Creates a batch using addBatch()and then executes it by calling
 * ececuteBatch()
 * 
 * @param playQuestions
 *            the ArrayList<T> to be added to batch and then saved to DB
 * @throws SQLException
 *             when executing the the batch
 */
public static void savePlaySessionInDB(
        ArrayList<Play_Questions> playQuestions) throws SQLException {
    try {
        String sql = "INSERT INTO player_questions (id, player_id, question_tbl_id, ans, player_score, play_session_id ) VALUES (null,?,?,?,?,?)";
        preparedStatement = preparedStatement(sql);
        for (int i = 0; i < playQuestions.size(); i++) {
            Play_Questions playQuestion = playQuestions.get(i);
            preparedStatement.setInt(1, playQuestion.getPlayer_id());
            preparedStatement.setInt(2, playQuestion.getQuestion_tbl_id());
            preparedStatement.setString(3, playQuestion.getAns());
            preparedStatement.setInt(4, playQuestion.getPlayer_score());
            preparedStatement.setInt(5, playQuestion.getPlay_session_id());
            preparedStatement.addBatch();

            if ((i + 1) % 100 == 0) {
                preparedStatement.executeBatch(); // excute every 100 items
            }
        }
        preparedStatement.executeBatch();
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        System.out
                .println("Problem with ConnectionClass savePlaySessionInDB(ArrayList<Play_Questions> playQuestions) method: "
                        + e.getMessage());
    } finally {
        // close the connection
        getConnection().close();
    }

}
/**
*使用addBatch()创建批处理,然后通过调用
*ececuteBatch()
* 
*@param游戏问题
*要添加到批处理然后保存到数据库的ArrayList
*@SQLException
*在执行批处理时
*/
公共静态无效savePlaySessionInDB(
ArrayList playQuestions)抛出SQLException{
试一试{
String sql=“插入玩家问题(id、玩家id、问题tbl id、ans、玩家分数、玩家会话id)值(空、、、、、、?)”;
preparedStatement=preparedStatement(sql);
对于(int i=0;i
公然接受一个更好的建议


Gman

我必须说,由于这个解决方案现在实际上运行得很好,从长远来看,它可能仍然会带来一些问题。这实际上取决于您的应用程序的性质,它是一个将被许多用户部署和使用的应用程序吗?或者它只是一个测试应用程序?无论如何,我建议您正确地建模对象,因为这是面向对象编程中最重要的事情, 我的建议是:

  • 隔离问题、玩家、答案对象,拥有像Play_Question这样的对象将使您的应用程序难以动态扩展
  • 对循环使用迭代器,它已经过优化,性能优于循环,尤其是在集合中
  • 对于我来说,如果它是桌面应用程序,我自然会使用单例连接类&JNDI如果它是web应用程序,那么连接类使用连接池,这样我的应用程序就不会为每个db请求打开新的连接,它使您的应用程序在db请求中运行得非常快[如果web使用JNDI,桌面应用程序的bonecp连接池]

    地图很容易使用,它是一个键/值对的例子,同样很好的工作和乐趣


  • 没关系,我花了相当多的时间开发应用程序,通常我都是按比例开发的,哈哈,我在方法savePlayerData()的Players类中使用了迭代器你可以在你的收集类中使用它。

    tks@I.Tyger为了提供你的选择,在这个后期阶段,我已经实现了不同的方法,没有时间更改应用程序或数据库来匹配,因为表r
    /**
     * add the question to playQuestionList
     */
    public void saveQuestionToPlayersQuestion() {
        Play_Questions temp = new Play_Questions(playerId, question_tbl_id,
                choosenAnswer, scorePerQuestion, nextPlaySessionId);
        playQuestionList.add(temp);
    }
    
    /**
     * save the playQuestion to DataBase
     */
    public void savePlayersQuestionsToDB() {
        try {
            ConnectionClass.savePlaySessionInDB(playQuestionList);
            System.out.println("Worked check DB --->>");
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out
                    .println("Error with ElbtView savePlayersQuestionsToDB()");
        }
    }
    
    /**
     * Creates a batch using addBatch()and then executes it by calling
     * ececuteBatch()
     * 
     * @param playQuestions
     *            the ArrayList<T> to be added to batch and then saved to DB
     * @throws SQLException
     *             when executing the the batch
     */
    public static void savePlaySessionInDB(
            ArrayList<Play_Questions> playQuestions) throws SQLException {
        try {
            String sql = "INSERT INTO player_questions (id, player_id, question_tbl_id, ans, player_score, play_session_id ) VALUES (null,?,?,?,?,?)";
            preparedStatement = preparedStatement(sql);
            for (int i = 0; i < playQuestions.size(); i++) {
                Play_Questions playQuestion = playQuestions.get(i);
                preparedStatement.setInt(1, playQuestion.getPlayer_id());
                preparedStatement.setInt(2, playQuestion.getQuestion_tbl_id());
                preparedStatement.setString(3, playQuestion.getAns());
                preparedStatement.setInt(4, playQuestion.getPlayer_score());
                preparedStatement.setInt(5, playQuestion.getPlay_session_id());
                preparedStatement.addBatch();
    
                if ((i + 1) % 100 == 0) {
                    preparedStatement.executeBatch(); // excute every 100 items
                }
            }
            preparedStatement.executeBatch();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            System.out
                    .println("Problem with ConnectionClass savePlaySessionInDB(ArrayList<Play_Questions> playQuestions) method: "
                            + e.getMessage());
        } finally {
            // close the connection
            getConnection().close();
        }
    
    }