从ArrayList <t> </t>将数据插入MySql DB

时间:2014-03-21 20:35:38

标签: java mysql arraylist

任何人都可以帮助我做得更好一点,我有一个ArrayList,每次在会话中通过调用方法saveQuestionToPlayersQuestion()回答问题时添加数据,在回答所有问题后调用savePlayersQuestionsToDB()方法。我在该模式的架构中有一个表。

我有它工作并保存到数据库,但不认为它是正确的方法。

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

ConnectionClass.createPlaySessionInDB(pQ.getPlayer_id(),
                        pQ.getQuestion_tbl_id(), pQ.getAns(),
                        pQ.getPlayer_score(), pQ.getPlay_session_id());

对于列表中的每个对象,当只有3个问题被回答时就可以了,但如果他们必须回答20或30个问题,会发生什么。有没有更好的方法。

我声明的ArrayList

private ArrayList<Play_Questions> playQuestionList;


playQuestionList = new ArrayList<Play_Questions>();

这是我调用的方法,用于保存每个回答playQuestionList的问题,下一个方法savePlayersQuestionsToDB()是使用增强的for循环将所有对象保存到DB的方法。

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

/**
 * save the playQuestion to DataBase
 */
public void savePlayersQuestionsToDB() {

    for (Play_Questions pQ : playQuestionList) {
        if (pQ == null) {
            System.out.println("Play Question List is empty");
        } else
            try {
                ConnectionClass.createPlaySessionInDB(pQ.getPlayer_id(),
                        pQ.getQuestion_tbl_id(), pQ.getAns(),
                        pQ.getPlayer_score(), pQ.getPlay_session_id());
                System.out.println("Worked check DB --->>");
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                System.out
                        .println("Error with ElbtView savePlayersQuestionsToDB()");
            }
    }

以下是Connection Class

中的方法
    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();
    }
}

这是Play_Questions类

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

4 个答案:

答案 0 :(得分:0)

这是我的方法,你最好使用一种非常透明的方法来模拟接近现实生活场景的问题。

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




}

现在,在成功登录玩家对象后,封装了每个玩家的所有操作的玩家类被添加到会话中,它处理诸如标记,保存到数据库等操作

/**
 * 
 *  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);
        }
    }

}

因此,任何时候玩家回答你打电话的问题

p.answerQuestion(Question q , Answer a)

问题对象是已回答的特定问题,并且创建了答案对象,以匹配问题。 U还可以通过在播放器类上添加一个名为current_question的值来跟踪用户当前的问题,使用getter和setter(问题对象)来跟踪当前问题,以便用户可以返回上一个问题然后调用

p.updateAnswer(Question q, Answer a)

同样的事情你传递特定的问题和新的答案对象

p.savePlayerData()

将数据保存到数据库

p.autoMark()

在保存记录之前,在p.savePlayerData()方法中调用此方法,因此数据库仅保留最终评估&amp;标记记录,这对于智能报告非常有用,例如谁得分最高。如果您有其他问题可以联系我tyger2007@gmail.com。

答案 1 :(得分:0)

好的,我确实设法实现了我想要做的事情,这里是修改后的代码,以帮助其他人遇到同样的问题。这不是确定的方法,只是我现在知道的唯一方法来实现我需要的东西。如果有人有一个更好,更快的方式,我很想知道。从这个帖子中获得了一些灵感Java: Insert multiple rows into MySQL with PreparedStatement

这是我调用的方法,将每个回答的问题保存到playQuestionList和下一个方法savePlayersQuestionsToDB(),而不是在这里工作,我将Arraylist传递给Connection Class并在那里循环。

/**
 * 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();
    }

}

对更好的建议持开放态度。

GMAN

答案 2 :(得分:0)

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

  1. 隔离问题,播放器,答案对象,像Play_Question这样的对象会使您的应用程序难以动态扩展。
  2. 使用Iterator作为循环,它经过优化,优于循环,特别是在集合中。
  3. 对我来说,如果它是桌面应用程序,我自然会使用单例连接类。 JNDI如果是一个Web应用程序,连接类使用连接池,因此我的应用程序不会为每个数据库请求打开一个新连接,它会使您的应用程序在桌面应用程序的db请求[http://jolbox.com/ bonecp连接池中超快网络使用JNDI]

    地图非常容易使用它的一对键/值对,所有相同的好工作,并享受乐趣。

答案 3 :(得分:0)

没关系,花了相当长的时间来开发通常我总是按比例开发的应用程序,大声笑,我在方法中的Players类中使用了迭代器savePlayerData()你总是可以将它与你的集合类一起使用。