任何人都可以帮助我做得更好一点,我有一个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
答案 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)
我必须说,因为这个解决方案现在实际上运行得很好,但在长期内它可能仍然会带来一些问题,它实际上取决于应用程序的性质,是否是一个将被许多用户部署和使用的应用程序?或者它只是一个测试应用程序?,无论如何我建议您正确建模对象,因为这是面向对象编程中最重要的事情, 我的建议:
对我来说,如果它是桌面应用程序,我自然会使用单例连接类。 JNDI如果是一个Web应用程序,连接类使用连接池,因此我的应用程序不会为每个数据库请求打开一个新连接,它会使您的应用程序在桌面应用程序的db请求[http://jolbox.com/ bonecp连接池中超快网络使用JNDI]
地图非常容易使用它的一对键/值对,所有相同的好工作,并享受乐趣。
答案 3 :(得分:0)
没关系,花了相当长的时间来开发通常我总是按比例开发的应用程序,大声笑,我在方法中的Players类中使用了迭代器savePlayerData()你总是可以将它与你的集合类一起使用。