<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    幸せのちから

    平凡的世界
    看似平常實崎嶇
    成如容易卻艱辛

    Limit指南

    Limit指南


    1. 引言

    在你需要處理大量數(shù)據(jù)時你應(yīng)該考慮使用eXtremeTable的Limit特性。Limit這個名字來自MySQL的limit 命令,Limit接口的目的就是如何對表的結(jié)果集進行l(wèi)imit處理。Limit實現(xiàn)知道當(dāng)排序、過濾、分頁、導(dǎo)出時,用戶如何與表互相作用。有了這些信息你 將能夠使用可能是最有效的方式顯示正確的過濾、排序后的請求頁面。

    為了示范Limit特性,我將要做的工作將分解為JSP、Controller、Service和DAO。這示范了一種使用分層的方式來處理 Limit。你可以根據(jù)自己的需要來增加或減少層。本示例也使用了Spring框架來重新得到使用Spring的JDBC取得的數(shù)據(jù),因此你的代碼看起來可能有點不同。eXtremeTable的一個特點就是不依賴任何框架和容器。

    1.1. JSP

    為了使用Limit特性,eXtremeTable需要使用limit特定的RetrieveRowsCallback、 FilterRowsCallback和SortRowsCallback接口。eXtremeComponents提供了每個接口的一個實現(xiàn),可以簡單地通過設(shè)置每個屬性值為limit來簡單來使用。

    <ec:table 
    items="presidents"
    retrieveRowsCallback="limit"
    filterRowsCallback="limit"
    sortRowsCallback="limit"
    view="limit"
    >
    ...

    另外視圖屬性參照一個名為limit的定制視圖。這是一個簡單修改默認eXtremeTable視圖,不包含最后頁工具條的實現(xiàn)。這僅僅關(guān)系到你是否能取得確切需要的行。 一些數(shù)據(jù)庫例如Oracle和MySQL都提供了一種得到確定行的特性,但是,其他的數(shù)據(jù)庫例如:Sybase沒有提供特性。在我的示例中我考慮最壞的情況你的數(shù)據(jù)庫不支持這種特性。

    即使你的數(shù)據(jù)庫不提供取得特定行的特性,當(dāng)你考慮用戶如何和表協(xié)同工作時,Limit仍然非常有意義。用戶通常會對一些數(shù)據(jù)進行排序、過濾和分頁。 這個例子中15條數(shù)據(jù)構(gòu)成一頁,第一頁需要15條數(shù)據(jù),第二頁需要30條數(shù)據(jù),第三頁需要45條數(shù)據(jù),以此類推。在經(jīng)過一段時間分頁后,他們常常使用過濾來提煉數(shù)據(jù)。 即使他們不這樣做,他們也必須在此之前對大量的數(shù)據(jù)進行分頁,這將影響效率。當(dāng)然如果允許用戶點擊最后頁,那么所有的數(shù)據(jù)都將被取出,這將非常影響效率。

    1.2. Controller

    提示:Spring框架的Controller和Struts框架的Action非常相像。

    controller首先需要創(chuàng)建一個Limit。為了完成這個你需要得到一些關(guān)于Context和LimitFactory的幫助。

    Context context = new HttpServletRequestContext(request);
    LimitFactory limitFactory = new TableLimitFactory(context);
    Limit limit = new TableLimit(limitFactory);

    Context是一個處理取得屬性的接口,LimitFactory使用Context來找出用戶如何和eXtremeTable交互。 然后Limit使用LimitFactory來組裝自己。

    為了初始化Limit,它將包含所有的有用的信息。這些信息包括數(shù)據(jù)將被如何排序和過濾,哪一頁將被顯示和是否允許被導(dǎo)出。

    然而,Limit仍然需要得到行的信息,這樣正確的信息頁面才能被顯示給用戶。行信息包括開始行、結(jié)束行、當(dāng)前顯示行。 controller必須從service得到這些信息,而Service將從dao中得到這些信息。這里我只給出Controller端的代碼。

    int totalRows = presidentsService.getTotalPresidents(limit.getFilterSet(), limit.isExported());
    limit.setRowAttributes(totalRows, defaultRowsDisplayed);

    limit需要得到所有的行來得到行的信息。service需要知道那些被過濾,不管這些數(shù)據(jù)是否要導(dǎo)出。為了設(shè)置行信息,默認的一頁顯示的行數(shù)需要被設(shè)置。 這可以通過對TableTag的rowsDisplayed屬性設(shè)置一個確定的數(shù)值來實現(xiàn)。

    現(xiàn)在我們只需要從services得到Collection數(shù)據(jù)。

    Collection presidents = presidentsService.getPresidents(limit.getFilterSet(), limit.getSort(), limit.getRowEnd());

    因為limit已經(jīng)包含所有信息,這將十分容易。所有需要做的就是傳入過濾器,排序和最后行的信息。 最后要做的是將Collections和totalRow這些信息傳送回JSP以便eXtremeTable知道如何顯示這些信息。

    request.setAttribute("presidents", presidents);
    request.setAttribute("totalRows", new Integer(totalRows));

    1.3. Service

    service需要和dao進行交互來得到總行數(shù)和Collection。

    1.3.1. 取得總行數(shù)

    controller需要到第一條信息就是總行數(shù)。

    public int getTotalPresidents(FilterSet filterSet, boolean isExported) {
    String totalQuery = presidentsDao.getTotalPresidentsQuery();
    String modTotalQuery = filterQuery(filterSet, totalQuery);
    int totalRows = presidentsDao.getTotalPresidents(modTotalQuery);
    if (isExported && totalRows > maxExportRows) {
    totalRows = maxExportRows;
    }
    return totalRows;
    }

    service和dao一起來過濾結(jié)果集,它的工作方式是在Where語句后面增加更多的AND語句來修改查詢字符串。為此,你需要和Limit FilterSet一起工作。

    FilterSet是一個過濾器對象數(shù)組,一個過濾器包括一個bean property和這個過濾器的值。或者,簡單的說就是用戶想要過濾的行和他們輸入的值。這使得它非常容易交互。service只需要迭代所有的 FilterSet并調(diào)用dao來拼接查詢語句。(譯者注:過濾的實現(xiàn)方式是:在Where后面增加And語句來改變查詢語句以達到對數(shù)據(jù)進行過濾的效果)

    private String filterQuery(FilterSet filterSet, String query) {
    if (!filterSet.isFiltered() || filterSet.isCleared()) {
    return query;
    }

    Filter filters[] = filterSet.getFilters();
    for (int i = 0; i < filters.length; i++) {
    Filter filter = filters[i];
    String property = filter.getProperty();
    String value = filter.getValue();
    query = presidentsDao.filterQuery(query, property, value);
    }

    return query;
    }

    query修改包括了filter信息,總行數(shù)。在一些情況下這就足夠,但是當(dāng)用戶導(dǎo)出數(shù)據(jù)時仍然存在一個潛在的問題。為了保持高效 service不允許導(dǎo)出超出一個最大行數(shù)的數(shù)據(jù)。

    1.3.2. 取得Collection

    controller需要到第二條信息就是Collection。

    public Collection getPresidents(FilterSet filterSet, Sort sort, int rowEnd) {
    String patientsQuery = presidentsDao.getPresidentsQuery();
    String modPatientsQuery = filterQuery(filterSet, patientsQuery);
    modPatientsQuery = sortQuery(sort, modPatientsQuery);
    modPatientsQuery = presidentsDao.limitQuery(rowEnd, modPatientsQuery);
    return presidentsDao.getPresidents(modPatientsQuery);
    }

    和前面一樣,service和dao一起來過濾結(jié)果集。

    另外query字符串需要擴展ORDER BY語句以便數(shù)據(jù)按照正確的方式進行排序。Sort包含一個bean property和 sortOrder值(正序還是逆序)。service僅僅需要使用Sort來調(diào)用dao。

    private String sortQuery(Sort sort, String query) {
    if (!sort.isSorted()) {
    String defaultSortOrder = presidentsDao.getDefaultSortOrder();
    if (StringUtils.isNotBlank(defaultSortOrder)) {
    return query + defaultSortOrder;
    }

    return query;
    }

    String property = sort.getProperty();
    String sortOrder = sort.getSortOrder();

    return presidentsDao.sortQuery(query, property, sortOrder);
    }

    query字符串最后需要的修改就是增加數(shù)據(jù)庫特別的指令來limit將要被返回的結(jié)果集。這就是limitQuery() 方法的作用。

    1.4. DAO

    dao為service負責(zé)底層數(shù)據(jù)工作。

    1.4.1. 定義Query字符串

    為了真正理解dao,query字符串需要被展示。

    這就是得到數(shù)據(jù)的presidents query字符串:

    private final static String presidentsQuery = 
    " SELECT " +
    " president_id presidentId, " +
    " first_name firstName, " +
    " last_name lastName, " +
    " nick_name nickName, " +
    " concat(first_name, ' ',last_name) fullName, " +
    " term, " +
    " born, " +
    " died, " +
    " education, " +
    " career, " +
    " political_party politicalParty " +
    " FROM presidents ";

    這是得到總行數(shù)的query字符串:

    private final static String totalPresidentsQuery = 
    " SELECT count(*) FROM presidents ";

    1.4.2. Filter 和 Sort Query 字符串

    兩個最有趣的方法就是過濾和排序。

    filter看起來像這樣:

    public String filterQuery(String query, String property, String value) {
    StringBuffer result = new StringBuffer(query);

    if (query.indexOf("WHERE") == -1) {
    result.append(" WHERE 1 = 1 "); //stub WHERE clause so can just append AND clause
    }

    if (property.equals("fullName")) {
    result.append(" AND concat(first_name, ' ',last_name) like '%" + value + "%'");
    } else if (property.equals("nickName")) {
    result.append(" AND nick_name like '%" + value + "%'");
    } else {
    result.append(" AND " + property + " like '%" + value + "%'");
    }

    return result.toString();
    }

    filterQuery()方法需要增加正確的AND語句到query字符串。

    sort看起來非常類似:

    public String sortQuery(String query, String property, String sortOrder) {
    StringBuffer result = new StringBuffer(query + " ORDER BY ");

    if (property.equals("fullName")) {
    result.append("concat(first_name, ' ',last_name) " + sortOrder);
    } else {
    result.append(property + " " + sortOrder);
    }

    return result.toString();
    }

    sortQuery()方法需要增加正確的ORDER BY語句到query字符串。

    1.4.3. Limit Query String

    現(xiàn)在query字符串修改能夠正確的進行filter和sort,它還需要修改以便只取頁面顯示相關(guān)的數(shù)據(jù)。MySQL為s the limit命令。

    public String limitQuery(int rowEnd, String query) {
    return query + " limit " + rowEnd;
    }

    1.4.4. 取回總行數(shù)和Collection.

    service需要的唯一東西就是:總行數(shù)和Collection。

    public Collection getPresidents(final String query) {
    return jdbcTemplate.query(query, new ResultReader() {
    List results = new ArrayList();
    public List getResults() {
    return results;
    }

    public void processRow(ResultSet rs)
    throws SQLException {
    President president = new President();
    president.setPresidentId(new Integer(rs.getInt("presidentId")));
    president.setFirstName(rs.getString("firstName"));
    president.setLastName(rs.getString("lastName"));
    president.setNickName(rs.getString("nickName"));
    president.setFullName(rs.getString("fullName"));
    president.setTerm(rs.getString("term"));
    president.setBorn(rs.getDate("born"));
    president.setDied(rs.getDate("died"));
    president.setEducation(rs.getString("education"));
    president.setCareer(rs.getString("career"));
    president.setPoliticalParty(rs.getString("politicalParty"));
    results.add(president);
    }
    });
    }

    public int getTotalPresidents(final String query) {
    return jdbcTemplate.queryForInt(query);
    }

    ResultReader是一個幫助處理JDBC查詢的Spring特殊類,作為一個callback來處理JDBC ResultSet。jdbcTemplate是對JDBC連接的抽象。

    1.4.5. 默認的Sort順序

    最后,這是service需要的默認sort順序:

    public String getDefaultSortOrder() {
    return " ORDER BY concat(first_name, ' ', last_name) ";
    }

    posted on 2006-02-23 10:34 Lucky 閱讀(2156) 評論(8)  編輯  收藏 所屬分類: extremeComponents

    評論

    # re: Limit指南 2006-05-16 13:48 悠哥

    版本:eXtremeComponents-1.0.1-RC2
    環(huán)境:JSF

    文件:departments.jsp
    <f:view>
    <f:loadBundle var="text" basename="#{departmentList.bundleName}"/>
    <h:form id="editDepartment">
    <ec:table
    items="departmentList.departments"
    action="${pageContext.request.contextPath}/hr/departments.html"
    imagePath="${pageContext.request.contextPath}/images/table/*.gif"
    title="${text['userList.title']}"
    rowsDisplayed="10"
    form="editDepartment" var="department"
    retrieveRowsCallback="limit"
    filterRowsCallback="limit"
    sortRowsCallback="limit"
    view="limit"
    autoIncludeParameters="false">
    <ec:row highlightRow="true">
    <ec:column title="${text['department.name']}" property="name"/>
    </ec:row>
    </ec:table>
    </h:form>
    </f:view>

    文件:DepartmentList.java
    public List getDepartments() {
    Context context = new HttpServletRequestContext(getRequest());
    LimitFactory limitFactory = new TableLimitFactory(context);
    Limit limit = new TableLimit(limitFactory);

    //int pageSize = limit.getCurrentRowsDisplayed();
    //可能是一個bug,生成 limit 的時候,并沒有給 currentRowsDisplayed 賦值
    int pageSize = limitFactory.getCurrentRowsDisplayed(0, 10);

    FilterSet filter = limit.getFilterSet();

    Page page = new PageHibernate(limit.getPage(), pageSize);
    page.setFilters(FilterUtil.convert(filter));

    page = departmentManager.getDepartments(page);

    List list = page.getThisPageElements();

    limit.setRowAttributes(page.getTotalNumberOfElements(), page.getPageSize());

    getRequest().setAttribute("totalRows", new Integer(page.getTotalNumberOfElements()));
    return list;
    }

    結(jié)果:
    1.從limit中取不到pagesize,可能是一個bug,跟蹤TableLimit原碼,初始化的時候,并沒有給 currentRowsDisplayed 賦值
    2.沒有顯示“最后一頁”,這個按鈕  回復(fù)  更多評論   

    # re: Limit指南 2006-05-16 14:03 悠哥

    3.不能生成 excel 文件  回復(fù)  更多評論   

    # re: Limit指南 2006-05-16 14:14 xplucky

    我沒用過JSF,你可以sina的免費郵箱中找到extremesite實例,用戶名、密碼: extremetable。  回復(fù)  更多評論   

    # re: Limit指南 2006-09-20 20:56 Jkallen

    呵呵 我正在看英文的tutoails而頭疼呢!

    支持!以后常來  回復(fù)  更多評論   

    # re: Limit指南 2006-09-20 21:03 Jkallen

    對了,這個ResultReader是spring哪個版本的啊?

    現(xiàn)在我們公司的都是:
    ecTableRowMapper implements RowMapper
    這樣來將resultset中的結(jié)果放到map中(當(dāng)然也可以放到一個DTO中)  回復(fù)  更多評論   

    # re: Limit指南 2006-10-16 18:23 孫建彬

    在創(chuàng)建limit之前:
    你是在哪里定義defaultRowsDisplayed的,然后怎么樣取得的?
    發(fā)個e-mail:volcano_hosan@sina.com,多謝!  回復(fù)  更多評論   

    # re: Limit指南 2006-10-17 16:23 sLAmbBkiNg

    如何解決使用LIMIT后“最后一頁”按鈕不顯示問題?
    M5版本據(jù)說解決了導(dǎo)出EXCEL和PDF中文文件名問題,M5版本在哪里下載?
    BLOG上的連接不能下  回復(fù)  更多評論   

    # re: Limit指南 2007-07-20 10:25 assd

    去掉頁面中的 view="limit"  回復(fù)  更多評論   

    <2006年2月>
    2930311234
    567891011
    12131415161718
    19202122232425
    2627281234
    567891011

    導(dǎo)航

    隨筆分類(125)

    文章分類(5)

    日本語

    搜索

    積分與排名

    最新隨筆

    最新評論

    主站蜘蛛池模板: 亚洲国产91在线| 亚洲最大在线观看| 日韩大片免费观看视频播放| 免费无码成人AV片在线在线播放| 亚洲六月丁香六月婷婷色伊人| 免费福利视频导航| 亚洲乱码卡三乱码新区| 国产福利在线免费| 亚洲日本国产综合高清| 黄页网站在线看免费| 色婷五月综激情亚洲综合| 免费特级黄毛片在线成人观看| 国产亚洲欧美日韩亚洲中文色| 亚洲精品网站在线观看不卡无广告| 日本一区二区三区在线视频观看免费| 五月婷婷亚洲综合| a在线观看免费视频| 婷婷亚洲综合五月天小说| 真人做人试看60分钟免费视频| 亚洲色欲色欲www| 国产午夜影视大全免费观看| 一个人看的www免费在线视频| 亚洲精品乱码久久久久久按摩 | 国产亚洲精品2021自在线| 四虎国产精品免费视| 免费人成视频在线播放| 久久精品国产亚洲AV果冻传媒| 182tv免费观看在线视频| 亚洲精品无码国产片| 国产亚洲av人片在线观看| 日本免费一区二区三区四区五六区| 亚洲人成免费电影| 国产福利电影一区二区三区,亚洲国模精品一区| 尤物视频在线免费观看| 亚洲码一区二区三区| 国产公开免费人成视频| 免费看又黄又无码的网站| 朝桐光亚洲专区在线中文字幕| 久久被窝电影亚洲爽爽爽| 成年女人毛片免费视频| 久久免费观看视频|