2014-02-07 21 views
0

我有一個應用程序,它創建了一些查詢(更新或插入),然後執行每個查詢。如何將字符串寫入容器以便在循環之後使用?

整個代碼工作正常,但我看到我的服務器IO延遲在這個過程中太多了。

代碼執行一個週期爲1分鐘的循環。

然後我想要做的是將每個查詢寫入內存,而不是執行它,然後,一旦我有整個查詢列表執行,使用mysql中的「LOAD DATA LOCAL INFILE」,這將花費更少的時間。

我的問題是:如何在Java中的「文件」或「任何其他容器」中將所有查詢(字符串對象)寫入循環之後使用它?

@ user3283548這是我的示例代碼:

的Class1:

import java.util.ArrayList; 

public class Class1 { 



public static void main(String[] args) throws Exception { 
    // TODO Auto-generated method stub 

    ArrayList<String> Staff=new ArrayList<String>(); 
    Staff.add("tom"); 
    Staff.add("Laura"); 
    Staff.add("Patricia"); 
    for (int x = 0; x < Staff.size(); x++) { 
     System.out.println(Staff.get(x)); 
     Class2 user = new Class2 (Staff.get(x)); 
     user.checkUser(); 

    } 
} 

} 

等級2:

public class Class2 { 

private String user; 

public Class2(String user){ 
    this.user=user; 
} 
public void checkUser() throws Exception{ 

if (user.equals("tom")){ 
     String queryUser="update UsersT set userStatus='2' where UserName='"+user+"';"; 
     Class3 updateUser = new Class3(queryUser); 
     updateUser.UpdateQuery();; 
}else{ 
     String queryUser="Insert into UsersT (UserName,userStatus)Values('"+user+"','1');"; 
     Class3 updateUser = new Class3(queryUser); 
     updateUser.InsertQuery(); 
     System.out.println(user+" is not ton doing new insert"); 
} 

} 
} 

Class3的:

public class Class3 { 
    public String Query; 

    public Class3(String Query){ 
     this.Query = Query; 
    } 

    public void UpdateQuery() throws Exception{ 

    /*// Accessing Driver From Jar File 
    Class.forName("com.mysql.jdbc.Driver"); 
    //DB Connection 
    Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/default","root","1234567"); 
    String sql =Query; 
    PreparedStatement pst = con.prepareStatement(sql);*/ 

    System.out.println(Query); //Just to test 

    //pst.execute(); 
} 
    public void InsertQuery() throws Exception{ 

     /*// Accessing Driver From Jar File 
     Class.forName("com.mysql.jdbc.Driver"); 
     //DB Connection 
     Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/default","root","1234567"); 
     String sql =Query; 
     PreparedStatement pst = con.prepareStatement(sql);*/ 

     System.out.println(Query); //Just to test 

     //pst.execute(); 
    } 
} 

然後,我想做的事在中創建一個ArraList Class1並在Class3中使用它來收集所有必須執行的查詢。

這個想法是在主進程完成後一次執行查詢列表,而不是爲Class1循環中的每個元素執行查詢。我想這樣做,因爲我認爲這將是花費較少的資源IO從服務器HD

回答

2

你的循環可能是太慢了,因爲你建立使用字符串

我大膽猜測你的字符串「再這樣搞

String query = "SELECT * FROM " + variablea + " WHERE + variableb + " = " ...

如果你正在做大量的字符串連接,然後使用StringBuilder因爲每次你改變它實際上是重新創建一個字符串,它是昂貴的時間。只需將您的代碼更改爲使用StringBuilder而不是字符串,可能會將您的循環執行時間縮短爲幾個MS。只需撥打.toString()方法StringBuilder obj即可獲取字符串。

存儲對象

如果你想存儲的東西爲了以後使用你應該把它存放在Collection。如果你想要一個鍵值關係,然後使用Map(HashMap會適合你)。如果你只想使用ListArrayList是最流行的)。

因此,舉例來說,如果我想保存查詢字符串我以後會用...

  1. 構造一個使用StringBuilder的字符串。
  2. 把字符串(通過調用。的toString()轉換成一個HashMap
  3. 獲取從HashMap中的查詢字符串...

你永遠不應該的事情存儲在磁盤上,如果你不需要他們將超過應用程序重新啓動持續的,甚至那麼我d將它們存儲在不在文件中的數據庫中。

希望這會有所幫助。

感謝

大衛

編輯:UPDATE根據您發佈您的代碼:

確定,這需要一些重大的重新分解!

我把它保持得很簡單,因爲我沒有很多時間來全面地重新編寫。

我評論過我所做的更正。

您的主要問題是創建循環中的對象。您應該只創建一個對象,因爲創建對象很昂貴。

我也糾正了其他編碼問題,並取代了for循環,因爲你不應該像那樣寫它。我也將類重命名爲有用的東西。

我沒有測試過,所以你可能需要做一些工作才能使它工作。但是這應該快很多。

OLD CLASS 1

import java.util.ArrayList; 
import java.util.List; 

public class StaffChecker { 


public static void main(String[] args) throws Exception { 

    // Creating objects is expensive, you should do this as little as possible 
    StaffCheckBO staffCheckBO = new StaffCheckBO(); 

    // variables should be Camel Cased and describe what they hold 
    // Never start with ArrayList start with List you should specific the interface on the left side. 
    List<String> staffList = new ArrayList<String>(); 
    staffList.add("tom"); 
    staffList.add("Laura"); 
    staffList.add("Patricia"); 

    // use a foreach loop not a (int x = 0 ...) This is the preffered method. 
    for (String staffMember : staffList) { 
     // You now dont need to use .get() you can access the current variable using staffMember 
     System.out.println(staffMember); 

     // Do the work 
     staffCheckBO.checkUser(staffMember); 
    } 
    } 
} 

OLD CLASS 2

/** 
* Probably not really any need for this class but I'll assume further business logic may follow. 
*/ 
public class StaffCheckBO { 

// Again only create our DAO once...CREATING OBJECTS IS EXPENSIVE. 
private StaffDAO staffDAO = new StaffDAO(); 

public void checkUser(String staffMember) throws Exception{ 

boolean staffExists = staffDAO.checkStaffExists(staffMember); 

    if(staffExists) { 
     System.out.println(staffMember +" is not in database, doing new insert."); 
     staffDAO.insertStaff(staffMember); 
    } else { 
     System.out.println(staffMember +" has been found in the database, updating user."); 
     staffDAO.updateStaff(staffMember); 
    } 
    } 
} 

OLD CLASS 3

import java.sql.*; 

/** 
* You will need to do some work to get this class to work fully and this is obviously  basic but its to give you an idea. 
*/ 
public class StaffDAO { 

public boolean checkStaffExists(String staffName) { 
    boolean staffExists = false; 

    try { 
     String query = "SELECT * FROM STAFF_TABLE WHERE STAFF_NAME = ?"; 
     PreparedStatement preparedStatement = getDBConnection().prepareStatement(query); 

     // Load your variables into the string in order to be safe against injection attacks. 
     preparedStatement.setString(1, staffName); 
     ResultSet resultSet = preparedStatement.executeQuery(); 

     // If a record has been found the staff member is in the database. This obviously doesn't account for multiple staff members 
     if(resultSet.next()) { 
      staffExists = true; 
     } 
    } catch (SQLException e) { 
     System.out.println("SQL Exception in getStaff: " + e.getMessage()); 
    } 

    return staffExists; 
} 

// Method names should be camel cased 
public void updateStaff(String staffName) throws Exception { 

    try { 
     String query = "YOUR QUERY"; 
     PreparedStatement preparedStatement = getDBConnection().prepareStatement(query); 

     // Load your variables into the string in order to be safe against injection attacks. 
     preparedStatement.setString(1, staffName); 
     ResultSet resultSet = preparedStatement.executeQuery(); 

    } catch (SQLException e) { 
     System.out.println("SQL Exception in getStaff: " + e.getMessage()); 
    } 

} 

public void insertStaff(String staffName) throws Exception { 

    try { 
     String query = "YOUR QUERY"; 
     PreparedStatement preparedStatement = getDBConnection().prepareStatement(query); 

     // Load your variables into the string in order to be safe against injection attacks. 
     preparedStatement.setString(1, staffName); 
     ResultSet resultSet = preparedStatement.executeQuery(); 

    } catch (SQLException e) { 
     System.out.println("SQL Exception in getStaff: " + e.getMessage()); 
    } 

} 


/** 
* You need to abstract the connection logic away so you avoid code reuse. 
* 
* @return 
*/ 
private Connection getDBConnection() { 
    Connection connection = null; 

    try { 
     Class.forName("com.mysql.jdbc.Driver"); 

     connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/default", "root", "1234567"); 
    } catch (ClassNotFoundException e) { 
     System.out.println("Could not find class. DB Connection could not be created: " + e.getMessage()); 
    } catch (SQLException e) { 
     System.out.println("SQL Exception. " + e.getMessage()); 
    } 

    return connection; 
    } 
} 
+0

感謝您的編輯Rembo。第一篇文章,所以我會確保下一次正確的代碼塊內的代碼:)。 –

+0

感謝您的信息。關於字符串,不完全是我的問題,因爲我不得不創建只有100個字符串沒有更多。所花費的時間是因爲在循環內部,我打電話給別人上課花費一點時間做一些其他操作。但無論如何,我不知道它,並確定我會在我的代碼的其他部分使用它。讓我分享這個清晰的例子(http://www.yoda.arachsys.com/java/strings.html) – Sallyerik

+0

關於存儲對象:我知道了,我可以使用ArrayList,然後使用它。但我現在的問題是,我的主類中的循環調用其他類不返回任何東西,第二類做一些操作,然後直接調用我的Update_Databse_Class在我的數據庫中執行查詢。有什麼辦法可以在我的主類中創建一個ArrayList,它可以用於任何其他類,直到它被刪除/銷燬/刪除/關閉或其他任何類。 – Sallyerik

相關問題