?
JSP用自定义标签实现ASP.net的gridview、datasource组件
?
第一部分:使用说明
???????? 使用过ASP.NET的人都知道,gridview控件功能很强大,使用很方便,提高了开发效率、而且表现逻辑和数据分离,只需提供一个DataTable对象(一个表格的数据对象)。甚至,只要引入datasource控件,可以不用代码也可以实现对数据库的查看、删除、修改等功能。
???????? JSP虽然没有控件,但可以使用自定义标签来实现类似ASP.NET控件的功能。网上也有很多开源的标签库。我利用自定义标签实现了gridview和datasource的主要功能。
???????? 效果:
???????? 上面第一种是使用集合作为数据源,第二种使用datasource作为数据源。第一种需要定义一个List集合,删除功能提供了一个连接需要自己写代码实现。第二种不需要编写一句代码就可以实现显示数据、分页、修改、删除等功能,并且会保存到数据库。
???????? 先看一下JSP页面的标签:
??
?
标签说明:
(1)?????gridview里的属性
enablePaging:是否使用分页功能;pageSize:每页有多少行;datasource:数据源,当使用datasource是指定datasource的id,并且要指定属性key的值(主键,删除和修改时要用到),使用list类型需要使用pageContext.setAttribute保存。Key:主键(不一定是数据库的主键),使用list作为数据源时不用指定。
(2)? column的属性
dataItem:数据库表的属性名或者list类型的列名;readonly:只读,不能对该列进行编辑。
(3)?????? linkcolumn为进入该项详细介绍的连接
urlFormatString:链接的url,可以指定参数{0} ;
urlBindItem:urlFormatString 参数{0}绑定的数据项;textFormatString:超链接文字描述部分,可以指定参数{0};
textBindItem:textFormatString 参数{0}绑定的数据项;
(4)?????? deletecolumn 删除按钮那一列
使用list作为数据源时可以指定urlFormatString和urlBindItem参数。使用datasource时不需要参数。
(5)?????? editcolumn 编辑按钮列,点击后进入编辑状态。只要使用datasource的情况下可以使用。
?
(6)?????? datasource(需要写在gridview的上面)里有4个必填属性:id,connectionString(链接数据库的字符串),tableName(数据库表名,用于删除和更新),selectString(提供给gridview的数据)
还有,table的样式我没搞,自己可以使用css设置,gridview的id为生成table的name,每一列都可以知道width属性。
我的开发环境的是:myeclipse8.5+jdk1.5+mysql5。自定义标签要使用2.0的SimpleTagSupport。
?
第二部分:如何实现的
标签的处理类继承于SimpleTagSupport,在dotag函数处理。代码结构如下图:
?
当遇到gridview标签时,生成包含带有属性的<table>标签,并根据数据源的行数和分页中页面的大小,决定迭代的次数,迭代处理子标签column、deletecolumn等。每次迭代都生成<tr>标签,遇到子标签生成<td>标签,根据当前行数和dataItem输出数据。父标签和子标签的交流通过sendData这个类进行。迭代第n次时,gridview标签把数据源的该行数据保存到sendData的类变量中,在子标签中读取该变量的数据。
分页的实现。我在url中设置了一个分页参数,该参数是要显示的那一页,获取到当前的url并修改这个参数的值,把这个url插入到上一页、下一页等标签的onclick=” window.location.href='..’”之中。另外还要根据当前页数,决定上、下页按钮的可见性。
Linkcolumn 通过urlFormatString="index.jsp?id={0}"设置生成<a>标签的href属性,并把从urlBindItem获取的的值代替参数{0}。TextFormatString也一样。
Datasource标签。Connection类封装了对数据库底层的操作。Datasource这个类获取的数据库的连接字符串、selectString的参数,实例化source类(里面有数据,还有删除、修改等操作),把它保存的senddate的类变量中,以供gridview使用。Source类中读取数据时需要使用ResultSetMetaData获取每一列的信息,在生成update,delete语句是用到,因为属性的动态的,所以对数据库的操作要使用prepareStatement,并且用setObject方法设置参数的值。之后在gridview点解删除时,这个删除所对应的url为当前页面加上一个删除参数,参数值为该行的key,根据这个参数执行source类的delete方法。修改按钮中也是在url中就一个参数,使加载该行数据时加入<input type=”text”>标签,并在updatecolumn中生成取消和确定的按钮。取消按钮对应的url自是减去修改按钮新增的那个参数。确定按钮对应的url在原来的基础上加上标志参数,之后根据这个参数调养source的update方法。
?
遇到的问题和解决:
?? 1.点击下一页、删除、修改等按钮时,会改变gridview的状态,要执行相应的代码,但自定义标签是无状态的。开始是想写几个servlet,点击按钮时跳到对应的servlet处理,把状态记录在类变量中,但这样需要在web.xml里写servlet的配置。我不想这样,就用url来处理,每个按钮对应不同的参数,参数的值是动态改变的。当解析gridview标签时,根据这些参数做相应的处理。
?? 2.sql语句的生成,Update、delete语句是动态生成的。解决:使用ResultSetMetaData获取每一列的信息,对数据库的操作要使用prepareStatement,根据gridview的column包含的列生成sql语句,并且用setObject方法设置参数的值。
?