版本演变过程和系统的基本原理
视频讲解在线观看:视频讲解链接
http://i.youku.com/jfok1972
一、版本的变迁
此系统的构思来源于我于2006年用Delphi为某省国税局做的一个反避税基础数据库。该系统中需要查询2万多家企业的7年的所得税申报的年报数据,还有财务报表,以及其他相关的报表,共有大约50张表,当时摆在我面前的题目就是要任意选择一些字段的组合查询,还要能自定义二个比值的比率,还有对于分类汇总的指标也是自定义的,并且可以定义多级。这个系统算是一个我在编程顶峰时候做的一个项目。
在后来改用java开发c/s管理系统之后,就有了设计出能够全部自定义的管理系统的想法,也做出一个雏形。由于整个系统都是由我一个人完成的,我无法于每个领域都做到深入研究,因此在选用前后台的开发工具上面,我就只能选择成熟的框架了,前台最先使用的是extjs3,后台是java下的常用的ssh2,数据库用的是最容易管理的Sql Server 2005。
几年前我运用了前后台都用java开发的smartGwt重新设计了系统,也为客户做成了一套系统,但是smartGwt的调试和界面以及grid的渲染方式令我无法忍受,加之于正好extjs4的发布,于是我就用extjs4重新编写了前台界面,现在介绍的这套系统就是基于此。
二、为什么只要2步就可以构建完成?
熟悉hibernate的人可能可以猜想得到,其实这套系统就自动处理hibernate对象和其之间的关系。通俗的讲,就是前后台结合,把hibernate bean转换成一个个的模块,模块之间的上下级关系由manyToOne,oneToOne来控制。
在我后面将要介绍的如何搭一个简易的销售管理系统中会有一个“省份”的模块,先用这个模块来讲解一下系统的搭建过程。
第1步:建立数据表,省份模块,表名 Province
CREATE TABLE [dbo].[Province](
[tf_provinceId] [nvarchar](2) COLLATE Chinese_PRC_CI_AS NOT NULL,
[tf_name] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,
[tf_shortname] [nvarchar](10) COLLATE Chinese_PRC_CI_AS NULL,
[tf_district] [nvarchar](50) COLLATE Chinese_PRC_CI_AS NULL,
[tf_area] [int] NULL,
[tf_numberOfPeople] [int] NULL,
[tf_GDP] [money] NULL,
[tf_percent] [money] NULL,
[tf_isMunicipality] [bit] NULL,
[tf_createDate] [datetime] NULL,
[tf_remark] [nvarchar](max) COLLATE Chinese_PRC_CI_AS NULL,
[tf_inputmen] [nvarchar](10) COLLATE Chinese_PRC_CI_AS NOT NULL,
[tf_inputdate] [datetime] NOT NULL,
CONSTRAINT [PK_Province] PRIMARY KEY CLUSTERED
(
[tf_provinceId] ASC
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
第2步:生成的hibernate bean
@Entity
@TableDefine(group = "编码设置", id = 8010, title = "省份")
public class Province extends _InputInfoAbstract implements Serializable {
@Id
@FieldDefine(title = "编码", number = 10, fieldGroup = "基本信息")
@Column(nullable = false, length = 10)
private String tf_provinceId;
@FieldDefine(title = "名称", number = 20, nameField = true, fieldGroup = "基本信息")
@Column(nullable = false, length = 50)
private String tf_name;
@FieldDefine(title = "简称", number = 30, fieldGroup = "基本信息")
@Column(length = 10)
private String tf_shortname;
@FieldDefine(title = "所属区域", number = 40, fieldGroup = "基本信息")
@Column(length = 50)
private String tf_district;
@FieldDefine(title = "面积", number = 50, fieldGroup = "附加信息")
private Integer tf_area;
@FieldDefine(title = "人口数量", number = 60, fieldGroup = "附加信息")
private Integer tf_numberOfPeople;
@FieldDefine(title = "GPD", number = 70, fieldGroup = "附加信息")
private Double tf_GDP;
@FieldDefine(title = "百分比", number = 80, fieldGroup = "附加信息")
private Double tf_percent;
@FieldDefine(title = "是否自治区", number = 90, fieldGroup = "附加信息")
private Boolean tf_isMunicipality;
@FieldDefine(title = "附加日期", number = 100, fieldGroup = "附加信息")
private Date tf_createDate;
@FieldDefine(title = "备注", number = 190, fieldGroup = "附加信息")
private String tf_remark;
public Province(){
}
对于hibernate bean,我采用的是(Hibernate Annotations)标注方法。
在上面的bean文件中,我用到了自己的二个Java注释@interface文件,来标注表的信息和字段的信息。
<span style="font-size:14px;">@TableDefine(group = "编码设置", id = 8010, title = "省份")</span>
这条表示,Province 的模块名称为 省份,模块分组是放在 编码设置 里,id 号为 8010
package com.jfok.server.common.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface TableDefine {
//此表的id号,为一个4位数字
int id();
//模块名称
String title();
<span style="white-space:pre"> </span>//模块简称
String shortname() default "";
//模块分组名称
String group() ;
//模块的主键是否可以是分级的,如果是可以分级的,可定义为"2,2,2",表示有三级,每级代码长为2位,
//比如会计科目可以这样来定义
// 10
// 1001
// 100101
// 100102
// 100102
// 1002
// ......
String codeLevel() default "" ;
//模块是否有附件
boolean attachment() default false ;
}
@FieldDefine(title = "名称", number = 20, nameField = true, fieldGroup = "基本信息")
此条标注语句放在tf_name之前,表示 tf_name 的字段名是:名称,顺序号是20, 是记录的命名字段,字段分组放在基本信息组中。
package com.jfok.server.common.annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldDefine {
//字段名称
String title();
//顺序号
int number() default 0;
//字段备注
String remark() default "";
//是否是记录的命名字段,例如:对于客户单位表,客户名称字段其值为true,对于一份合同,合同名称其值为true
boolean nameField() default false;
//是否是隐藏字段
boolean hidden() default false;
//字段分组
String fieldGroup() default "默认组";
}
至此一个模块的表和字段的基本信息的定义就完成了,对于标准模块而言,把这个模块加到系统里以后,已经不用再有其他的编码了。