|
...Well,
let's check it step by step. In my JSP (2 Daniel): <ac:ajaxDataScroller
rendered="#{Recherche.data.rowCount gt 0}" id="scroller" for="tblData" fastStep="10" renderCurrentAsText="false" maxPages="9" ajaxSingle="true" /> ... <t:dataTable id="tblData" value="#{Recherche.data}" var="foto" rowId="#{foto.id}"
rows="#{Recherche.rowsPerPage}" newspaperColumns="4" newspaperOrientation="horizontal"> <t:column> <ui:include src="mediaview.xhtml"></ui:include> </t:column> </t:dataTable> I think,
the lines var="foto" rowId="#{foto.id}" are
essential in JSP. I may be wrong, but the dataTable needs to identify
the items
somehow... I've
collected also the 'bean's code' from some levels of class hierarchy: //in bean
itself public final
DataModel getData(){ return _getPagedList().getDataModel(); } //'standard' implementation of
_getPagedList() in base class: //(Since I have many different PagedLists,
the common methods //are extracted to). private IPagedList _pagedList = null; protected
IPagedList _getPagedList()
{ if (null == _pagedList) {//pay attention to this check! _pagedList = new
PagedListFoto(GetMiddlewareConnector()); _pagedList.setRowsPerPage(rowsPerPage);); } return _pagedList; } The private
member _pagedList is also initializes 'lazy' -> just once per
instance. Then in
PagedList. private DataModel
dataModel; public
PagedListFoto(SesEJBConnector ejbConnector){ super(ejbConnector); dataModel = null; } This one we
have discuss early... public
DataModel getDataModel()
{ _log.debug("--------------
GetDataModel() called -------"); if (dataModel ==
null ||
_invalidated) { dataModel = new
LocalDataModel(rowsPerPage); _invalidated = false;
//set 'dirty'
flag } return dataModel; } And then
very deeply in base class: constructor public PagedListBase(SesEJBConnector
ejbConnector){ _log =
LogFactory.getLog(this.getClass()); myConnector =
ejbConnector; internalStorage = new
ArrayList<Integer>();//list of IDs _invalidated = true; } public int getCount(){ return internalStorage.size(); } //
this two
methods are used during fetching of page data protected
List<Integer> getSubList(int
startRow, int
pageSize){ int
toIndex = Math.min(internalStorage.size(),
startRow + pageSize); return internalStorage.subList(startRow,
toIndex); } protected
String
getStrIdCommaList(List<Integer> subList){ StringBuffer sb = new
StringBuffer(); for(Integer
ID : subList) sb.append(sb.length() == 0 ?
ID.toString() : ","+ID.toString()); return
sb.toString(); } Well... not
especially clear, but still better then nothing :) The rest (how the
items are
fetched) was in rar. How
and from where to populate this internal storage should be
trivial. I have no
ideas, why the framework access getDataModel() again on going to
another
application page, but after many hours studying of source code of
original
t:dataScroller it's not really great surprise to me :) It was exactly
the
reason to use ac:ajaxDataScroller instead. 2 Vlad Daniel was
quicker with the answer. I've traced this again in my code... two calls
to
getDataModel() should be the only source of duplicated DB access.
(Regardless
of bean's scope, two components access this property.) 2 Vladimir >DEBUG
=== LocalDataModel.fetchPage startRow: 0 pageSize: 5 ??????? I'm not
sure if it's not a result of some "preserve data model"-tricks (of
t:dataScroller? dataTable?)... Any way, it's not the same class
instance where
the old (startRow/pageSize) values are stored :) I would try to log
instance's
hash or check the scope of bean. > 2. I think,
this property is simply omitted in .tld or facelet taglib. In fact the
scroller
is a composed component. It consists of (at least) panelGrid, some
commandLink-s and facet-s. So it's just not clear, which one should use
this
value :) Anyway I'll be wondering, if this warning affects the fetching. And
generally, about the strategy to handle large recordsets... I don't
think, some
really better solution is possible :) The scroller needs this total
record
count to know, how many pages to generate. (Don't forget: the DataModel
must
also can be able to 'report' this value.) In my implementation I have
an
internal storage... let's say, an ArrayList of IDs (integer or long),
so I'm doing
not separate "select count(*)..." but "select ID from..."
(with all filtering/ordering stuff) already in constructor and fill
this list
just once. After this I have the total count automatically and each
statement
to fetch particular data page is "select ... where ID in(...)". Since
the field is indexed, it's pretty quick... probably, the best possible
choice.
I have extra implemented the dirty flag to force 'hard' reload of this
internal
list, if some changes was made, that can affect the order or total
count of
items (edit/add/delete). The call hierarchy in fetching chain is
trivial:
getInternalList().getSublist(). The first one reloads the IDs if data
are
'dirty' (this happens during first call from constructor), the second
composes
IDs of requested subset (page) into comma separated string. Since I'm
working
with EBJ, I haven't to reload whole dataset each time when just one
'record' is
changed - if the entity was successfully persisted, I have already the
actual
'copy'. (I guess Daniel, you are using event listener in your backing
bean to
edit data directly in PagedList? It's the only way to have actual copy
displayed without to reload this page.) I'm working
with kind of snapshot (search results) with extra buffering. My
internal 'in
memory' page is up to five times larger as my displayed page. Since the
user
can adjust the count of displayed items, I'm adjusting also the size of
internal buffer dynamically to keep roundtrip time reasonably even if
'on next
page' the next internal frame of data must be fetched. I try also to
predicate
'next' portion of fetched data, but it's different long story :) That's
why I'm
not posting all of my code... it's scattered over dozen of classes and
packages
:) This simple strategy (even without predication) works fine for me.
By
resultsets of 20000~30000 records and displayed page of
8-80 items (5~7 joined tables each) the
response time is under 500ms (normally 40~60ms / click)
(JBoss/EJB3/Oracle) If the
dataset must be really 'live' (I mean, if after each click the
page/scroller
must reflect the data in DB EXACTLY), it should be also necessarily to
implement some smart strategy to keep 'current' page over roundtrip
etc. (The
first one thinkable pitfall with t:dataScroller: we are at page n with
m items
per page. Then we navigate to n+1 and back, but the items are not more
the
same-> someone have added m items to the dataset and they are now
displayed
at page n due to sorting order.) However I'm not sure, if one really
needs in
this case some datascroller... rather some scroller with fixed length
of
resultset (?may be, incremented on demand etc.) Regards, paul Vladimir Isakovich schrieb:
|
- Re: Tomahawk+DataScroller+WorkingWithL... Vladimir Isakovich
- Re: Tomahawk+DataScroller+Working... Paul Iov
- Re: Tomahawk+DataScroller+Wor... daniel ccss
- Re: Tomahawk+DataScroller+Wor... daniel ccss
- Re: Tomahawk+DataScroller+Wor... Paul Iov
- Re: Tomahawk+DataScroller+Wor... Paul Iov
- Re: Tomahawk+DataScroller+Wor... daniel ccss
- Re: Tomahawk+DataScroller+Wor... Paul Iov
- Re: Tomahawk+DataScroller+Working... Paul Iov
- Re: Tomahawk+DataScroller+WorkingWithLargeTables vlad10
- Re: Tomahawk+DataScroller+WorkingWithLargeTables Paul Iov
- problem with Fixed header in data table Arvind Pandey
- Re: problem with Fixed header in data table eric . jung
- problem with Fixed header in data table Arvind Pandey
- Re: problem with Fixed header in data ... eric . jung
- RE: problem with Fixed header in ... Arvind Pandey
- Re: problem with Fixed header in data table Vladimir Isakovich
- Re: Tomahawk+DataScroller+WorkingWithLargeTables Paul Iov
- Re: Tomahawk+DataScroller+WorkingWithLargeTables Vladimir Isakovich

