ERLEDIGT
NEIN
NEIN
ANTWORTEN
48
48
ZUGRIFFE
11133
11133
EMPFEHLEN
-
15.06.07 11:54 #31
Danke nochmal für deine Mühe. Bei meiner Lösung habe ich die Tableklasse so implementiert, dass Sie alle Daten in ein Array reinschreibt. Auf diese Art und Weise, kann ich mir zwar sehr viel größere Tabellen anzeigen lassen, als innerhalb einer einzigen ScrollPane aber bei wirklich großen Tabellen hab ich natürlich immernoch das Speicherproblem. Meine Frage ist wie kann ich die Methoden boolean moveToRow(long row); und String valueAt(long row, int column); ohne scrollable Resultsets implementieren?
-
30.08.07 11:44 #32
- Registriert seit
- May 2007
- Ort
- Riedstadt (Hessen)
- Beiträge
- 354
Aus aktuellem Anlass (Nachfrage) führe ich diesen Thread weiter...
Zum Problem:
Ich hatte Dir ein SQL-Beispiel gepostet, mit dem Du die Daten "päckchenweise" aus der Datenbank auslesen kannst. Wenn Du gemäß meines Beispiels im SQL-Statement Zeilennummern erzeugst, kannst Du mit einer einfachen Abfrage jeweils so viele Datensätze lesen, wie Du verarbeiten kannst.
Hier nochmal der SQLString:
SELECT emp_id, lname, fname, job_id,
(SELECT COUNT(*) FROM employee e2 WHERE e2.lname <= e.lname AND e2.job_id = 10) AS rownumber
FROM employee e
WHERE job_id = 10
ORDER BY lname
Der Unterselect "(SELECT COUNT(*) FROM employee e2 WHERE e2.lname <= e.lname AND e2.job_id = 10) AS rownumber" erzeugt eine Zeilennummer.
Mache daraus einen View (Abfrage), dann kannst du einen Select auf den view Ausführen, hast aber immer zeilennummern in der Abfrage.
Dadurch kannst du mit
Select * from MyView where rownumber between x and y
die Daten paketweise lesen. Also nicht alle Daten auf einmal in ein Array packen, sondern das TableModel (oder wer auch immer) lädt bei Bedarf immer nur wenige hundert Zeilen über diesen View ein. damit können Deine Tabellen Terrabyte groß sein, Du liest nur was Du brauchst...
GrußI didn't write this; a very complex macro did.
-
03.09.07 14:53 #33
Vielen Dank für Deine Antwort!
Mein Problem ist leider, dass der User meines ies die DB zur Laufzeit auswählt und auch SQL-Statements zur Laufzeit eingeben können soll. Von diesen Statements brauche ich denn das Ergebnis innerhalb meiner JTable, deshalb kann ich keine Views anlegen, weil ich eben vorher nicht weis wie die entsprechende DB aussieht.
Ich könnte höchstens versuchen die Strings mit den SQL-Statements auseinander zu nehmen und automatisch ein Feld mit der Zeilennummer in diese Statements einzufügen, aber allein schon bei dem Gedanken daran wird mir schlecht
-
03.09.07 17:18 #34
- Registriert seit
- May 2007
- Ort
- Riedstadt (Hessen)
- Beiträge
- 354
Hi,
wenn ich mal mehr Zeit habe, werde ich dem dem Problem mal näher widmen. Aaaaber andere Leute haben das Problem ja auch. In der Regel wird es dadurch gelöst, dass man erst einen Select count(*) auf die where -Klausel los läßt, dann beim Überschreiten einer Schwelle den Anwender zur Präzessierung der Auswahl auffordert.
Ist es möglich mehr über die Hintergründe zu erfahren? Möglicherweise, kann man das Problem ja an einer ganz anderen Stelle lösen.
Meine Neugier ist geweckt.
GrüßeI didn't write this; a very complex macro did.
-
14.09.07 14:09 #35
Also... ich hab mich dann mal entschlossen für verschiedene DBMSs verschiedene PagingModels zu schreiben.
hier einmal das zu MSSQL geht auch mit Oracle:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import javax.swing.table.*; import javax.swing.*; import java.awt.event.*; public class MSSQLPagingModel extends AbstractTableModel { private Connection conn; private ResultSet rs; private ResultSetMetaData rsmd; private String statement; protected int pageSize; protected int pageOffset; private int row; private int rowCount; private int columnCount; private String[] columnNames; protected String[][] data; public MSSQLPagingModel(String statement) { this.statement = statement; conn = DBConnection.getConnection(); row = 0; pageOffset = 0; pageSize = 100; try { rs = DBConnection.executeQuery(statement); rsmd = rs.getMetaData(); //Zeilenzahl berechnen rs.last(); rowCount = rs.getRow(); rs.beforeFirst(); ////// columnCount = rsmd.getColumnCount(); columnNames = new String[columnCount]; for (int i=0; i<columnCount; i++) { columnNames[i] = rsmd.getColumnName(i+1); } data = new String[pageSize][columnCount]; int i=0; while (rs.next() && i<pageSize) { for (int j=0; j<columnCount; j++) { data[i][j]= rs.getString(j+1); } i++; } rs.close(); } catch (SQLException e) { e.printStackTrace(); } } //Return values appropriate for the visible table part. public int getRowCount() { return Math.min(pageSize, rowCount); } public int getColumnCount() { return columnCount; } // Work only on the visible part of the table. public Object getValueAt(int row, int col) { return data[row][col]; } public String getColumnName(int col) { return columnNames[col]; } //Use this method to figure out which page you are on. public int getPageOffset() { return pageOffset; } public int getPageCount() { return (int)Math.ceil((double)rowCount / pageSize); } // Use this method if you want to know how big the real table is . . . we // could also write "getRealValueAt()" if needed. public int getRealRowCount() { return rowCount; } public int getPageSize() { return pageSize; } public void setPageSize(int s) { if (s == pageSize) { return; } int oldPageSize = pageSize; pageSize = s; pageOffset = (oldPageSize * pageOffset) / pageSize; fireTableDataChanged(); if (pageSize < oldPageSize) { fireTableRowsDeleted(pageSize, oldPageSize - 1); } else { fireTableRowsInserted(oldPageSize, pageSize - 1); } } //Update the page offset and fire a data changed (all rows). public void pageDown() { if (pageOffset < getPageCount() - 1) { pageOffset++; //System.out.println(pageOffset); try { rs = DBConnection.executeQuery(statement); rs.first(); rs.relative((pageOffset*pageSize)-1); int i=0; while (rs.next() && i<pageSize) { for (int j=0; j<columnCount; j++) { data[i][j] = rs.getString(j+1); } i++; } //letzte Seite mit leerzeichen füllen for (int k=i; k<pageSize; k++) { for (int j=0; j<columnCount; j++) { data[k][j] = ""; } } } catch (SQLException e) { e.printStackTrace(); } fireTableDataChanged(); } } // Update the page offset and fire a data changed (all rows). public void pageUp() { if (pageOffset > 0) { pageOffset--; //System.out.println(pageOffset); try { rs = DBConnection.executeQuery(statement); rs.first(); rs.relative((pageOffset*pageSize)-1); //System.out.println(test); int i=0; while (rs.next() && i<pageSize) { for (int j=0; j<columnCount; j++) { data[i][j] = rs.getString(j+1); } i++; } } catch (SQLException e) { e.printStackTrace(); } fireTableDataChanged(); } } // We provide our own version of a scrollpane that includes // the page up and page down buttons by default. public static JScrollPane createPagingScrollPaneForTable(JTable jt) { JScrollPane jsp = new JScrollPane(jt); TableModel tmodel = jt.getModel(); // Don't choke if this is called on a regular table . . . if (! (tmodel instanceof MySQLPagingModel || tmodel instanceof MSSQLPagingModel || tmodel instanceof PagingModel)) { return jsp; } // Okay, go ahead and build the real scrollpane final MSSQLPagingModel model = (MSSQLPagingModel)tmodel; final JButton upButton = new JButton(/*new ArrowIcon(ArrowIcon.UP)*/"UP"); upButton.setEnabled(false); // starts off at 0, so can't go up final JButton downButton = new JButton(/*new ArrowIcon(ArrowIcon.DOWN)*/"DOWN"); if (model.getPageCount() <= 1) { downButton.setEnabled(false); // One page...can't scroll down } upButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { model.pageUp(); // If we hit the top of the data, disable the up button. if (model.getPageOffset() == 0) { upButton.setEnabled(false); } downButton.setEnabled(true); } } ); downButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { model.pageDown(); // If we hit the bottom of the data, disable the down button. if (model.getPageOffset() == (model.getPageCount() - 1)) { downButton.setEnabled(false); } upButton.setEnabled(true); } } ); // Turn on the scrollbars; otherwise we won't get our corners. jsp.setVerticalScrollBarPolicy (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); jsp.setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); // Add in the corners (page up/down). jsp.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, upButton); jsp.setCorner(ScrollPaneConstants.LOWER_RIGHT_CORNER, downButton); return jsp; } }
Der obige code funktioniert leider nicht mit MySQL. Da kommt immernoch dieser Speichererror. Also hab ich für MySQL ein eigenes PageingModel geschrieben:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import javax.swing.table.*; import javax.swing.*; import java.awt.event.*; public class MySQLPagingModel extends AbstractTableModel { private Connection conn; private ResultSet rs; private ResultSetMetaData rsmd; private String statement; protected int pageSize; protected int pageOffset; private int row; private int rowCount; private int columnCount; private String[] columnNames; protected String[][] data; public MySQLPagingModel(String statement) { this.statement = statement; conn = DBConnection.getConnection(); row = 0; pageOffset = 0; pageSize = 100; try { rs = DBConnection.executeQuery("SELECT * FROM ("+statement+") AS tmp LIMIT 0, "+pageSize); rsmd = rs.getMetaData(); //Zeilenzahl berechnen Statement stm2 = conn.createStatement(); ResultSet rs2 = stm2.executeQuery("SELECT COUNT(*) FROM ("+statement+") AS tmp"); rs2.next(); rowCount = rs2.getInt(1); rs2.close(); stm2.close(); ////// columnCount = rsmd.getColumnCount(); columnNames = new String[columnCount]; for (int i=0; i<columnCount; i++) { columnNames[i] = rsmd.getColumnName(i+1); } data = new String[pageSize][columnCount]; int i=0; while (rs.next()) { for (int j=0; j<columnCount; j++) { data[i][j]= rs.getString(j+1); } i++; } rs.close(); } catch (SQLException e) { e.printStackTrace(); } } //Return values appropriate for the visible table part. public int getRowCount() { return Math.min(pageSize, rowCount); } public int getColumnCount() { return columnCount; } // Work only on the visible part of the table. public Object getValueAt(int row, int col) { //int realRow = row + (pageOffset * pageSize); return data[row][col]; } public String getColumnName(int col) { return columnNames[col]; } //Use this method to figure out which page you are on. public int getPageOffset() { return pageOffset; } public int getPageCount() { return (int)Math.ceil((double)rowCount / pageSize); } // Use this method if you want to know how big the real table is . . . we // could also write "getRealValueAt()" if needed. public int getRealRowCount() { return rowCount; } public int getPageSize() { return pageSize; } /* public void setPageSize(int s) { if (s == pageSize) { return; } int oldPageSize = pageSize; pageSize = s; pageOffset = (oldPageSize * pageOffset) / pageSize; fireTableDataChanged(); */ /* if (pageSize < oldPageSize) { fireTableRowsDeleted(pageSize, oldPageSize - 1); } else { fireTableRowsInserted(oldPageSize, pageSize - 1); } */ //} //Update the page offset and fire a data changed (all rows). public void pageDown() { System.out.println(pageOffset); if (pageOffset < getPageCount() - 1) { pageOffset++; try { rs = DBConnection.executeQuery("SELECT * FROM ("+statement+") AS tmp LIMIT "+(pageOffset*pageSize)+", "+pageSize); int i=0; while (rs.next() /*&& i<pageSize*/) { for (int j=0; j<columnCount; j++) { data[i][j] = rs.getString(j+1); } i++; } for (int k=i; k<pageSize; k++) { for (int j=0; j<columnCount; j++) { data[k][j] = ""; } } } catch (SQLException e) { e.printStackTrace(); } fireTableDataChanged(); } } // Update the page offset and fire a data changed (all rows). public void pageUp() { System.out.println(pageOffset); if (pageOffset > 0) { pageOffset--; try { String test = "SELECT * FROM ("+statement+") AS tmp LIMIT "+(pageOffset*pageSize)+", "+pageSize; rs = DBConnection.executeQuery(test); System.out.println(test); int i=0; while (rs.next() /*&& i<pageSize*/) { for (int j=0; j<columnCount; j++) { data[i][j] = rs.getString(j+1); } i++; } } catch (SQLException e) { e.printStackTrace(); } fireTableDataChanged(); } } // We provide our own version of a scrollpane that includes // the page up and page down buttons by default. public static JScrollPane createPagingScrollPaneForTable(JTable jt) { JScrollPane jsp = new JScrollPane(jt); TableModel tmodel = jt.getModel(); // Don't choke if this is called on a regular table . . . if (! (tmodel instanceof MySQLPagingModel || tmodel instanceof PagingModel)) { return jsp; } // Okay, go ahead and build the real scrollpane final MySQLPagingModel model = (MySQLPagingModel)tmodel; final JButton upButton = new JButton(/*new ArrowIcon(ArrowIcon.UP)*/"UP"); upButton.setEnabled(false); // starts off at 0, so can't go up final JButton downButton = new JButton(/*new ArrowIcon(ArrowIcon.DOWN)*/"DOWN"); if (model.getPageCount() <= 1) { downButton.setEnabled(false); // One page...can't scroll down } upButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { model.pageUp(); // If we hit the top of the data, disable the up button. if (model.getPageOffset() == 0) { upButton.setEnabled(false); } downButton.setEnabled(true); } } ); downButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { model.pageDown(); // If we hit the bottom of the data, disable the down button. if (model.getPageOffset() == (model.getPageCount() - 1)) { downButton.setEnabled(false); } upButton.setEnabled(true); } } ); // Turn on the scrollbars; otherwise we won't get our corners. jsp.setVerticalScrollBarPolicy (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); jsp.setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); // Add in the corners (page up/down). jsp.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, upButton); jsp.setCorner(ScrollPaneConstants.LOWER_RIGHT_CORNER, downButton); return jsp; } }
So das funktioniert zwar Theoretisch. Aber jeder Pagewechsel dauert ewig (so 30 - 45 sec) bei einer PageSize von 100. Irgendwie scheint der MySQL-Server die ergebnisse aber zu cachen oder irgendwelche temporären StoredProcedures anzulegen oder weiß der Geier. Auf jeden Fall geht das Angucken von Seiten, die ich schonmal angeguckt hab richtig schön schnell, auch wenn ich mein Prog zwischendurch schliesse und wieder neu öffne.
Meine Frage wäre, wieso ist das so lahm? Wie kann ich das schneller machen?
Und so aus mehr allgemeinem Interesse. Wie speichert der MySQL-Server welche Daten, dass ich so schnell darauf zugriff habe, wenn ich sie vorher schon irgendwann mal abgerufen habe? (Der kann ja nicht hunderte von Ergebnissmengen cachen oder etwa doch?)
-
14.09.07 14:21 #36
- Registriert seit
- May 2007
- Ort
- Riedstadt (Hessen)
- Beiträge
- 354
Hi,
hier mal ein Schnellschuss aus der Hüfte... Ich würde die Statements, wenn es geht in PreparedStatements umwandeln. Dann werden Sie oft deutlich schneller ausgeführt.
Soweit ich weiss, muss bei einem Statement immer der SQL-String von dem DBMS geparst und ein Ausführungsplan erstellt werden. Wenn Du Glück hast, wird das Statement danach gecached.
Ein PreparedStatement macht das gleich und landet gleich im Cache. Es kann parametriesiert werden und sollte deswegen die Geschwindigkeit erhöhen...
Versuchs mal.
GrussI didn't write this; a very complex macro did.
-
14.09.07 15:42 #37
Logisch da hätt ich auch mal drauf kommen können.
Aber, ich hab das jetzt gemacht und scheinbar scheinen preparedStatements in verbindung mit LIMIT nicht viel zu nützen. Denn jetzt hab ich ca. 15sec pro zu Ladender Seite. Allerding cacht der SQLServer jetzt nix mehr und so dauert der seitenaufbau immer 15sec.
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import javax.swing.table.*; import javax.swing.*; import java.awt.event.*; public class MySQLPagingModel extends AbstractTableModel { private Connection conn; private PreparedStatement preparedStatement; private ResultSet rs; private ResultSetMetaData rsmd; private String statement; protected int pageSize; protected int pageOffset; private int row; private int rowCount; private int columnCount; private String[] columnNames; protected String[][] data; public MySQLPagingModel(String statement) { this.statement = statement; conn = DBConnection.getConnection(); row = 0; pageOffset = 0; pageSize = 100; try { preparedStatement = conn.prepareStatement("SELECT * FROM ("+statement+") AS tmp LIMIT ?, ?"); rs = DBConnection.executeQuery("SELECT * FROM ("+statement+") AS tmp LIMIT 0, "+pageSize); rsmd = rs.getMetaData(); //Zeilenzahl berechnen Statement stm2 = conn.createStatement(); ResultSet rs2 = stm2.executeQuery("SELECT COUNT(*) FROM ("+statement+") AS tmp"); rs2.next(); rowCount = rs2.getInt(1); rs2.close(); stm2.close(); ////// columnCount = rsmd.getColumnCount(); columnNames = new String[columnCount]; for (int i=0; i<columnCount; i++) { columnNames[i] = rsmd.getColumnName(i+1); } data = new String[pageSize][columnCount]; int i=0; while (rs.next()) { for (int j=0; j<columnCount; j++) { data[i][j]= rs.getString(j+1); } i++; } rs.close(); } catch (SQLException e) { e.printStackTrace(); } } //Return values appropriate for the visible table part. public int getRowCount() { return Math.min(pageSize, rowCount); } public int getColumnCount() { return columnCount; } // Work only on the visible part of the table. public Object getValueAt(int row, int col) { return data[row][col]; } public String getColumnName(int col) { return columnNames[col]; } //Use this method to figure out which page you are on. public int getPageOffset() { return pageOffset; } public int getPageCount() { return (int)Math.ceil((double)rowCount / pageSize); } // Use this method if you want to know how big the real table is . . . we // could also write "getRealValueAt()" if needed. public int getRealRowCount() { return rowCount; } public int getPageSize() { return pageSize; } /* public void setPageSize(int s) { if (s == pageSize) { return; } int oldPageSize = pageSize; pageSize = s; pageOffset = (oldPageSize * pageOffset) / pageSize; fireTableDataChanged(); */ /* if (pageSize < oldPageSize) { fireTableRowsDeleted(pageSize, oldPageSize - 1); } else { fireTableRowsInserted(oldPageSize, pageSize - 1); } */ //} //Update the page offset and fire a data changed (all rows). public void pageDown() { System.out.println(pageOffset); if (pageOffset < getPageCount() - 1) { pageOffset++; try { preparedStatement.setInt(1, (pageOffset*pageSize)); preparedStatement.setInt(2, pageSize); rs = preparedStatement.executeQuery(); int i=0; while (rs.next() /*&& i<pageSize*/) { for (int j=0; j<columnCount; j++) { data[i][j] = rs.getString(j+1); } i++; } for (int k=i; k<pageSize; k++) { for (int j=0; j<columnCount; j++) { data[k][j] = ""; } } } catch (SQLException e) { e.printStackTrace(); } fireTableDataChanged(); } } // Update the page offset and fire a data changed (all rows). public void pageUp() { System.out.println(pageOffset); if (pageOffset > 0) { pageOffset--; try { //String test = statement+" LIMIT "+(pageOffset*pageSize)+", "+((pageOffset*pageSize)+pageSize); //String test = "SELECT * FROM ("+statement+") AS tmp LIMIT "+(pageOffset*pageSize)+", "+pageSize; //rs = DBConnection.executeQuery(test); //System.out.println(test); preparedStatement.setInt(1, (pageOffset*pageSize)); preparedStatement.setInt(2, pageSize); rs = preparedStatement.executeQuery(); int i=0; while (rs.next() /*&& i<pageSize*/) { for (int j=0; j<columnCount; j++) { data[i][j] = rs.getString(j+1); } i++; } } catch (SQLException e) { e.printStackTrace(); } fireTableDataChanged(); } } // We provide our own version of a scrollpane that includes // the page up and page down buttons by default. public static JScrollPane createPagingScrollPaneForTable(JTable jt) { JScrollPane jsp = new JScrollPane(jt); TableModel tmodel = jt.getModel(); // Don't choke if this is called on a regular table . . . if (! (tmodel instanceof MySQLPagingModel || tmodel instanceof PagingModel)) { return jsp; } // Okay, go ahead and build the real scrollpane final MySQLPagingModel model = (MySQLPagingModel)tmodel; final JButton upButton = new JButton(/*new ArrowIcon(ArrowIcon.UP)*/"UP"); upButton.setEnabled(false); // starts off at 0, so can't go up final JButton downButton = new JButton(/*new ArrowIcon(ArrowIcon.DOWN)*/"DOWN"); if (model.getPageCount() <= 1) { downButton.setEnabled(false); // One page...can't scroll down } upButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { model.pageUp(); // If we hit the top of the data, disable the up button. if (model.getPageOffset() == 0) { upButton.setEnabled(false); } downButton.setEnabled(true); } } ); downButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { model.pageDown(); // If we hit the bottom of the data, disable the down button. if (model.getPageOffset() == (model.getPageCount() - 1)) { downButton.setEnabled(false); } upButton.setEnabled(true); } } ); // Turn on the scrollbars; otherwise we won't get our corners. jsp.setVerticalScrollBarPolicy (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); jsp.setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); // Add in the corners (page up/down). jsp.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, upButton); jsp.setCorner(ScrollPaneConstants.LOWER_RIGHT_CORNER, downButton); return jsp; } }
-
14.09.07 18:11 #38
- Registriert seit
- May 2007
- Ort
- Riedstadt (Hessen)
- Beiträge
- 354
Hi,
dann weiss ich auch nicht weiter. Hört sich so an, als müsstest Du tief in den MySql abtauchen und das hat mit Java nix mehr zu tun. Die 15 bzw. 30 Sekunden wundern mich ehrlich gesagt ein wenig. Hast Du das mal nativ mit der MySQL-Console validiert?
Kannst Du die Daten denn nicht selbst cachen?
Wie auch immer, wenn Du eine Lösung findest, wäre ich sehr interessiert...
GrußI didn't write this; a very complex macro did.
-
17.09.07 12:13 #39
So, hab jez ne einigermaßen akzeptable Lösung gefunden.
Hab statt "Select * From ("+statement+") as tmp LIMIT blabla.
Einfach nur "("+statement+") Limit blabla" gemacht. Jetzt gehts schön schnell. Aber die letzte Page wird leider bis zur pageSize aufgefüllt.
Wenn ich also z.B. (Select * From tabelle LIMIT 0, 150) LIMIT 0, 200; ausführe bekomme ich leider 200 ergebnisse und keine 150.
Da das aber nur in der Anzeige so ist und zum Weiterverarbeiten das original Statement was der user eingegeben hat ausgeführt wird ist das jetzt nicht so wichtig.
hier nochmal komplett:
Code :1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; //import java.util.List; import javax.swing.table.*; import javax.swing.*; import java.awt.event.*; //import java.awt.*; public class MySQLPagingModel extends AbstractTableModel { private Connection conn; private PreparedStatement preparedStatement; private ResultSet rs; private ResultSetMetaData rsmd; private String statement; protected int pageSize; protected int pageOffset; private int row; private int rowCount; private int columnCount; private String[] columnNames; //protected Record[] data; protected String[][] data; public MySQLPagingModel(String statement) { this.statement = statement; conn = DBConnection.getConnection(); row = 0; pageOffset = 0; pageSize = 100; try { preparedStatement = conn.prepareStatement("("+statement+") LIMIT ?, ?"); rs = DBConnection.executeQuery("SELECT * FROM ("+statement+") AS tmp LIMIT 0, "+pageSize); //rs = DBConnection.executeQuery(statement); rsmd = rs.getMetaData(); //Zeilenzahl berechnen Statement stm2 = conn.createStatement(); ResultSet rs2 = stm2.executeQuery("SELECT COUNT(*) FROM ("+statement+") AS tmp"); rs2.next(); rowCount = rs2.getInt(1); rs2.close(); stm2.close(); ////// columnCount = rsmd.getColumnCount(); columnNames = new String[columnCount]; for (int i=0; i<columnCount; i++) { columnNames[i] = rsmd.getColumnName(i+1); } data = new String[pageSize][columnCount]; int i=0; while (rs.next()) { for (int j=0; j<columnCount; j++) { data[i][j]= rs.getString(j+1); } i++; } rs.close(); } catch (SQLException e) { e.printStackTrace(); } } //Return values appropriate for the visible table part. public int getRowCount() { return Math.min(pageSize, rowCount); } public int getColumnCount() { return columnCount; } // Work only on the visible part of the table. public Object getValueAt(int row, int col) { //int realRow = row + (pageOffset * pageSize); return data[row][col]; } public String getColumnName(int col) { return columnNames[col]; } //Use this method to figure out which page you are on. public int getPageOffset() { return pageOffset; } public int getPageCount() { return (int)Math.ceil((double)rowCount / pageSize); } // Use this method if you want to know how big the real table is . . . we // could also write "getRealValueAt()" if needed. public int getRealRowCount() { return rowCount; } public int getPageSize() { return pageSize; } /* public void setPageSize(int s) { if (s == pageSize) { return; } int oldPageSize = pageSize; pageSize = s; pageOffset = (oldPageSize * pageOffset) / pageSize; fireTableDataChanged(); */ /* if (pageSize < oldPageSize) { fireTableRowsDeleted(pageSize, oldPageSize - 1); } else { fireTableRowsInserted(oldPageSize, pageSize - 1); } */ //} //Update the page offset and fire a data changed (all rows). public void pageDown() { System.out.println(pageOffset); if (pageOffset < getPageCount() - 1) { pageOffset++; try { //rs = DBConnection.executeQuery(statement+" LIMIT "+(pageOffset*pageSize)+", "+((pageOffset*pageSize)+pageSize)); //preparedStatement = conn.prepareStatement("SELECT * FROM ("+statement+") AS tmp LIMIT ?, ?"); preparedStatement.setInt(1, (pageOffset*pageSize)); preparedStatement.setInt(2, pageSize); //rs = DBConnection.executeQuery("SELECT * FROM ("+statement+") AS tmp LIMIT "+(pageOffset*pageSize)+", "+pageSize); rs = preparedStatement.executeQuery(); int i=0; while (rs.next() /*&& i<pageSize*/) { for (int j=0; j<columnCount; j++) { data[i][j] = rs.getString(j+1); } i++; } rs.close(); for (int k=i; k<pageSize; k++) { for (int j=0; j<columnCount; j++) { data[k][j] = ""; } } } catch (SQLException e) { e.printStackTrace(); } fireTableDataChanged(); } } // Update the page offset and fire a data changed (all rows). public void pageUp() { System.out.println(pageOffset); if (pageOffset > 0) { pageOffset--; try { //String test = statement+" LIMIT "+(pageOffset*pageSize)+", "+((pageOffset*pageSize)+pageSize); //String test = "SELECT * FROM ("+statement+") AS tmp LIMIT "+(pageOffset*pageSize)+", "+pageSize; //rs = DBConnection.executeQuery(test); //System.out.println(test); preparedStatement.setInt(1, (pageOffset*pageSize)); preparedStatement.setInt(2, pageSize); rs = preparedStatement.executeQuery(); int i=0; while (rs.next() /*&& i<pageSize*/) { for (int j=0; j<columnCount; j++) { data[i][j] = rs.getString(j+1); } i++; } rs.close(); } catch (SQLException e) { e.printStackTrace(); } fireTableDataChanged(); } } // We provide our own version of a scrollpane that includes // the page up and page down buttons by default. public static JScrollPane createPagingScrollPaneForTable(JTable jt) { JScrollPane jsp = new JScrollPane(jt); TableModel tmodel = jt.getModel(); // Don't choke if this is called on a regular table . . . if (! (tmodel instanceof MySQLPagingModel || tmodel instanceof PagingModel)) { return jsp; } // Okay, go ahead and build the real scrollpane final MySQLPagingModel model = (MySQLPagingModel)tmodel; final JButton upButton = new JButton(/*new ArrowIcon(ArrowIcon.UP)*/"UP"); upButton.setEnabled(false); // starts off at 0, so can't go up final JButton downButton = new JButton(/*new ArrowIcon(ArrowIcon.DOWN)*/"DOWN"); if (model.getPageCount() <= 1) { downButton.setEnabled(false); // One page...can't scroll down } upButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { model.pageUp(); // If we hit the top of the data, disable the up button. if (model.getPageOffset() == 0) { upButton.setEnabled(false); } downButton.setEnabled(true); } } ); downButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent ae) { model.pageDown(); // If we hit the bottom of the data, disable the down button. if (model.getPageOffset() == (model.getPageCount() - 1)) { downButton.setEnabled(false); } upButton.setEnabled(true); } } ); // Turn on the scrollbars; otherwise we won't get our corners. jsp.setVerticalScrollBarPolicy (ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS); jsp.setHorizontalScrollBarPolicy (ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS); // Add in the corners (page up/down). jsp.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, upButton); jsp.setCorner(ScrollPaneConstants.LOWER_RIGHT_CORNER, downButton); return jsp; } }
-
17.09.07 12:37 #40
Eine Frage hätt ich da noch.
Wo hastn Du das ArrowIcon her?
new ArrowIcon(ArrowIcon.UP) kennt eclipse bei mir nicht
hab was gefunden:
org.gui4j.core.swing.calendar;
meintest Du das?Geändert von tekilla209 (17.09.07 um 12:50 Uhr)
-
17.09.07 18:16 #41
- Registriert seit
- May 2007
- Ort
- Riedstadt (Hessen)
- Beiträge
- 354
Ja, es gibt aber wohl noch mehr Varianten im Netz..
Schöne Lösung! Hast gut gekämpft....
GrüßeI didn't write this; a very complex macro did.
-
Ich habe gute Erfahrungen mit gc() gemacht. Nachdem ich mehrere Connection-Objekte angelegt hatte ist mir der Speicher übergelaufen, und ich war zu dämlich, die Sache mit close()-Statements in den Griff zu bekommen. Ich habe den Fehler dann durch ein try-catch lokalisiert, und im catch-Block den Garbage-Collector aufgerufen. Vom Programmierstil sicherlich quick&dirty, aber es funktioniert!
-
06.02.12 07:42 #43
- Registriert seit
- Feb 2012
- Beiträge
- 1
Hallo
ich hab eine frage:
Muß ich unbedingt den Zeiger auf null setzen, damit der GC das löscht?
Beispiel:
ich gebe
ein.Code :1 2 3
JLabel label = new JLabel(); //label = null; label = new JLabel();
wird das alte Objekt dann trotzdem vom GC gelöscht?
-
06.02.12 09:02 #44
- Registriert seit
- May 2007
- Ort
- Riedstadt (Hessen)
- Beiträge
- 354
Hallo
Objekte werden gelöscht, wenn sie nicht mehr erreichbar sind. Du musst den Zeiger nicht auf "null" setzen. Wenn keine zweite Referenz auf das JLabel verweist, wird es weggeräumt.I didn't write this; a very complex macro did.
-
Also ja, dein Code ist so in Ordnung.
Falls du die Frage deswegen stellst, weil es nicht gelöscht wird:
Es muss nicht sofort passieren.
Der GC kann das machen, wann er will.
PS: Willkommen bei tutorials.de
Netiquette (vA §15) und Nutzungsregeln (vA §4.8) einhalten! Programmcode in Codetags/Codeboxen.
Sehr gute Beiträge bitte Bewerten (Stern darunter oder "Danke").
"Funktioniert nicht" ist zu ungenau! Code, Fehlermeldungen, Verhalten des Programms, ...?
Ähnliche Themen
-
Warenwirtschafts-System vs. ERP-System
Von hikeda_ya im Forum Coders TalkAntworten: 2Letzter Beitrag: 15.09.10, 11:03 -
system()
Von Anfänger007 im Forum C/C++Antworten: 0Letzter Beitrag: 24.10.07, 12:21 -
2.1-System
Von tittli im Forum Audiotechnik, Recording & Audio-SoftwareAntworten: 3Letzter Beitrag: 27.09.07, 19:01 -
System::Byte => System::String
Von dertobian im Forum C/C++Antworten: 6Letzter Beitrag: 25.08.07, 18:57 -
Was für ein System
Von MediaPlanet im Forum PHPAntworten: 3Letzter Beitrag: 25.08.03, 00:03






Zitieren

Login





