深入 Table 配置
现在,打开我们的 WEB 服务器,并打开浏览器。访问我们的 user_demo 操作页面:
http://localhost:8080/cwin/cwin?_CWIN_ID=user_demo
_CWIN_ID 参数表示 Window 的 ID 。我们在前面提到过, Cwin 的核心是 Window 。而我们现在传递的参数却是表名。事实上,如果我们传入的参数不是一个已经定义的 Window ,那么 Cwin 会尝试查看这个 ID 是不是一个表名,如果是,则会生成默认的配置,并将这张表做为默认的 Window 来处理。现在,我们打开 table.xml ,学习它的配置。
验证的配置
找到 id 为 user_demo 的 table 元素,它的配置应该如下所是:
<table id="user_demo">
<field name="id" desc="id" validType="int" isKey="true"/>
<field name="login_name" desc="login_name"/>
<field name="email" desc="email"/>
<field name="password" desc="password"/>
<field name="type" desc="type"/>
<field name="create_time" desc="create_time" validType="date"/>
<field name="intro" desc="intro"/>
</table>
有关于各个元素的配置的含义,可以查看我们提供的 XSD 文件。也可以查看我们的附件。这里,将这些默认生成的各个元素与属性做一个介绍。
在父元素 <table> 下面,有一系列的子元素 <field> ,这个很容易理解,就是每个字段的定义。 name 属性:字段名
desc 属性:字段描述
validType 属性:验证类型
字段名当然是不用修改的也是不允许修改的。
我们先修改 Desc 属性吧,因为我们在页面上看到的表头与输入提示都是字段名。
OK ,现在我们的 user_demo 配置变成了这样:
<table id="user_demo">
<field name="id" desc="ID" validType="int" isKey="true"/>
<field name="login_name" desc=" 登录名 "/>
<field name="email" desc=" 电子信箱 "/>
<field name="password" desc=" 密码 "/>
<field name="type" desc=" 用户类型 "/>
<field name="create_time" desc=" 创建时间 " validType="date"/>
<field name="intro" desc=" 个人说明 "/>
</table>
我们加上了中文的说明。
现在刷新我们的页面,怎么还和以前一样??
这是因为 Cwin 对配置都缓存起来了。进入 Cwin 的控制页面 (/demo/demo.jsp) ,点击更新缓存的链接。接下来,刷新我们的 user_demo 页。注意到了吗,表头与输入提示都已经变成了中文的了!
但我们的 user_demo 表还没有任何的记录呢,好吧,让我们来添加一些记录。
点击页面上的 add record 链接。
我们可以试着为 ID 输入非数字。出现了验证,但错误信息显得很粗糙。对吗。但我们的 Email 选项呢。没有验证?是的,我们在上面的配置文件中没有看到对 Email 的验证类型定义。
OK ,我们现在为它们都加上验证类型。最后,配置文件变成这样。
<table id="user_demo">
<field name="id" desc="ID" validType="int" isKey="true"/>
<field name="login_name" desc=" 登录名 " validType="signName"/>
<field name="email" desc=" 电子信箱 " validType="email"/>
<field name="password" desc=" 密码 " minLen="6" maxLen="20"/>
<field name="type" desc=" 用户类型 " min="0" max="9"/>
<field name="create_time" desc=" 创建时间 " validType="date"/>
<field name="intro" desc=" 个人说明 " general="false"/>
</table>
登录名: validType=”signName” signName 的规则与 JAVA 语言变量名的命名规则类似。
电子信箱: validType="email" 可限定他为 Email 。
用户类型: min="0" max="9" 限定为 0 – 9 之间的数字
密码: minLen="6" maxLen="20" 限定他为 6 到 20 位之间的字符。
个人说明: general="false" 表示允许这一项输入特殊字符。
这个选项默认为 true 。表示不允许输入特殊字符的。比如上面的密码,是不允许特殊字符的。
OK ,我们刷新缓存,刷新页面,试试。验证都生效了吗?
但我们现在有一个问题,就是我们的验证提示都很粗糙,有没有好的解决方案呢?那就是 <field> 的子元素, <comment> 。好的,我们现在为每个元素加上 Comment 子元素。
于是,我们的配置文件变成了这样:
<table id="user_demo">
<field name="id" desc="ID" validType="int" isKey="true"/>
<field name="login_name" desc=" 登录名 " validType="signName">
<comment> 请输入正确的登录名 </comment>
</field>
<field name="email" desc=" 电子信箱 " validType="email">
<comment> 请输入正确的电子信箱 </comment>
</field>
<field name="password" desc=" 密码 " minLen="6" maxLen="20">
<comment> 请输入符合要求的密码, 6--20 位长 </comment>
</field>
<field name="type" desc=" 用户类型 " min="0" max="9"/>
<field name="create_time" desc=" 创建时间 " validType="date">
<comment> 请输入正确的时间 </comment>
</field>
<field name="intro" desc=" 个人说明 " general="false"/>
</table>
我们就可以看到我们所定义的验证信息了。
查询与排序的配置
一个简单的用户浏览功能好像马马虎虎可以使用了。但老板还需要分页查询并且可以按某些字段排序。那我们因为这个需要来为 Cwin 作扩展吗?正如你所想的,不需要!在每一个 <field> 中有几个属性是用来定义排序与查询的。
老板需要以登录名与 Email 来对用户进行查询并排序。
在 <field> 中有一个属性叫做 cond ,用来定义查询时的条件。
我们可以如下定义:
<field name="login_name" desc=" 登录名 " validType="signName" cond =”like”>
<field name="email " desc=" 电子信箱 " validType="signName" cond =”like”>
“like” 表示查询时将使用 like 匹配。另外 Cwin 还支持 < , > , = , between 等条件。
而我们排序的属性叫做 order 。
order 的值一般是一个字段名,某些情况下可能是一个函数。因为我们在比较复杂的场景下将会用到一些的排序条件。比如说按用户注册的月份来排序。
<field name="login_name" desc=" 登录名 " validType="signName" cond =”like” order=”login_name”>
<field name="email " desc=" 电子信箱 " validType="signName" cond =”like” order=”email”>
好了,最终的 XML 配置如下:
<table id="user_demo">
<field name="id" desc="ID" validType="int" isKey="true"/>
<field name="login_name" desc=" 登录名 " validType="signName" order="login_name" cond="like">
<comment> 请输入正确的登录名 </comment>
</field>
<field name="email" desc=" 电子信箱 " validType="email" order="email" cond="like">
<comment> 请输入正确的电子信箱 </comment>
</field>
<field name="password" desc=" 密码 " minLen="6" maxLen="20">
<comment> 请输入符合要求的密码, 6--20 位长 </comment>
</field>
<field name="type" desc=" 用户类型 " min="0" max="9"/>
<field name="create_time" desc=" 创建时间 " validType="date">
<comment> 请输入正确的时间 </comment>
</field>
<field name="intro" desc=" 个人说明 " general="false"/>
</table>
现在请刷新缓存并刷新页面。看到查询表单了吗?
那么排序呢?您应该看到输出表格的箭头了,点击我们定义了排序的字段的表头吧。嗯,这一切是不是很简单呢?
有一个细节,如果定义的条件是 between ,比如说注册时间。因为我们有两个查询框,我的查询描述将输出什么? Cwin 有自己默认的输出。在这里,您最好使用 condDesc 做一下配置,两个描述使用逗号分隔,注意,是英文逗号。比如 condDesc=” 开始时间 , 结束时间 ” 。诸位可以试一试。
默认值与默认变量
除了数据库自身的默认值以外,可以为 <field> 配置两种变量值,一种是插入数据时的默认值(相当于数据库自己定义的 default 属性),一种是修改时的默认值。分别对应于 default 与 modifyValue 属性。
Cwin 提供了一种更灵活的默认值:变量。 Cwin 内置支持的变量只有一个: _CWIN_SYS_TIME (系统时间)。在数据输入时 Cwin 会将这个变量替换为当前的时间。另外, Cwin 也支持用户自定义的默认值变量。这需要用户继承一个类 (cn.antia.cwin.ValiableInjector) 来为这些变量赋值。需要覆盖其 protected Object parseValiableValue(String sv, HttpServletRequest request) 方法。然后在 table.xml 的 <constants> 中定义变量与 ValiableInjector 类。
比如,我们需要将用户的注册时间设定为系统时间。就可以定义如下:
<field name="create_time" desc=" 创建时间 " default=” _CWIN_SYS_TIME”>
主键生成器配置
Cwin 内置支持两种主键生成器: increment 和 uuid 。 Increment 将产生自增型主键。为 Cwin 的默认主键生成方式。 Uuid 将产生 UUID 串。另外如果用户需要有其它的主键生成方式,则需要用户自定义主键生成器。实现 cn.antia.cwin.db.tool. IdGenerator 接口。
默认主键生成器与用户自定义的主键生成器在 table.xml 的 <constants> 中指定。分别对应于 default_id_generator 与 id_generator 属性。 id_generator 用来指定用户自定义的主键生成器实现。
default_id_generator 有四个可选值: increment 、 uuid 、 appointed 、 foreignKey 。
针对每张表可以指定不同的主键生成器。利用 <field> 元素的 idGenerator 属性。 idGenerator 属性的值与 default_id_generator 的值一致。当 idGenerator 的值为 appointed 时, Cwin 将会使用 id_generator 定义的 IdGenerator 实现来获取主键。 foreignKey 一般用于一对一关系中的右边表。
存储类型
存储属性类型表示数据在数据库中的存储形式。通过 <field> 元素的 store 来定义。它有四个可选值:
normal: 正常存储
md5:md5 加密存储
encrypt: 加密存储, Cwin 提供的一种 md5 加密的一种衍生形式
binary: 二进制存储。用来存储大型文件。 ( 目前版本 (1.0pv1) 没有实现此功能 )
如果现在老板过来,要求我们将密码存储为 MD5 形式。 OK 。我们来做一下修改:
<field name="password" desc=" 密码 " minLen="6" maxLen="20" store=”md5”>
嗯,对,就是这样,老板的要求实现了了!
元素配置的引用
为了避免元素配置的重复。 Cwin 提供了元素引用功能。使用 ref 属性。
Ref 有两种语法,一种是直接引用,另一种则带有点 (.) 号。
直接引用类似这样: ref=”valid” ,引用从公共字段中定义的 valid 元素。
带点号的则是 ref=”user.create_time” ,表示引用在 Window ID 为 user 或表名为 user create_time 字段定义。
元素配置的覆盖:
如果在元素中引用了其它元素,而在这个元素中又定义了一些已经在被引用元素中已经定义属性。那么,被引用元素中的定义将被引用元素中的定义覆盖。
输入的配置
现在来看我们的编辑页面,还有些问题:
<!---->1. <!---->主键字段不应出现在编辑页面。
<!---->2. <!---->个人说明应使用 Textarea 来输入。
<!---->3. <!---->用户类型需要以下拉列表形式展现。
好了,我们带着这些问题来了解输入的配置。
输入是 Field 的一个子节点:以下是一个输入框的示例。
<input type=”text” desc=” 登录名 ” size=”80” >
针对第一个问题,诸位读者认为将如何配置呢?对了,就是 hidden 。
<input type=”hidden”/> ,嗯,这样,我们的第一个问题就算是解决了。
那么,第二个问题就是:
<input type=”textarea” cols=”70” rows=”4”/>
那么第三个问题就是:
<input type=”select”/> 。
那么,下拉选项的配置呢?这稍有难度,因为我们需要引入一个新的子节点。 <options>
Options 的第一种配置很直接:
<options>
<option value=”1” desc=” 管理员 ”/>
<option value=”2” desc=” 普通用户 ”/>
</options>
另一种方式,则是通过 sql 。假定我们有一张表用来存储用户类型,则可以如下定义:
<options>
<sql>select id,name from user_type</sql>
</option>
其中 SQL 元素中定义的 SQL ,将以查询结果的第一列为 value ,第二列为 desc 。
现在,让我们来完成输入的配置:
<table id="user_demo">
<field name="id" desc="ID" validType="int" isKey="true">
<input type="hidden"/>
</field>
<field name="login_name" desc=" 登录名 " validType="signName" order="login_name" cond="like">
<comment> 请输入正确的登录名 </comment>
</field>
<field name="email" desc=" 电子信箱 " validType="email" order="email" cond="like">
<comment> 请输入正确的电子信箱 </comment>
</field>
<field name="password" desc=" 密码 " minLen="6" maxLen="20">
<comment> 请输入符合要求的密码, 6--20 位长 </comment>
</field>
<field name="type" desc=" 用户类型 ">
<input type="select"/>
<options>
<option desc=" 管理员 " value="1"/>
<option desc=" 普通用户 " value="0"/>
</options>
</field>
<field name="create_time" desc=" 创建时间 " validType="date">
<comment> 请输入正确的时间 </comment>
</field>
<field name="intro" desc=" 个人说明 " general="false">
<input type="textarea" cols="70" rows="5"/>
</field>
</table>
老办法,刷新缓存,查看页面变化。
另外,您也可以试试将用户的个人说明将成 fckeditor 试试。定义如下:
<input type="fckeditor" cols="870" rows="195"/>
Fckeditor 可以上传图片哦。。。
等等,请注意这次表格数据发生的变化。
<!---->1. <!---->用户类型列:变成了描述,而不是真实的值。这是 Cwin 在配置好 options 之后默认显示为描述,如果需要显示为值。当然也是可以的。
<!---->2. <!---->个人说明: 显示为了 … ,而没有显示具体内容。这是为什么呢。这是 Cwin 做的一小小的工作,将长字段在表格中隐藏了。当然,您也可以在页面中配置它为隐藏。但这些都是下一节的内容了。
输出配置
输出配置相对来说要简单一些。输出的配置集中在 <output> 元素上。它的属性有: dispMode,desc,goat 等等,但这三个属性将是最基础的。
dispMode :定义在输出表格中的显示方式,它有几个可选值: none,hidden,pop,link,value, desc
其中 value 是默认值,将会把原始值输出在页面上。
none 表示不在表格中输入这一列。
desc 表示在元素拥有 options 值输出描述而不是值。
link 比较有用处,他将在表格中输出一个超链接。但为了要使 link 有效,我们必须定义另一个属性,叫做 href !这个大家都知道。如果需要定义链接的目标窗口,那么则需要再加一个属性,叫做 target……
hidden 表示在表格中隐藏,这样的话我们的输出表格中显示什么呢。对了是 goat 属性定义的值,如果 goat 没有定义值,那么会有一个自动赋予的值。而这个默认值则在 constants 中定义。
另外其它支持的属性有:
href,target,title, style, class,onclick, onmouseout, onmouseover:
这些属性将在表格输出时原样输出。
嗯,有一个很重要的功能:这些属性的值的定义是可以带变量定义的。这使得这些自定义属性变得很有用。比如我们定义一个 onclick 属性为 onclick=”alert(‘userid:[id]’);” 或者这样定义 href=”cwin?_CWIN_ID=user_demo&_CWIN_ACTION=show&id=[id]” 。
这个 [id] 就是变量。
好啦,现在,老板要求在表格中点击登录名可以在新窗口查看用户的信息以便打印。并且需要将用户的个人说明以浮动层的方式展示。
针对这个需求,我们要做的是定义两个 output 元素,一个在登录名的 field 下,一个在个人说明的 field 下。定义如下:
<output dispMode="link" href="cwin?_CWIN_ID=user_demo&_CWIN_ACTION=show&id=[id]" target="_blank"/>
<output dispMode="pop"/>
这个版本的配置是这样:
<table id="user_demo">
<field name="id" desc="ID" validType="int" isKey="true">
<input type="hidden"/>
</field>
<field name="login_name" desc="登录名" validType="signName" order="login_name" cond="like">
<output dispMode="link" href="cwin?_CWIN_ID=user_demo&_CWIN_ACTION=show&id=[id]" target="_blank"/>
<comment>请输入正确的登录名</comment>
</field>
<field name="email" desc="电子信箱" validType="email" order="email" cond="like">
<comment>请输入正确的电子信箱</comment>
</field>
<field name="password" desc="密码" minLen="6" maxLen="20">
<comment>请输入符合要求的密码,6--20位长</comment>
</field>
<field name="type" desc="用户类型">
<input type="select"/>
<options>
<option desc="管理员" value="1"/>
<option desc="普通用户" value="0"/>
</options>
</field>
<field name="create_time" desc="创建时间" validType="date">
<comment>请输入正确的时间</comment>
</field>
<field name="intro" desc="个人说明" general="false">
<input type="fckeditor" cols="870" rows="195"/>
<output dispMode="pop"/>
</field>
</table>
好了,如果您刷新页面看到了界面上的效果,我们进入下一章。
分享到:
相关推荐
2. **透明效果实现**: 在Windows中,透明效果通常通过修改窗口的WS_EX_TRANSPARENT扩展样式或使用SetWindowRgn函数实现。WS_EX_TRANSPARENT使窗口对消息透明,但不会影响子窗口。而SetWindowRgn则可以设置窗口的...
2. **事件驱动**:ActionScript3.0的一大优势是其事件驱动模型,Dartou_cwin5可能提供了一套完善的事件处理机制,使开发者能更好地响应用户交互和系统事件。 3. **数据绑定**:为了简化UI和数据之间的交互,框架...
2. vis_spectrum.cpp:这是源代码文件,很可能包含了光谱分析器的主要功能实现,包括音频数据的处理和可视化。 3. optionsdlg.cpp:可能包含了选项对话框的代码,让用户可以设置插件的参数或偏好。 4. CWin32Window....
2. **定时器**:为了实现“实时”更新,我们需要设置一个定时器,如SetTimer()函数,定期触发事件,更新曲线数据并重绘窗口。定时器回调函数(如OnTimer())将负责刷新数据和控件的显示。 3. **数据处理**:实时...
2. **界面设计**: - 接下来,开发者需要设计用户界面,这可能包括棋盘的布局,按钮(如“开始”、“重置”等),以及可能的提示信息。在MFC中,通常使用资源编辑器来设计对话框和菜单,并将控件与类成员函数关联...
2. **选择硬盘**:按回车键确认选择本地硬盘。 3. **选择源分区**:使用上下光标键选择要备份的源分区,确认后继续。 4. **指定镜像文件位置与名称**:输入镜像文件的路径和文件名,例如D:\sysbak\cwin98.gho。 ...
2. 解压文件:使用解压工具,如WinRAR或7-Zip,打开压缩包并解压到指定位置。 3. 运行安装程序:找到解压后的安装文件,双击运行,通常会有一个向导式的界面引导用户完成安装。 4. 遵循提示:按照屏幕上的提示,同意...
2. `matroxamp_analyser_skin.bmp`:可能是另一个特定皮肤,可能针对Matrox公司的硬件进行了优化。 3. `vis_spectrum.cpp`:这是C++源代码文件,可能包含了光谱分析器的主要实现逻辑。 4. `optionsdlg.cpp`:这可能...
2. matroxamp_analyser_skin.bmp:可能是针对Matrox显卡优化的分析器皮肤,因为Matrox是当时的流行显卡品牌,可能有特定的显示优化。 3. vis_spectrum.cpp:这是光谱分析器的主要实现代码,包含处理音频数据并将其...
2. 按照提示选择源分区,然后指定镜像文件的名称和路径。例如,你可以将镜像文件保存在 D:\sysbak\ 目录下,并命名为 cwin98.gho。 分区还原则涉及到 Partition 菜单的 From Image 功能: 1. 选择 From Image 选项...
2.脚本调用样子如下: // Demo1. 删除文件 { local dllKernel32 = CWin32Dll( "Kernel32.dll" ); local iRet = dllKernel32.DeleteFileA( "c:/1.zip" ); print( iRet ); } // Demo2. 显示消息对话框 { ...
2. **Session存储**:可以将值存储在服务器端的Session对象中,两个窗口共享同一个Session,通过Session ID来访问。例如,`Session["value"] = "123"`,在另一个窗口中用`string value = Session["value"].ToString...
2. **套接字API**:在大多数操作系统中,Socket API提供了创建、绑定、监听、连接和读写数据等函数,如`socket()`, `bind()`, `listen()`, `accept()`, `connect()`, `send()`, `recv()`等。 3. **网络地址与端口**...
2. **初始化**:在类中提供一个初始化函数,用于设置窗口类属性,如窗口风格(WS_OVERLAPPEDWINDOW)、背景刷(hbrBackground)、窗口过程(WNDPROC)等。使用`RegisterClassEx`函数注册窗口类。 3. **窗口创建**:...
2. **运行SETUP.EXE**:执行安装程序,SETUP.EXE会检测硬件兼容性并开始复制必要的系统文件到硬盘。 3. **配置硬件**:在安装过程中,系统会询问有关硬件的详细信息,如内存大小、显示卡类型等,以便优化设置。 4. *...
2. **重载成员函数**:为了实现自定义行为,我们需要重载一些CListBox的成员函数。例如,可以重载`OnDrawItem()`来改变列表项的绘制方式,或者重载`OnMeasureItem()`来控制项的高度和宽度。 3. **消息映射**:确保...
2. **定义错误代码**:首先,你需要一个错误代码。这可能是从系统API调用返回的,或者用户直接输入的。 ```cpp DWORD dwError = 5; // 例如,错误代码5代表"Access is denied." ``` 3. **调用`FormatMessage`**:...
经过上述调整,这个高度自适应的`iframe`解决方案能够在IE、FF和Opera上正常工作,不再出现纵向滚动条,确保了用户体验的一致性。然而,值得注意的是,这个方法可能不适用于所有情况,例如Safari、Chrome等其他...
2. **构造函数**:初始化ComboBox控件,设置其初始属性,如位置、大小、样式等。 3. **成员函数**: - `AddItem`:添加新的选项到ComboBox。 - `SelectItem`:选择指定索引或值的项。 - `GetSelectedItem`:返回...