本文主要说的是关于在展示层一些常用的方案和实现,目录如下:
手工实现分页
手工实现分页
- 用eXtremeTable标签实现自动分页
- 用oscache缓存jsp,提高性能
本分页实现概览:Struts + hibernate
PageBean负责两部分内容,一是要在页面显示的业务信息,是一个ArrayList;另一个是逻辑控制信息,诸如是否有下一页,上一页等等.
PageBean代码如下:
public
class
PageBean {
int currentPage = 1 ; // 当前页:Action控制
int totalPages = 0 ; // 总页数 :自己运算
int pageRecorders = 5 ; // 每页记录数,默认为5,可以在初始化的时候修改 // 总数据数
int pageStartRow = 0 ; // 每页的起始数
int pageEndRow = 0 ; // 每页显示数据的终止数
boolean hasNextPage = false ; // 是否有下一页:自己运算
boolean hasPreviousPage = false ; // 是否有前一页 :自己运算
List objList = new ArrayList(); // 存放欲展示的对象列表
int totalRows; // 总记录数,由底层service提供
// 是否有上一页
public boolean isHasPreviousPage() {
return (currentPage > 1 ? true : false );
}
// 共有多少页,service只提供有多少条记录,多少页数由PageBean自己运算
public int getTotalPages() {
return (totalRows / pageRecorders == 0 ? totalRows / pageRecorders:totalRows / pageRecorders + 1 );
}
public int getCurrentPage() {
return currentPage;
}
public int getPageEndRow() {
return pageEndRow;
}
// 是否有下一页
public boolean isHasNextPage() {
return (currentPage < this .getTotalPages() ? true : false );
}
public int getTotalRows() {
return totalRows;
}
public int getPageStartRow() {
return pageStartRow;
}
public int getPageRecorders() {
return pageRecorders;
}
public void setObjList(List objList) {
this .objList = objList;
}
public void setHasPreviousPage( boolean hasPreviousPage) {
this .hasPreviousPage = hasPreviousPage;
}
public void setTotalPages( int totalPages) {
this .totalPages = totalPages;
}
public void setCurrentPage( int currentPage) {
this .currentPage = currentPage;
}
public void setPageEndRow( int pageEndRow) {
this .pageEndRow = pageEndRow;
}
public void setHasNextPage( boolean hasNextPage) {
this .hasNextPage = hasNextPage;
}
public void setTotalRows( int totalRows) {
this .totalRows = totalRows;
}
public void setPageStartRow( int pageStartRow) {
this .pageStartRow = pageStartRow;
}
public void setPageRecorders( int pageRecorders) {
this .pageRecorders = pageRecorders;
}
public List getObjList() {
return objList;
}
public PageBean() {}
public void description() {
String description = " 共有数据数: " + this .getTotalRows() +
" 共有页数: " + this .getTotalPages() +
" 当前页数为: " + this .getCurrentPage() +
" 是否有前一页: " + this .isHasPreviousPage() +
" 是否有下一页: " + this .isHasNextPage() +
" 开始行数: " + this .getPageStartRow() +
" 终止行数: " + this .getPageEndRow();
System.out.println(description);
}
}
int currentPage = 1 ; // 当前页:Action控制
int totalPages = 0 ; // 总页数 :自己运算
int pageRecorders = 5 ; // 每页记录数,默认为5,可以在初始化的时候修改 // 总数据数
int pageStartRow = 0 ; // 每页的起始数
int pageEndRow = 0 ; // 每页显示数据的终止数
boolean hasNextPage = false ; // 是否有下一页:自己运算
boolean hasPreviousPage = false ; // 是否有前一页 :自己运算
List objList = new ArrayList(); // 存放欲展示的对象列表
int totalRows; // 总记录数,由底层service提供
// 是否有上一页
public boolean isHasPreviousPage() {
return (currentPage > 1 ? true : false );
}
// 共有多少页,service只提供有多少条记录,多少页数由PageBean自己运算
public int getTotalPages() {
return (totalRows / pageRecorders == 0 ? totalRows / pageRecorders:totalRows / pageRecorders + 1 );
}
public int getCurrentPage() {
return currentPage;
}
public int getPageEndRow() {
return pageEndRow;
}
// 是否有下一页
public boolean isHasNextPage() {
return (currentPage < this .getTotalPages() ? true : false );
}
public int getTotalRows() {
return totalRows;
}
public int getPageStartRow() {
return pageStartRow;
}
public int getPageRecorders() {
return pageRecorders;
}
public void setObjList(List objList) {
this .objList = objList;
}
public void setHasPreviousPage( boolean hasPreviousPage) {
this .hasPreviousPage = hasPreviousPage;
}
public void setTotalPages( int totalPages) {
this .totalPages = totalPages;
}
public void setCurrentPage( int currentPage) {
this .currentPage = currentPage;
}
public void setPageEndRow( int pageEndRow) {
this .pageEndRow = pageEndRow;
}
public void setHasNextPage( boolean hasNextPage) {
this .hasNextPage = hasNextPage;
}
public void setTotalRows( int totalRows) {
this .totalRows = totalRows;
}
public void setPageStartRow( int pageStartRow) {
this .pageStartRow = pageStartRow;
}
public void setPageRecorders( int pageRecorders) {
this .pageRecorders = pageRecorders;
}
public List getObjList() {
return objList;
}
public PageBean() {}
public void description() {
String description = " 共有数据数: " + this .getTotalRows() +
" 共有页数: " + this .getTotalPages() +
" 当前页数为: " + this .getCurrentPage() +
" 是否有前一页: " + this .isHasPreviousPage() +
" 是否有下一页: " + this .isHasNextPage() +
" 开始行数: " + this .getPageStartRow() +
" 终止行数: " + this .getPageEndRow();
System.out.println(description);
}
}
注意,我没有在PageBean里放具体的业务逻辑,诸如getBooks()等,目的很简单,具有通用性,业务逻辑由另一个业务类实现BookService,BookService获得的业务数据都放在了PageBean的ArrayList里.
BookService代码如下:
public
class
BookService {
private static Logger log = Logger.getLogger(BookService. class .getName());
public BookService() {
}
/**
* 获得book列表
* @param pageBean PageBean:返回的对象存在pageBean里
*/
public static void getBooks(PageBean pageBean) {
String infoSql = " from Book " ; // 获得业务信息
String countSql = " select count(*) from Book " ; // 获得控制信息
Session session = null ;
try {
session = DBUtil.currentSession();
Query query = session.createQuery(infoSql);
query.setFirstResult((pageBean.getCurrentPage() - 1 ) * pageBean.getPageRecorders()); // 起始页
query.setMaxResults(pageBean.getPageRecorders()); // 每页记录数
pageBean.getObjList().clear();
for (Iterator it = query.iterate(); it.hasNext(); ) {
Book po = (Book)it.next();
BookVo vo = new BookVo();
BeanUtils.copyProperties(vo,po);
pageBean.getObjList().add(vo);
}
session = DBUtil.currentSession();
query = session.createQuery(countSql);
int totalRecords = ((Integer)query.list().get( 0 )).intValue();
pageBean.setTotalRows(totalRecords);
}
catch (Exception e) {
e.printStackTrace();
System.out.println( " 数据库异常 " + e.toString());
}
finally {
try {
if ( null != session) {
session.close();
}
}
catch (HibernateException ex) {
ex.printStackTrace();
}
}
}
}
private static Logger log = Logger.getLogger(BookService. class .getName());
public BookService() {
}
/**
* 获得book列表
* @param pageBean PageBean:返回的对象存在pageBean里
*/
public static void getBooks(PageBean pageBean) {
String infoSql = " from Book " ; // 获得业务信息
String countSql = " select count(*) from Book " ; // 获得控制信息
Session session = null ;
try {
session = DBUtil.currentSession();
Query query = session.createQuery(infoSql);
query.setFirstResult((pageBean.getCurrentPage() - 1 ) * pageBean.getPageRecorders()); // 起始页
query.setMaxResults(pageBean.getPageRecorders()); // 每页记录数
pageBean.getObjList().clear();
for (Iterator it = query.iterate(); it.hasNext(); ) {
Book po = (Book)it.next();
BookVo vo = new BookVo();
BeanUtils.copyProperties(vo,po);
pageBean.getObjList().add(vo);
}
session = DBUtil.currentSession();
query = session.createQuery(countSql);
int totalRecords = ((Integer)query.list().get( 0 )).intValue();
pageBean.setTotalRows(totalRecords);
}
catch (Exception e) {
e.printStackTrace();
System.out.println( " 数据库异常 " + e.toString());
}
finally {
try {
if ( null != session) {
session.close();
}
}
catch (HibernateException ex) {
ex.printStackTrace();
}
}
}
}
在Struts的Action中调用service,返回一个PageBean给展示页面
Action代码如下:
1
public
class
PageListAction
extends
Action {
2
3 public PageListAction() {}
4
5 ArrayList arrayList = new ArrayList();
6
7 public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws Exception {
8 String action;
9 PageBean pageBean = null ;
10 action = request.getParameter( " action " );
11 if (action == null || action.equals( " null " )) { // 第一次读取数据
12 pageBean = new PageBean();
13 } else { // 用户选择上一页或者下一页
14 if (action == " nextPage " || action.equals( " nextPage " )) {
15 pageBean = (PageBean)request.getSession().getAttribute( " pageBean " );
16 pageBean.setCurrentPage(pageBean.getCurrentPage() + 1 );
17 } else if (action == " previousPage " || action.equals( " previousPage " )) {
18 pageBean = (PageBean)request.getSession().getAttribute( " pageBean " );
19 pageBean.setCurrentPage(pageBean.getCurrentPage() - 1 );
20 } else if (action == " targetPage " || action.equals( " targetPage " )){ // 指定页
21 pageBean = (PageBean)request.getSession().getAttribute( " pageBean " );
22 System.out.println( " targetPage= " + request.getParameter( " targetPage " ));
23 // 这里根据需要可以对填写的目标页进行判断,不要大于最大页数[此处省略]
24 pageBean.setCurrentPage(Integer.parseInt(request.getParameter( " targetPage " )));
25 }
26 }
27 if ( null == pageBean) throw new Exception( " 获得PageBean异常 " );
28 BookService service = new BookService();
29 service.getBooks(pageBean);
30 pageBean.description();
31 request.getSession().setAttribute( " pageBean " ,pageBean);
32 request.setAttribute( " result " ,pageBean.getObjList());
33 return (mapping.findForward( " success " ));
34 }
35 }
2
3 public PageListAction() {}
4
5 ArrayList arrayList = new ArrayList();
6
7 public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws Exception {
8 String action;
9 PageBean pageBean = null ;
10 action = request.getParameter( " action " );
11 if (action == null || action.equals( " null " )) { // 第一次读取数据
12 pageBean = new PageBean();
13 } else { // 用户选择上一页或者下一页
14 if (action == " nextPage " || action.equals( " nextPage " )) {
15 pageBean = (PageBean)request.getSession().getAttribute( " pageBean " );
16 pageBean.setCurrentPage(pageBean.getCurrentPage() + 1 );
17 } else if (action == " previousPage " || action.equals( " previousPage " )) {
18 pageBean = (PageBean)request.getSession().getAttribute( " pageBean " );
19 pageBean.setCurrentPage(pageBean.getCurrentPage() - 1 );
20 } else if (action == " targetPage " || action.equals( " targetPage " )){ // 指定页
21 pageBean = (PageBean)request.getSession().getAttribute( " pageBean " );
22 System.out.println( " targetPage= " + request.getParameter( " targetPage " ));
23 // 这里根据需要可以对填写的目标页进行判断,不要大于最大页数[此处省略]
24 pageBean.setCurrentPage(Integer.parseInt(request.getParameter( " targetPage " )));
25 }
26 }
27 if ( null == pageBean) throw new Exception( " 获得PageBean异常 " );
28 BookService service = new BookService();
29 service.getBooks(pageBean);
30 pageBean.description();
31 request.getSession().setAttribute( " pageBean " ,pageBean);
32 request.setAttribute( " result " ,pageBean.getObjList());
33 return (mapping.findForward( " success " ));
34 }
35 }
在本Action中判断了可能出现的三种情况:
- 用户选择了"上一页"
- 用户选择了"下一页"
- 用户手工输入了指定的某一页
好了,到了我们呼之欲出的展示页面了 :)
show.jsp代码如下
<%
@ taglib uri
=
"
/WEB-INF/struts-logic.tld
"
prefix
=
"
logic
"
%>
<% @ taglib uri = " /WEB-INF/struts-bean.tld " prefix = " bean " %>
<% @ taglib uri = " /WEB-INF/struts-html.tld " prefix = " html " %>
<% @ page contentType = " text/html; charset=gb2312 " language = " java " %>
< html:html locale ="true" >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=gb2312" >
< script language ="javaScript" >
function go(){
try {
var targetValue = document.getElementById( " targetPage " ).value;
parseInt(targetValue);
alert(targetValue);
} catch (e){
alert( " 请正确填写目标页 " );
return ;
}
if (targetValue == null || targetValue == ''){
alert( " 请填写目标页 " );
return ;
}
window.location = " /fuck/pageList.do?action=targetPage&targetPage= " + targetValue;
}
</ script >
</ head >
< body >
< logic:present name ="pageBean" >
共有数据总数 < bean:write name ="pageBean" property ="totalRows" /> ;
共分 < bean:write name ="pageBean" property ="totalPages" /> 页,
当前是第 < bean:write name ="pageBean" property ="currentPage" /> 页
</ logic:present >
< table border ="1" >
< tr >< th > 书名 </ th >< th > 作者 </ th >< th > 价格 </ th ></ tr >
< logic:present name ="result" >
< logic:iterate id ="book" name ="result" >
< logic:present name ="book" >
< tr >
< td >< bean:write name ="book" property ="name" /></ td >
< td > < bean:write name ="book" property ="author" /></ td >
< td >< bean:write name ="book" property ="price" /></ td >
/ tr >
</ logic:present >
</ logic:iterate >
</ logic:present >
</ table >
< logic:present name ="pageBean" >
< logic:equal name ="pageBean" property ="hasNextPage" value ="true" >
< html:link page ="/pageList.do?action=nextPage" > nextPage </ html:link >
</ logic:equal >
< logic:equal name ="pageBean" property ="hasPreviousPage" value ="true" >
< html:link page ="/pageList.do?action=previousPage" > PreviousPage </ html:link >
</ logic:equal >
< input type ="text" name ="targetPage" id ="targetPage" />
< input type ="button" value ="go!" size ="2" onclick ="go();" />
</ logic:present >
</ body >
</ html:html >
<% @ taglib uri = " /WEB-INF/struts-bean.tld " prefix = " bean " %>
<% @ taglib uri = " /WEB-INF/struts-html.tld " prefix = " html " %>
<% @ page contentType = " text/html; charset=gb2312 " language = " java " %>
< html:html locale ="true" >
< head >
< meta http-equiv ="Content-Type" content ="text/html; charset=gb2312" >
< script language ="javaScript" >
function go(){
try {
var targetValue = document.getElementById( " targetPage " ).value;
parseInt(targetValue);
alert(targetValue);
} catch (e){
alert( " 请正确填写目标页 " );
return ;
}
if (targetValue == null || targetValue == ''){
alert( " 请填写目标页 " );
return ;
}
window.location = " /fuck/pageList.do?action=targetPage&targetPage= " + targetValue;
}
</ script >
</ head >
< body >
< logic:present name ="pageBean" >
共有数据总数 < bean:write name ="pageBean" property ="totalRows" /> ;
共分 < bean:write name ="pageBean" property ="totalPages" /> 页,
当前是第 < bean:write name ="pageBean" property ="currentPage" /> 页
</ logic:present >
< table border ="1" >
< tr >< th > 书名 </ th >< th > 作者 </ th >< th > 价格 </ th ></ tr >
< logic:present name ="result" >
< logic:iterate id ="book" name ="result" >
< logic:present name ="book" >
< tr >
< td >< bean:write name ="book" property ="name" /></ td >
< td > < bean:write name ="book" property ="author" /></ td >
< td >< bean:write name ="book" property ="price" /></ td >
/ tr >
</ logic:present >
</ logic:iterate >
</ logic:present >
</ table >
< logic:present name ="pageBean" >
< logic:equal name ="pageBean" property ="hasNextPage" value ="true" >
< html:link page ="/pageList.do?action=nextPage" > nextPage </ html:link >
</ logic:equal >
< logic:equal name ="pageBean" property ="hasPreviousPage" value ="true" >
< html:link page ="/pageList.do?action=previousPage" > PreviousPage </ html:link >
</ logic:equal >
< input type ="text" name ="targetPage" id ="targetPage" />
< input type ="button" value ="go!" size ="2" onclick ="go();" />
</ logic:present >
</ body >
</ html:html >
是否有上一页或者下一页,全部根据PageBean里的逻辑值动态判断.
这个页面没什么可说的,你可以根据自己的情况调整就OK了
第二. 用eXtremeTable标签实现自动分页
上面的方案大家已经看出来了,实际上是每一次用户点击一个页面都会查询数据库,这可以算是既是优点也是缺点,优点是数据库不用一次查询出所有的数据,在高数据量的情况下尤其如此,缺点就是和数据库的交互次数有点多了,不过这个完全看你的业务策略了,如果用户大多数情况下就是看没几条的记录,你又何必把全部数据给他取出来呢? 当然,在这里我们就说说一次取出全部数据,然后让标签帮助我们自动分页,终于可以偷懒了,你所要做的仅仅是取出所需要的业务数据而已,其他的就交给eXtremeTable标签来完成就OK了.
eXtremeTable标签的下载,安装和文档请参看官方网站
public
static
List getBooks() {
log.debug( " execute getBooks method! " );
String infoSql = " from Book " ; // 获得业务信息
Session session = null ;
List rtnList = new ArrayList();
try {
session = DBUtil.currentSession();
Query query = session.createQuery(infoSql);
for (Iterator it = query.iterate(); it.hasNext(); ) {
Book po = (Book) it.next();
BookVo vo = new BookVo();
BeanUtils.copyProperties(vo,po);
log.debug( " vo = [ " + vo + " ] " );
rtnList.add(vo);
}
}
catch (Exception e) {
e.printStackTrace();
System.out.println( " 数据库异常 " + e.toString());
}
finally {
try {
if ( null != session) {
session.close();
}
}
catch (HibernateException ex) {
ex.printStackTrace();
}
}
return rtnList;
}
log.debug( " execute getBooks method! " );
String infoSql = " from Book " ; // 获得业务信息
Session session = null ;
List rtnList = new ArrayList();
try {
session = DBUtil.currentSession();
Query query = session.createQuery(infoSql);
for (Iterator it = query.iterate(); it.hasNext(); ) {
Book po = (Book) it.next();
BookVo vo = new BookVo();
BeanUtils.copyProperties(vo,po);
log.debug( " vo = [ " + vo + " ] " );
rtnList.add(vo);
}
}
catch (Exception e) {
e.printStackTrace();
System.out.println( " 数据库异常 " + e.toString());
}
finally {
try {
if ( null != session) {
session.close();
}
}
catch (HibernateException ex) {
ex.printStackTrace();
}
}
return rtnList;
}
- Action
public
class
PageListWithTagAction
extends
Action {
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
BookService service = new BookService();
//我这里把数据放到session中,相当于做了缓存,根据你的业务策略也可以不用这么做
// 如果session中没有,则从数据库中查询
if ( null == httpServletRequest.getSession().getAttribute( " result " )){
List result = service.getBooks();
httpServletRequest.getSession().setAttribute( " result " ,result);
}
return (actionMapping.findForward( " success " ));
}
}
public ActionForward execute(ActionMapping actionMapping, ActionForm actionForm, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
BookService service = new BookService();
//我这里把数据放到session中,相当于做了缓存,根据你的业务策略也可以不用这么做
// 如果session中没有,则从数据库中查询
if ( null == httpServletRequest.getSession().getAttribute( " result " )){
List result = service.getBooks();
httpServletRequest.getSession().setAttribute( " result " ,result);
}
return (actionMapping.findForward( " success " ));
}
}
- jsp[show.jsp代码如下,留心里面的标签使用方法]
<
body
bgcolor
="#ffffff"
>
< ec:table tableId ="fuck"
items ="result"
action ="${pageContext.request.contextPath}/pageListWithTag.do"
imagePath ="${pageContext.request.contextPath}/jsp/images/table/*.gif"
title ="Books"
width ="60%"
rowsDisplayed ="5"
locale ="zh_CN"
cellpadding ="1"
cellspacing ="1"
border ="1"
method ="post"
showPagination ="false"
filterable ="false"
>
< ec:exportXls fileName ="Book.xls" tooltip ="导出Excel" >
</ ec:exportXls >
< ec:exportPdf fileName ="Book.pdf" tooltip ="导出pdf" headerColor ="blue" headerBackgroundColor ="red" headerTitle ="Book" > </ ec:exportPdf >
< ec:row highlightRow ="true" >
< ec:column property ="name" title ="书名" >
< a href ="${pageContext.request.contextPath}/bookDetail.do?bookID=${fuck.id}&bookName=${fuck.name}" > ${fuck.name}
</ a >
</ ec:column >
< ec:column property ="author" title ="作者" >
<!-- here can't use 'result.author' -->
${fuck.author}
</ ec:column >
< ec:column property ="price" title ="价格" cell ="currency" format ="$###,###,##0.00" />
< ec:column property ="date" title ="日期" cell ="date" format ="yyyy年MM月dd日" >
</ ec:column >
</ ec:row >
</ ec:table >
</ body >
< ec:table tableId ="fuck"
items ="result"
action ="${pageContext.request.contextPath}/pageListWithTag.do"
imagePath ="${pageContext.request.contextPath}/jsp/images/table/*.gif"
title ="Books"
width ="60%"
rowsDisplayed ="5"
locale ="zh_CN"
cellpadding ="1"
cellspacing ="1"
border ="1"
method ="post"
showPagination ="false"
filterable ="false"
>
< ec:exportXls fileName ="Book.xls" tooltip ="导出Excel" >
</ ec:exportXls >
< ec:exportPdf fileName ="Book.pdf" tooltip ="导出pdf" headerColor ="blue" headerBackgroundColor ="red" headerTitle ="Book" > </ ec:exportPdf >
< ec:row highlightRow ="true" >
< ec:column property ="name" title ="书名" >
< a href ="${pageContext.request.contextPath}/bookDetail.do?bookID=${fuck.id}&bookName=${fuck.name}" > ${fuck.name}
</ a >
</ ec:column >
< ec:column property ="author" title ="作者" >
<!-- here can't use 'result.author' -->
${fuck.author}
</ ec:column >
< ec:column property ="price" title ="价格" cell ="currency" format ="$###,###,##0.00" />
< ec:column property ="date" title ="日期" cell ="date" format ="yyyy年MM月dd日" >
</ ec:column >
</ ec:row >
</ ec:table >
</ body >
感觉如何?你不用再画你的页面了,不用再画table了,这点我特别喜欢,因为我自己画的东西都比较难看,毕竟我的美工功夫不够 :( "自从有了eXtremeTable吃嘛嘛香" :)
具体的标签使用方法请参考官方文档的Manual,说明还是比较详细的.
第三.用oscache缓存你的页面
为了提高页面的速度我们想了很多办法,比如 预编译的办法,以及把你常用的数据放到内存里,是的,除了用内存我们还能想到用什么办法呢,恩,我想以后cpu的缓存也特别大的话我们的下一个方案肯定就是把数据全部放到cpu里得了,哈哈,展望一下 :)
言归正传, oscache的广告我就不做了,差不多地球人都知道了,这里仅仅提供了一个想法,我想这确实是一个不错的方案,它提供了2个途径使用,一是通过tag的方式,可能也是用的最多的方式,另一个便是调用API,当然就可以在任何想调用的地方使用了.另外还有一个特别不错的功能就是有策略的刷新数据.这是一个useful的方式,比如你做了增删改操作那么数据库的数据已经发生变化了,你可以通知缓存来更新数据,方式是通过key或者group.
下面是几个摘自FAQ里的几个常用Example
- Example1
<
cache:cache
time
="600"
>
<% = myBean.getTitle() %>
</ cache:cache >
<% = myBean.getTitle() %>
</ cache:cache >
- Example2
<
cache:cache
key
="foobar"
scope
="session"
>
<% = myBean.getTitle() %>
</ cache:cache >
<% = myBean.getTitle() %>
</ cache:cache >
- Example3
<
cache:cache
>
<% try { %>
<% = myBean.getTitle() %> >
<% } catch (Exception e) { %>
<% application.log( " Exception occurred in myBean.getTitle(): " + e); %>
< cache:usecached />
<% } %>
</ cache:cache >
<% try { %>
<% = myBean.getTitle() %> >
<% } catch (Exception e) { %>
<% application.log( " Exception occurred in myBean.getTitle(): " + e); %>
< cache:usecached />
<% } %>
</ cache:cache >
上面的Example3可以实现在数据库当机的情况下从缓存里读取数据展示,显得更加友好
不知你注意到了没有,在oscache官方展示的例子里的jsp都有一个我称之为毛病的东西,或者说是困惑,那就是都用了
<%
=
.
%>
这种方式,感觉有点别扭,毕竟这种使用方式对于别人我不知道,反正对于我来说用的比较少,在以前的使用中我记得只有使用xml数据岛的时候用过这种方式,其他情况下很少用=的方式来打印出一些动态的数据,更常见的可能是如下这样的情况:
![](https://i-blog.csdnimg.cn/blog_migrate/9b8a8a44dd1c74ae49c20a7cd451974e.gif)
<
cache:cache
key
="dispInfo"
groups
="disInfo"
time
="1200"
>
<%
BookService service = new BookService();
List list = service.getBooks();
request.setAttribute( " list " ,list);
%>
</ cache:cache >
< c:forEach items ="${list}" var ="item" >
< c:out value ="${item.id}" /> == < c:out value ="${item.name}" />< br />
</ c:forEach >
<%
BookService service = new BookService();
List list = service.getBooks();
request.setAttribute( " list " ,list);
%>
</ cache:cache >
< c:forEach items ="${list}" var ="item" >
< c:out value ="${item.id}" /> == < c:out value ="${item.name}" />< br />
</ c:forEach >
不幸的是,这个一厢情愿的做法并不被oscache支持,除了第一次能够显示数据,下一次就显示不了了.也许oscache所谓的缓存jsp代码就是指缓存诸如<%=%>的方式才是jsp代码,其他的java型的就不被支持了?可能是理解不够,继续研究吧,希望有知道的不吝赐教 :)
恩,就是这么多,关于页面的缓存和分页以及标签.欢迎有这方面的更好的想法来交流.
本人不才,可能有很多地方理解不够深入,见笑了 :)