表格排序

【注】WW 问我J2EE怎么做服务器端排序,于是上次帮她写了点介绍,放在这里做个存档。

数据结构:

表格(Table)可以是数据库表,也可以是内存中的一个数据结构。例如:

class UserObject
{
 String columnA;
 int columnB;
 char columnC;
}

 一个 List 用来存放你的 UserObject,此时就构成一个表结构。逻辑结构如图:

Index      columnA    columnB      columnC
-------------------------------------------
1            'abc'    1            'a'
2            'efg'    2            'e'
3            'hij'    3            'h'

服务器端:

服务器端客户端参数:1. 当前页码,2. 每页大小,3. 按那个字段排序?

步骤为:

  1. 按客户端点击的字段排序,如果按上述数据结构,如果按 ColumnA 排序方法为,创建比较两个对象的 columnA 属性的方法
class UserComparator implements java.util.Comparator {
  
  int compare(Object o1, Object o2) {
    UserObject uo1 = (UserObject) o1;
    UserObject uo2 = (UserObject) o2;

    if (哪个前头?)
       return 1;        
    else if               
       return -1;        
    else
       return 0;    
   }
}

         
然后使用 Collections 的方法对 List 进行排序:java.util.Collections.sort(list, new UserComparator());

   2. 排序完毕。然后按常规手段,对 List 进行分页处理。

   3. 提取出 客户端请求的页码上的数据。

   4. 将提取出的数据变成 JSON,写回给客户端。

客户端步骤:

   展现方式为:

<table>
    <!-- 表头 -->
    <tr>
        <th>               
            <a href="#" onclick="sendSortRequest('columnA');">columnA</a>
        </th>
        <th>              
            <a href="#"
               onclick="sendSortRequest('columnB');">columnB</a>    
        </th>    
        <th>           
            <a href="#"
               onclick="sendSortRequest('columnC');">columnC</a>    
        </th>
    </tr>
    <!-- 数据 --> 
    <tr>
        <td>abc</td>
        <td>1</td>
        <td>a</td>
    </tr>
</table>

   1. 当点击表头时,使用AJAX方式向服务器端程序 POST 提交参数:1.当前页码,2. 每页大小,3. 按那个字段排序?
   2. 接收到服务器端返回JSON,更新当前表格(这个是纯JAVASCRIPT + DHTML的工作)

634 次阅读

使用Java读取Mysql数据的编码问题

使用 java 程序对 Mysql 数据库内数据进行操作,如果使用默认字符集时数据库连接串通常为:
 
db.url=jdbc:mysql://192.168.0.137/test?user=root&password=&autoReconnect=true&useUnicode=true
      
去掉设置:&characterEncoding=utf-8
 
此时使用的字符集为:ISO-8859-1。因此,插入数据库中的数据会被 Mysql 驱动转换成默认编码:ISO-8859-1。整个数据库中的数据本身不会有什么问题,使用 Mysql 查看的时候看到的是一些问号。但是如果使用 Java 读取这些数据的时候,如果要正确显示,则需要对其进行正确的编码:
  • 使用系统默认的编码方式:
                插入时:直接给定参数 stringValue ,此时 stringValue 为JVM默认编码
               插入后:数据库中 stringValue 值的编码为 ISO-8859-1
               读取时:使用 stringValue = new String(stringValue.getBytes(“ISO-8859-1”));进行将编码ISO-8859-1 转换成操作系统的默认编码(GBK)。
  • 上述过程完整描述为:
           
    插入时:直接给定参数 stringValue = new String(stringValue.getBytes(), “ISO-8859-1”);
    插入后:数据库中 stringValue 值的编码为 ISO-8859-1
    读取时:使用 stringValue = new String(stringValue.getBytes(“ISO-8859-1”));进行将编码ISO-8859-1 转换成操作系统的默认编码(GBK)。
  • 采用硬编码形式又可以写成:
           插入时:直接给定参数 stringValue = new String(stringValue.getBytes(“GBK”), “ISO-8859-1”);
          插入后:数据库中 stringValue 值的编码为 ISO-8859-1
          读取时:使用 stringValue = new String(stringValue.getBytes(“ISO-8859-1”), “GBK”);进行将编码ISO-8859-1 转换成操作系统的默认编码(GBK)。
414 次阅读

几点感悟

工作时偶有所思,留下点感悟。
 
契约的重要性
 
  软件部件之间的交互方式就是契约。契约包括传递给软件部件的参数,以及软件部件何时何种情况抛出错误。契约和现实生活中零件的规格极其类似,软件契约的无法达成,就和零件规格不一致一样,无法正常协同工作。因此,在契约的情况下,只需要考虑软件部件和其他部件之间的契约(接口),软件部件的内部实现变得不太重要。每个软件部件都有其自身严格定义的自责,系统应当能够定位这些功能和职责,从而当部件发生错误时,只需要修复该部件的错误,即可使得整个系统的错误得到修复。
 
      因此,在设计时需要考虑契约因素。每个部件只要符合契约即可,不应该考虑其他不需要关心的因素。例如,数据库访问类正常工作的条件是数据库正常工作,在数据库访问类无法正常工作的情况下,如果数据库无法正常工作,则应当去尝试修复数据库,而不应当去要求在数据库访问类中处理这种错误。如果数据库无法工作,数据库访问类理当无法工作。这就是契约。
 
      使用契约手段设计软件,需要有良好的错误检测手段,以便当系统发生错误时快速方便定位出具体错误位置。
 
      契约设计的最难点在于对契约的定义。通常,如果部件与部件之间的交互仅仅是简单的几个数据类型传递则相对来说好办一些。如果部件和部件之间交互的对象是一个非常复杂的对象,而该对象内部某些方法是不稳定的,则这种情况下作为参数的对象内部发生异常错误就很难界定这种错误是那个部件导致的。因为对于复杂对象,在使用该对象之前描述该对象所期望的内部状态是困难的。例如:工作流对象内部包含太多内容,就很难一次性描述需要那些东西来避免空指针的情况。此外还有对于软件构造过程中,不同的对象,其契约要求是不一样。例如:方法的契约要求通常是参数是否设置正确,组件的契约要求则通常是其它组件内部设置符合要求。
 
      软件必定会朝简单化、组件化、契约化方向发展。从目前的阶段来看,在软件的各种层面上都有契约的概念。早起Windows平台下开发插件、到 Java 中一系列的开发规范、到面向服务的开发结构 SOA 都是某种契约。
 
先设计后实现
 
      动手做软件之前需要对软件需求进行深入了解,然后进行概要以及详细设计。切忌不作设计就立即动手搭建系统。任何随意的行为都会导致随意的系统,随意的系统往往错漏百出。因此,设计时使用契约原则,进行概要设计,详细设计。
 
测试驱动开发
 
      使用测试来驱动设计是比较困难的。最难的点在于:如何设计所有的测试,测试的细致程度如何?最简单的测试是软件的大目标,即:软件能够正常运行。但对于一个巨大的软件项目,单元测试显然是一个巨大的工作量。如果考虑减少工作量,那么单元测试又很难覆盖所有的测试点。显然,这里需要寻找一个哲学的平衡点,找到那些关键的测试点进行测试,设计较好的测试。
362 次阅读