Click here to Skip to main content
15,885,309 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
Hello all,
I am very new to java, so please ignore if you think this question is stupid. A task has been assigned to me in which I have to extract data from h2 database table with **more than 1 crore rows (SAD) from one table.** And finally show that data into a j table with pagination.
What i exactly want is that when the program starts, it extract lets say 1 lac record from database and when user scroll down to the end of first lac records and again extract another lac data from database and so on …
It will be best if he goes scroll up, the program doesn’t extract rows which are already extracted. I Hope I explained my problem here very well.
Now, After a lot of googling, I found this (https://coderanch.com/t/345383/java/JTable-Paging)very good article which does 90% of what I want, but not with database connection. Can any one tell how to do this ?
Here is the sample code :

What I have tried:

public class PagingTableModel extends AbstractTableModel {
	private static final int MAX_PAGE_SIZE = 1000000;
	private static final int LATENCY_MILLIS = 1500;
	private int dataOffset = 0;
	private ArrayList<Integer> data = new ArrayList<Integer>();
	private SortedSet<Segment> pending = new TreeSet<Segment>();
	public int getColumnCount() {
		return 2;
	}
	public String getColumnName(int col) {
		if (col == 0)
			return "ANUMBER";
		if (col == 1)
			return "BNUMBER";
		return "DATETIME";
	}
	public int getRowCount() {
		return 10000000; // one million
	}
	public Object getValueAt(int row, int col) {
		ArrayList<Integer> page = data;
		int pageIndex = row - dataOffset;
		//JOptionPane.showMessageDialog(null, dataOffset);
		if (pageIndex < 0 || pageIndex >= page.size()) {
			System.out.println("object at " + row + " isn't loaded yet");
			schedule(row);
			return "..";
		}
		Object rowObject = page.get(pageIndex);
		return rowObject;
	}
	private void schedule(int offset) {
		if (isPending(offset)) {
			return;
		}
		int startOffset = Math.max(0, offset - MAX_PAGE_SIZE / 2);
		int length = offset + MAX_PAGE_SIZE / 2 - startOffset;
		load(startOffset, length);
	}
	private boolean isPending(int offset) {
		int sz = pending.size();
		if (sz == 0)
			return false;
		if (sz == 1) {
			Segment seg = pending.first();
			return seg.contains(offset);
		}
		Segment lo = new Segment(offset - MAX_PAGE_SIZE, 0);
		Segment hi = new Segment(offset + 1, 0);
		for (Segment seg : pending.subSet(lo, hi)) {
			if (seg.contains(offset))
				return true;
		}
		return false;
	}
	private void load(final int startOffset, final int length) {
		final Segment seg = new Segment(startOffset, length);
		pending.add(seg);
		Runnable fetch = new Runnable() {
			public void run() {
				try {
					Thread.sleep(LATENCY_MILLIS);
				} catch (InterruptedException ex) {
					System.out.println("error retrieving page at " + startOffset + ": aborting");
					pending.remove(seg);
					return;
				}
				final ArrayList<Integer> page = new ArrayList<Integer>();
				for (int j = 0; j < length; j += 1) {
					page.add(new Integer(j + startOffset));
				}
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						System.out.println("** loaded " + startOffset + " through " + (startOffset + length - 1));
						setData(startOffset, page);
						pending.remove(seg);
					}
				});
			}
		};
		new Thread(fetch).start();
	}
	private void setData(int offset, ArrayList<Integer> newData) {
		// This method must be called from the event dispatch thread.
		int lastRow = offset + newData.size() - 1;
		dataOffset = offset;
		data = newData;
		fireTableRowsUpdated(offset, lastRow);
	}
	public static void main(String[] argv) {
		JTable tab = new JTable(new PagingTableModel());
		JScrollPane sp = new JScrollPane(tab);
		JFrame f = new JFrame("PagingTableModel");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setContentPane(sp);
		f.setBounds(30, 50, 1300, 600);
		f.setVisible(true);
	}
	static final class Segment implements Comparable<Segment> {
		private int base = 0, length = 1;
		public Segment(int base, int length) {
			this.base = base;
			this.length = length;
		}
		public boolean contains(int pos) {
			return (base <= pos && pos < base + length);
		}
		public boolean equals(Object o) {
			return o instanceof Segment && base == ((Segment) o).base && length == ((Segment) o).length;
		}
		public int compareTo(Segment other) {
			int d = base - other.base;
			if (d != 0)
				return d;
			return length - other.length;
		}
	}
}
Posted
Updated 6-Jul-17 23:25pm

1 solution

Open a database and fetch data is expensive, so normally is a bunch of data fetched, stored in the data model and than displayed. I would fetch data set for at least two pages depending on the speed.

A somehow similar example by fetching all data and storing it into the plain model array ("data").
 
Share this answer
 
Comments
Bilal Zafar 7-Jul-17 5:49am    
I can bind my result Set into my jtable but all at once which obviously is not acceptable in my case. I need to know how to do this in chunks

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900