繁体   English   中英

从ArrayList将数据插入MySql DB <T>

[英]Insert Data to MySql DB from ArrayList<T>

任何人都可以帮我做得更好一点,我有一个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()");
            }
    }

这是连接类中的方法

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

您的帮助使我的代码更好一些,将不胜感激。

man

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

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




}

现在,成功登录后将每个播放器的所有操作封装起来的播放器类将一个播放器对象添加到会话中,它处理诸如标记,保存到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);
        }
    }

}

因此,只要玩家回答您打给您的问题

p.answerQuestion(Question q , Answer a)

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

p.updateAnswer(Question q, Answer a)

您通过相同的问题传递新的答案对象和新对象

p.savePlayerData()

将数据保存到数据库

p.autoMark()

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

好的,我确实设法实现了我想做的事情,这是经过修改的代码,可以帮助遇到相同问题的其他人。 这不是确定的方法,而这只是我目前知道的实现我所需要的唯一方法。 如果有人有一个更好,更快的方法,我很想知道。 Java:从此线程中获得一些启发:使用PreparedStatement将多行插入MySQL

这是我调用的方法,用于保存对playQuestionList回答的每个问题以及下一个方法savePlayersQuestionsToDB(),而不是在此处进行工作,而是将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();
    }

}

坚决接受更好的建议。

man

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

  1. 隔离问题,播放器,回答对象,拥有像Play_Question这样的对象将使您的应用程序难以动态扩展。
  2. 对您的循环使用Iterator,对它进行了优化,使其性能比循环更好,尤其是在集合中。
  3. 对我来说,如果它是桌面应用程序,我自然会使用单例连接类;如果它是Web应用程序,我自然会使用JNDI;连接类使用连接池,因此我的应用程序不会为每个数据库请求打开一个新连接,这会使您的应用程序超快在数据库请求中[如果Web使用JNDI,则为桌面应用程序提供http://jolbox.com/ bonecp连接池]

    地图非常容易使用,它是键/值对的例子,同样出色,而且很有趣。

没关系,花了很多时间来开发应用程序,这些应用程序我通常会一直按比例开发,大声笑,我在saveslayerData()方法的Players类中使用了迭代器,您可以将其始终与集合类一起使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM