电力系统介绍

电力系统介绍国家电力系统需解决问题 一 国电设备管理 项目介绍 一 技术设施维护 包括设备购置计划管理 设备管理 设备校准检修管理 1 设备购置计划 主要用来管理电力监测中心计划购置的设备 未购置 包括 CRUD 等功能

大家好,我是讯享网,很高兴认识大家。

国家电力系统需解决问题

一:(国电设备管理)
 项目介绍:
一、技术设施维护:包括设备购置计划管理、设备管理、设备校准检修管理。
1、设备购置计划:主要用来管理电力监测中心计划购置的设备(未购置),包括CRUD等功能;对已经购置的设备需要将状态从“未购置”变为“已购置”;并实现推迟购置计划,实现在时间上的顺延;实现批量导入功能,将大批量的数据以excel的形式导入到数据库;并可按照条件将数据导出(excel格式),导出的字段可通过系统灵活的进行配置。
2、设备管理:设备信息管理主要是对监测中心的设备进行统一的维护和管理,并可将设备按照条件导出excel报表。
3、设备校准和检修:对监测中心正在使用的设备定期的进行校准和检修,定期备份校准和检修的结果,并将校准和检修的结果录入系统。并实现上传文件、导出等功能。
二、技术资料管理:管理监测中心正在使用设备的相关技术资料,技术资料以附件的形式存在。
三、站点运行管理:包括站点的基本信息管理、站点运行情况管理、站点的维护情况管理。
1、站点基本信息管理:主要管理电力公司各个站点的基本信息情况。用站点的运行情况反映各站点下设备的运行情况,对站点的数据信息可进行批量导入和批量导出。
2、站点运行情况管理:控制管理站点的运行情况,主要包括站点的故障类型、故障持续时长、故障处理状态、故障处理结果等,通过查询条件反映站点在各个时间段的运行情况,对站点运行情况和故障类型做图表分析。
3、站点维护情况管理:包括对站点维护计划和维护情况两部分,维护计划用于方便提示用户定期对站点做维护,使得站点能正常运行,疏而不漏;维护情况则为出现故障的站点录入故障信息,以及出现问题后如何排除故障的处理信息等。
四、监测中心建筑物信息管理:管理监测中心所有建筑物。包括房屋建筑,道路,围墙等建筑物信息和各个建筑物的维修信息。
五、系统管理:该功能针对系统管理员开放或对检测中心的有关领导开放,包括用户、角色、权限的管理和分配;维护项目中使用的元数据(即数据字典);还包括系统运行监控功能,所谓运行监控是对站点、设备的运行情况进行维护和检查,出现问题后要及时报警,并将实时检查的数据放置系统首页;还包括系统的日志和审计功能,记录系统各个环节的使用情况,保证系统的安全运行。
六、审批流转:在审批流程管理模块中实现对“设备购置计划”、“设备费用报销”等审核流程的部署和定制,根据流程定义的规则实现了对公司的重要事件、文件等信息的审批流转;其中审核文件模板、待办审核文件以附件的形式在流程中传递,由报审人下载模板,按公司模板要求填写文件,并报审领导;在流程审批过程中,领导对上传的文件下载后进行审核。

1:说说你最近做的这个项目的背景?
《国家电力监测中心设备资源管理系统》是国家电力管理中心根据业务需求发展需要,建立的以设备信息管理为核心,其他管理为辅助的业务数据管理和查询系统。所有数据均以WEB的形式直接录入系统,数据录入及汇总后,为各级用户提供各种统计数据信息,辅助本部门相应决策,提高业务工作效率。
国家电网设备资源管理系统,一旦开发完成电力公司各个所属单位以及分公司均可以使用,系统会针对不同的单位和站点完成部署,每个单位和站点维护设备由自己去配置使用,但是总数据由统一数据库维护,实现数据共享和查询。
2:你的表结构是如何设计的?为什么要这么设计?
为了项目开发方便、高效,增强表之间的关联,数据库采用主外键的主从表关系设计,操作数据库采用hibernate进行数据库表和字段的映射
一:仪器设备管理:
设备购置计划中的设备与设备信息是一对一关系,电力设备管理中的所有设备均有购置计划中获取,购置计划中的设备需要领导审批,审批通过对设备进行购买,购买后将设备放置到设备信息表中维护,购置计划可以使用批量添加设备功能,将大批量的设备导入到设备表的数据库中,方便用户的操作。
电力仪器设备表与设备校准/检修表是1对多的关系,根据需求,一个设备要定期进行校准和检修,如果在监控中发现设备问题,并要将出现问题的原因进行分析、总结,同时将校准和检修的记录添加到设备校准/检修表中,在这里,因为校准记录和检修记录都包括时间、批注、校准人\检修人等字段,为了增强表中字段的重用性,所以经项目组研究后将2个表(校准表和检修表)合并成1个表,采用一个标识用来记录是校准信息还是检修信息,这样的好处在于使用1个表,维护起来方便。
二:资料图书管理
图书资料管理表,根据需求,所有电力设备的使用说明书以及电力设备运行维护操作的帮助说明书等都要放到图书资料管理中,由管理员上传,其他人负责下载查看(指定查询条件,根据所属单位和图纸类别)。附件表的结构如图
表名(中文) 表名(英文) 字段前缀
图书资料附件表 Elec_FileUpload Elec_
序号 字段名 类型 长度 NULL 说明
1 SeqID int no 主键ID
2 ProjID varchar 50 yes 带有附件的工程ID(所属单位)
3 BelongTo varchar 50 yes 所属模块1-0,1-1,1-2,2-0(图纸类别)
4 FileName varchar 50 yes 文件名
5 FileURL varchar 1000 yes 文件路径
6 ProgressTime varchar 20 上传时间
7 Comment varchar 500 备注
8 IsDelete varchar 10 是否删除
9 CreateEmpID varchar 50 创建人
10 CreateDate datetime 创建时间
其中projID字段是供所属单位字段查询使用,belongTo字段供图纸类别字段查询使用
但是您是不是觉得这样命名很别扭,这是因为我们这里采用1个表来维护所有的文件上传对应的业务附件。
例如,我们项目中会多次用到文件上传,如校准记录、检修记录、站点运行情况、设备运行情况都是以附件的形式传递和查看,为了减少附件表的重复定义,增强表的重用性,传统做法是一个业务表都会对应附件表,这样附件表会很多,所以我们设计使用同一张表完成所有业务的附件上传,即都放置到一个“图书资料附件表”中。我们看一下数据库的设计
表名(中文) 表名(英文) 字段前缀
图书资料附件表 Elec_FileUpload Elec_
序号 字段名 类型 长度 NULL 说明
1 SeqID int no 主键ID
2 ProjID varchar 50 yes 带有附件的工程ID(所属单位)
3 BelongTo varchar 50 yes 所属模块1-0,1-1,1-2,2-0(图纸类别)
4 FileName varchar 50 yes 文件名
5 FileURL varchar 1000 yes 文件路径
6 ProgressTime varchar 20 上传时间
7 Comment varchar 500 备注
8 IsDelete varchar 10 是否删除
9 CreateEmpID varchar 50 创建人
10 CreateDate datetime 创建时间
其中projID字段表示带有附件业务表的主键ID,belongTo字段表示所属模块,即该附件应该存放的模块编号,该编号由开发人员定义,但是不能重复。例如:校准记录编号为“1-1”、检修记录编号为“1-2”、站点运行情况编号为“1-3”、设备运行情况编号为“1-4”,这样查询附件是就可以通过这两个字段,查询每个模块表中对应的主键ID的业务,即这个业务表单对应的所有附件。
三:站点管理
所有电力仪器设备的运行和维护统一要放置到每个单位的站点下,那么站点的运行和监控就成为客户比较关心的话题。
站点基本信息表,包括维护站点的代号、名称、地点、厂家、通讯方式、使用日期等信息。
站点在维护过程中需要先制定站点的维护计划,即提前申请维护站点计划,方便对某一地区进行通知,站点维护计划和站点信息组成多对一的关系,即一个站点会存在多个维护计划,方便客户针对站点添加数据,并按照计划日期对站点进行考察和维护。
按照计划维护站点过程中,将站点的运行和维护情况录入数据库表中存储,开发设计站点运行情况表,其中站点基本信息表和站点运行情况表是1对多的关系,站点运行情况表中包括上报年月、故障发生时间、故障描述,同时也包括故障处理时间、处理方法和手段、故障原因等字段,这样设计方便与对站点进行故障的分析和统计,方便对站点进行解决方案的收集和汇总,为站点的运行维护故障提供解决方案。同时也通过时间对站点的故障时长进行汇总,电力公司领导通过汇总的故障时长计算该站点的运行情况是否达标,是否符合公司内部期望的要求。
四:检测台建筑管理
检测台建筑物表,用来维护电力公司所有的建筑物信息。包括管理监测中心所有建筑物。包括房屋建筑,道路,围墙等建筑物信息和各个建筑物的维修信息。字段包括:创始时间、大修时间、使用时间、扩建面积。合理维护电力设备建筑物信息,达到设备、站点、建筑物合理优化。
五:系统管理
用户信息表
表名(中文) 表名(英文) 字段前缀
用户登录信息表 Elec_User Elec_
序号 字段名 类型 长度 NULL 说明
1 UserID varchar 50 no 主键ID
2 JctID varchar 50 yes 所属单位code(对应数据字典)
3 UserName varchar 50 yes 用户姓名
4 LogonName varchar 50 yes 登录名
5 LogonPwd varchar 50 yes 密码
6 SexID varchar 10 yes 性别
7 Birthday datetime yes 出生日期
8 Adress varchar 100 yes 联系地址
9 ContactTel varchar 50 yes 联系电话
10 Email varchar 50 yes 电子邮箱
11 Mobile varchar 50 yes 手机
12 IsDuty varchar 10 yes 是否在职
13 OnDutyDate datetime yes 入职时间
14 OffDutyDate datetime yes 离职时间
15 Comment varchar 500 yes 备注
16 IsDelete varchar 10 yes 是否删除,0表示正常
17 CreatEmpID varchar 50 yes 创建人ID
18 CreateDate datetime yes 创建时间
19 LastEmpID varchar 50 yes 修改人ID
20 LastDate datetime 修改时间

角色信息表
表名(中文) 表名(英文) 字段前缀
角色信息表 Elec_Role Elec_
序号 字段名 类型 长度 NULL 说明
1 roleID varchar 50 no 主键ID
2 roleName varchar 50 yes 角色名称
权限信息
表名(中文) 表名(英文) 字段前缀
权限信息表 Elec_Role Elec_
序号 字段名 类型 长度 NULL 说明
1 mid varchar 50 no 权限code(aa,ab,ac等)
2 pid varchar 50 yes 父级权限code (0,aa等)
3 name varchar 50 yes 权限名称
4 url varchar 500 yes 权限访问路径url(ztree插件中的属性)
5 icon varchar 100 yes 权限显示图表(ztree插件中的属性)
6 target varchar 50 yes 权限url访问目标区域(ztree插件中的属性)
7 isMenu boolean yes 权限是否是菜单
8 isParent boolean yes 权限是否父级权限(ztree插件中的属性)
用户角色关联表
表名(中文) 表名(英文) 字段前缀
用户角色关联表(多对多中间表)即联合主键 Elec_User_Role Elec_
序号 字段名 类型 长度 NULL 说明
1 userID varchar 50 no 用户ID
2 roleID varchar 50 yes 角色ID
角色权限关联表
表名(中文) 表名(英文) 字段前缀
角色权限关联表(多对多中间表)即联合主键 Elec_Role_Popedom Elec_
序号 字段名 类型 长度 NULL 说明
1 roleID varchar 50 yes 角色ID
2 mid varchar 50 yes 权限code(aa,ab,ac等)
3 pid varchar 50 yes 父级权限code (0,aa等)

首页运行监控信息表:将当天录入的站点和设备的运行情况录入后在系统登录首页中进行显示
表名(中文) 表名(英文) 字段前缀
运行监控信息表 Elec_commonmsg Elec_
序号 字段名 类型 长度 NULL 说明
1 UserID varchar 50 no 用户ID
2 StationRun varchar 1000 yes 站点运行情况
3 DevRun varchar 1000 yes 设备运行情况
4 CreateEmpCode varchar 50 yes 创建人
5 CreateDate datetime yes 创建日期
数据字典表:贯穿整个项目的数据核心
表名(中文) 表名(英文) 字段前缀
数据字典表 Elec_SystemDDL Elec_
序号 字段名 类型 长度 NULL 说明
1 seqID Int 50 no 主键ID
2 Keyword varchar 20 yes 查询关键字
3 DdlCode Int 100 yes 数据字典的code值
4 DdlName varchar 50 yes 数据字典的value值
存放数据结构为:

六:报表管理(设置字段的动态导出)
完成对数据库各个业务表字段的动态设置,方便页面动态显示每个字段,方便做excel文件字段动态设置导出
在页面中使用:

其中未导出字段列表和导出字段列表加起来是所有的用户表字段。

数据库设计:完成对字段的动态设置:
表名(中文) 表名(英文) 字段前缀
导出字段设置表 Elec_ExportFields Elec_
序号 字段名 类型 长度 NULL 说明
1 BelongTo varchar 10 no 所属模块(如1-0,1-1,2-1等)
2 ExpNameList varchar 5000 yes 导出名称列表(中文)用“#”分开
3 ExpFieldName varchar 5000 yes 导出字段名称(字段名)用“#”分开
4 NoExpNameList varchar 5000 yes 未导出名称列表(中文)用“#”分开
5 NoExpFieldName datetime yes 未导出字段名称(字段名)用“#”分开

【保存】后,数据库存放结果:

其中:
expNameList表示中文名称,即显示的文件的标题名称
登录名#用户姓名#性别#联系电话#职位#入职时间
expFieldName表示导出字段的英文数据库表对应的列名称
logonName#userName#sexID#contactTel#postID#onDutyDate
我们可以按照该数据库的设置,动态导出excel报表数据结果:

3:这个项目为用户提供了哪些服务?包括哪些模块
【技术设施维护管理,图书资料管理,站点运行管理】
(1) 运行监控模块:填写站点运行情况、设备运行情况
使用文本编辑器ckeditor+ckfinder,实现对运行情况的数据编辑,支持图片视频的上传和下载,在系统首页可以查看其运行情况数据。
在首页中显示当天的运行监控结果。
(2) 图书资料管理:从系统中搜索图书资料
使用lucene进行全文检索,搜索索引库数据,实现大量数据的搜索查询,提高查询的性能和效率,并实现对检索结果的数据截取(即摘要)和文字高亮。
使用struts2的文件上传拦截器完成多文件的上传,上传支持多种文件类型
使用struts2的返回类型完成文件下载
(3) 设备校准记录,设备检修记录,站点运行监控报告模块
【1】使用POI完成对excel报表的导出
【2】下载导入模板,添加数据,使用JXL完成对excel报表的导入
【3】在导入、导出功能中实现了excel报表对大批量数据的分页功能!并实现对文件数据的动态导出,对导出文件的显示效果进行了优化。
【4】在导入、导出过程中,每当查询数据字典进行数据项编号和值转换的过程中,使用了hibernate的二级缓存(ecache缓存),大大提高了检索策略,尤其在报表导入、导出、加载数据项的时候,对数据录入准确性的校验、比对,在性能上优化了数据的检索速度和效率。
【5】在导入、导出过程中,由于数据量较大,而且同时还需要对数据进行校验,所有为了给客户提供导入、导出的感官效果,使用ajax在页面上开启另一个线程,这个线程用来计算导入、导出的执行条数的百分比情况,将信息友好的显示在页面上,实现一个百分比效果的进度条。

JXL和POI的区别:
1:JXL的api更加灵活,api更容易被开发人员理解,操作时,可以使用sheet对象的getCell(i, j);获取某行某列的值,将值放置到集合对象中,方便完成数据的批量导入
2:但是JXL技术只支持.xls的格式,不支持office2007的格式,即xlsx,所以我们提供给客户的模板都要求是.xls的格式,要求客户按照模板填写和导入,并添加一定限制,解决该问题
(4) 设备校准记录,设备检修记录,站点运行监控报告模块
使用Jfreechart技术对设备的校准和检修情况做分析和统计,饼图、柱状图、线状图综合分析每个设备的周、月、年的运行情况(即一个月出现故障几次、报修几次、维修周期多长时间),并由技术人员统一根据数据做故障分析。
而且在站点基本信息模块中,使用FusionChartFree技术实现flash效果的数据统计,统计每个站点的运行情况,并通过比较得出每个站点的供电情况,站点的持续供电时间,以及故障持续时间等,统计站点的运行情况和维护情况,并得到客户的好评。
(5) 数据字典模块
数据字典将所有业务表中用作统计功能的字段,都从数据字典中调用,存放
时存放数据项的编号,而显示时显示数据项的值,保证了数据库表字段存储的数据安全。根据不同的数据类型存放不同数据项的值。
使用数据字典的过程中,除了本系统部署在各个站点调用之外,还使用webservice的远程技术,北京国家电网总公司作为服务器端使用axis远程发布电力系统功能元数据,即数据字典的数据,并提供wsdl的使用说明书,供各个分公司调用数据,达到所有元数据的统一。例如各个分公司的设备监控平台,元数据统计指标都依赖于我们的系统,就需要调用我们元数据用作数据汇总,如监控指标、故障类型等数据。
(6) 设备购置计划,设备费用报销,站点维护计划模块,
在以上业务审批流转模块中,使用jbpm4.4(Activiti)完成对工作流的制定和控制,实现审批流程的灵活定制,模板方便上传和下载,对流程进行定制,发布,在流程图中实现顺序执行、分签、会签、指定transition分配任务等操作,并在各个环节中,给申请人和审核人提供了流程实例运行信息的动态监控功能,帮助审核人查看当前流程图的位置,前端使用highslide js(ajax)用于图片显示,实现动画效果。
(7) 分页服务
根据项目经理要求,自己开发并实现了一个js框架(核心操作使用ajax),在页面上可以实现异步请求,不用使整个页面刷新,就可以得到分页的效果,给js已被项目组认可,应用于系统的分页功能、图书管理、站点和设备监控、角色功能、数据字典维护等功能
分页具体效果如下:
2个页面index.jsp和list.jsp
index.jap中定义2个Form表单,Form1表单中设置查询的条件(传递查询条件参数),Form2表单中显示分页查询的结果列表。
list.jsp中存放查询后的分页结果,将查询后的分页结果(即list.jsp)的全部内容放置到form2表单中。
即传递表单Form1中元素的值作为参数到服务器,在服务器端组织查询条件,并进行分页查询,将查询的结果跳转到list.jsp中,并显示对应的结果,最后通过操作js将list.jsp的全部内容显示到index.jsp的Form2中,完成分页。
开发后的js并可以进行扩展:项目中在站点和设备运行情况中,一个页面可使用多个Form表单,在Form1中选择站点和设备的名称,在同一个页面对应Form2、Form3的表单中,显示对应的站点和设备的监控情况。

4:你承担这个项目的那些核心模块?
需求分析,需求设计,编码
设备仪器管理(设备购置,设备运行维护,设备监控,设备校准,设备检修),资料图书管理(资料图书上传,下载,查看),站点运行管理(站点基本信息,站点运行情况,站点维护情况),系统管理(用户、角色、权限、授权、系统权限控制)
审批流转模块管理(设备购置、设备费用报销实现审核流程操作)

这里参加的模块越多,越能说明你在项目中的地位。
5:这些模块的实现思路说一下?
(1)仪器设备管理
在做仪器设备管理的购置计划模块中,将设备购置计划数据填写后,使用JBPM工作流,将业务人员填写好的设备购置计划单按照定义好的流程执行,由公司内部领导审核,审核通过,按照填写的购置时间和购置地点,以及预算金额去执行,在购置计划中,提供【购置】按钮,可以将购置完成的设备,复制一份数据放置到仪器设备管理中,如果不是着急购置的设备,提供【计划顺延】功能,推迟设备购置时间,推迟时间的长短通过参数的设置,将设备购置计划顺延后,到指定时间后再进行提示购买。
在做设备购置计划中,为了方便客户批量添加设备购置计划,添加批量导入功能,将所有的设备购置单填写在excel报表中,然后执行批量导入,将购置计划的清单全部导入到数据库中,这样方便领导做批量审核和批量购置。并对导入的细节层层校验,保证数据录入数据库的绝对准确。
设备管理中提供查询功能,针对每个分公司,每个站点查询对应设备,并将查询的设备以报表的形式导出,针对需求,在【导出】时实现动态设置和显示excel报表上的字段,这样是因为客户的需求是要求针对每个单位对设备类型的要求不同和打印不同的excel报表,这样设置可以使得打印的excel报表字段显示更加灵活,为了追求导出的性能,在导出中使用到数据字典转换的字段全部采用hibernate的二级缓存进行检索,而且优化sql,全部使用一条sql语句完成对所有字段数据的检索和导出,为了实现大批量数据导出,添加导出excel的算法,在excel报表中实现分页,这样解决了报表每个工作表中行,列数据有限的局限性,更好的支持excel报表的导出功能,为了让客户看到导出报表的执行速率,使用ajax完成进度条,在后台进行计算,进度条上显示导出数据的百分比情况。
设备校准检修模块中,针对仪器设备添加校准和检修的记录,针对需求,一个设备可以添加多个校准记录和检修记录,所以先针对查询条件,查询对应的设备信息,在后边添加新增,修改,删除,查看等功能,灵活的对一个设备完成填写校准记录和检修记录。同时由于校准和检修的数据差不多,所以采用一个表完成2个业务的功能操作,使用标识字段判断究竟保存的校准记录还是检修记录;系统提供校准记录和检修记录的文档管理,使得每个设备按照定义好的校准周期和检修周期的参数设置运行,根据每个设备类型和种类,自动设置校准周期和检修周期(例如1周,1个月,1年等),将在周期内生成的校准报告和检修报告可以以附件的形式上传到指定设备中,用于领导的下载和查阅。
针对需求,实现批量添加校准记录和检修记录功能,使用所属单位和设备类型作为条件,选择对应的设备(这里要求该设备的品牌和类型要一致),实现批量添加设备校准记录和检修记录功能,可以填写一个校准记录和检修记录,同时批量添加到多个设备中,实现用户的简化操作。
资料图书管理中,根据需求,这个模块的数据量很大,而且检索频率很高,所有仪器设备和站点维护相关文档全部要放置到该模块进行管理,所以我觉得可以采用附件的形式管理,不要求客户每次录入资料图书信息,只是以一份文档的电子版存在即可,在页面中指定所属单位和图纸的种类,完成文件上传,搜索时为了搜索的准确性,并提高搜索效率,采用lucene技术,检索时使用索引库检索,这样的好处是实现了对搜索数据提取摘要和文字高亮,由于检索的是索引库,索引性能要比检索数据库要快,支持的检索方式也比数据库灵活,但是这里开发时要注意,一定让数据库的数据和索引库要同步,否则不能搜索出我们想要的结果。
审批流转模块中,根据需求,这个业务是将设备的购置计划单或者设备费用报销单填写后,交给公司经理和财务审核,审核通过后按照申请去执行,为了让流程按部就班执行,决定使用JBPM(Activiti)技术,用工作流的方式处理流程的定义、管理和执行。
系统管理中,实现用户管理(即使用该系统的用户),角色管理列出系统中所有的用户和权限,并对每个用户进行授权,权限表采用树型菜单的数据设置,符合jquery的ztree加载格式。将jquery的ztree插件用到的属性设置到权限表中,这样实现了ztree加载json数据的灵活性,实现权限菜单的动态设置和显示,而且方便实现细颗粒的权限控制。并使用过滤器控制粗颗粒度权限控制(精确Session级别),使用struts2的自定义拦截器实现细颗粒度权限控制,将每个访问Action类的方法上定义注解,注解上对应权限表的权限数据给定的惟一访问权限的标识(权限code和父级权限code),我们再访问Action的方法时,如果当前用户具有权限可以访问,如果不具有权限跳转到错误页面,由错误页面提示错误信息,5秒后跳转到系统首页,完成后好提示。
运行监控模块的需求是:用来监控当前系统所属分公司单位下的设备运行情况,以及当前分公司下管理每个站点的运行情况,每15分钟将监控的报告录入系统,这样可以通过选择,针对某个设备或者某个站点去监控其运行情况,如果没有异常会由系统自动录入数据,表示无异常(使用spring的quartz调度器,完成定时任务,查询最后一次录入数据的时间,如果间隔时间大于15分钟,会自动录入一条数据,表示没有出现异常),如果出现异常,需要人工录入数据,并指定出现异常的设备名称和站点,并要用特殊的图片或者符号标出异常,并在系统首页进行显示,并且给各个管理者发送邮件,尽快解决问题。
运行监控模块中为了方便查看当天站点运行情况和设备运行情况,将当天运行情况生成报告,或者以表格的形式输出,再或者以视频的形式查看,使用ckeditor+ckfinder文本编辑器,实现对数据格式的多样性优化,客户看了更加直观。但是考虑文本编辑器的原理是将html标签进行存储,这样数据库表中列存放的数据量很大,所以我建议将数据进行分段存储
原理如下:

操作:

6:项目中哪些功能模块涉及到了大数据量访问(高并发问题)你是怎么解决的?
暂时没有高并发,因为我们的系统部署后在每个分公司的站点都会部署系统的系统,所以每个站点和设备运行情况比较独立,每个分公司的站点负责维护不同数据,所以不会出现数据高并发。
惟一大数据操作就是资料图书管理模块,但是我采用lucene技术,先查询索引库再查询数据库的方式,解决了大批量数据的检索,上传文档也是根据所属单位和图纸类别上传,每个文档的管理也不会出现冲突。

7:你碰到了哪些问题?你是怎么解决的?
1:在做报表导入,导出的时候,如果固定excel字段格式,显得不够灵活,针对不同公司,不同站点导出excel的字段不同,所以需要实现报表字段的动态设置,所以实现【导出设置】、【导入设置】功能。
【导出设置】功能原理分析,及解决方案:
(1)数据库表,定义一个导出设置表,表中5个字段,分别是所属模块、导出字段的中文名,导出字段的英文名,未导出字段的中文名,未导出字段的英文名,存放的数据是excel字段显示的中文名称,和使用hql语句和sql语句的数据字典的英文名称。

(3)数据库存放的方式

注意:

操作:

保存数据库的结果:(字段显示的是导入中文字段和导入英文字段)

2:在文件导入、导出过程中,由于数据量很大,有些时候还要做必要的校验,所以比较浪费时间,客户等待时间也很长,即使添加了进度条客户也不知道还要执行多久才能结束操作,于是我决定使用ajax开发一个多线程服务,一个线程处理数据,一个线程计算数据执行操作进度,并同时换算成百分比,在页面中显示。百分比效果的进度条让客户在操作报表的时候得心应手,而且可以自行安排时间,减少了不必要的等待。 

讯享网

:3:文件上传,由于我们的系统多处使用附件上传,资料图书管理,设备运行、设备校准报告,设备检修报告和站点运行,站点监控报告均支持附件上传,为了统一维护附件表,我提出将所有附件都放置到同一个表中维护
表结构设计:
表名(中文) 表名(英文) 字段前缀
图书资料附件表/其他模块附件表 Elec_FileUpload Elec_
序号 字段名 类型 长度 NULL 说明
1 SeqID int no 主键ID
2 ProjID varchar 50 yes 带有附件的工程ID(所属单位)
3 BelongTo varchar 50 yes 所属模块1-0,1-1,1-2,2-0(图纸类别)
4 FileName varchar 50 yes 文件名
5 FileURL varchar 1000 yes 文件路径
6 ProgressTime varchar 20 上传时间
7 Comment varchar 500 备注
8 IsDelete varchar 10 是否删除
9 CreateEmpID varchar 50 创建人
10 CreateDate datetime 创建时间

资料图书管理模块上传附件
字段表示
2 ProjID varchar 50 yes 带有附件的工程ID(所属单位)
3 BelongTo varchar 50 yes 所属模块1-0,1-1,1-2,2-0(图纸类别)
其他业务模块上传附件
2 ProjID varchar 50 yes 带有附件的工程ID(所属单位)
3 BelongTo varchar 50 yes 所属模块1-0,1-1,1-2,2-0(图纸类别)
这样维护统一将所有的附件放置到一张表中维护
同时为了将附件按照时间文件夹维护,满足附件在服务器上的规范管理,决定将文件上传完成以下要求:
1:完成文件上传
1:将上传的文件统一放置到upload的文件夹下
2:将每天上传的文件,使用日期格式的文件夹分开,将每个业务的模块放置统一文件夹下
3:上传的文件名要指定唯一,可以使用UUID的方式,也可以使用日期作为文件名
4:封装一个文件上传的方法,该方法可以支持多文件的上传,即支持各种格式文件的上传
5:保存路径path的时候,使用相对路径进行保存,这样便于项目的可移植性

讯享网//完成文件上传,同时返回上传文件的路径path(相对路径) / * 完成文件上传 1:将上传的文件统一放置到upload的文件夹下 2:将每天上传的文件,使用日期格式的文件夹分开,并使得每个业务模块用文件夹的方式分开 3:上传的文件名要指定唯一,可以使用UUID的方式,也可以使用日期作为文件名 4:封装一个文件上传的方法,该方法可以支持多文件的上传,即支持各种格式文件的上传 5:保存路径path的时候,使用相对路径进行保存,这样便于项目的可移植性 */ public static String fileUploadReturnPath(File upload, String uploadFileName,String model) { //获取upload的文件夹 String basepath = ServletActionContext.getServletContext().getRealPath("/upload"); //指定日期格式的文件夹(yyyy/MM/dd) String datepath = DateUtils.dateToString(new Date()); //文件后缀 String perfix = uploadFileName.substring(uploadFileName.lastIndexOf(".")); //文件名(格式:ADFSDFSDFA@#$@#$@DSDFS12321.doc) String filename = UUID.randomUUID().toString()+perfix; //判断当前日期文件夹是否存在,如果不存在,创建一个日期的文件夹 String modelPath = basepath+datepath+"/"+model; File dateFile = new File(modelPath); if(!dateFile.exists()){ dateFile.mkdirs(); } //目标文件 File destFile = new File(modelPath+"/"+filename); //文件上传 upload.renameTo(destFile); //返回相对路径 return "/upload"+datepath+filename; } 

}

4:在导入、导出报表的时候,为了做大批量数据的操作,开发实现excel报表的分页功能,解决了excel每个单元表格中存放数据的有限性(65536行和256列),和同事一起写出一个导出和导入的算法,将每个单元格作为一页,解决了导入、导出数据的局限性。 5:为了解决导入,导出数据的性能优化,拼写sql语句,争取将所有数据都使用1条sql语句完成。而且在数据转换的时候,使用缓存(hibernate的二级缓存)处理,从缓存中获取想要的数据,而不是从数据库,这样加快了检索的性能。 6:本来图书资料管理中没有考虑使用lucene进行检索,就是根据所属单位和图纸类别上传对应设备和站点的信息资源,由公司员工下载查看,但是在开发后期我发现这样操作性能有时候很慢,而且搜索到的结果不是客户想要的,于是在网上搜集lucene的资料,决定使用lucene操作索引库的方式去做,结果这样做确实加快了搜索性能,而且搜索的数据更加准确,lucene的分词器和高亮器在这个模块上得到非常好的体现,并得到了用户的好评。 7:根据需求,在设备购置和费用报销过程中,需要每个分公司单位的负责人审核签字,完成审核,由于之前审核流程不是很复杂,只需各自部门经理和站点总负责人签字,所有开始没有考虑使用JBPM(Activiti),使用申请单中提供标识字段完成审核,但是项目开发中期客户决定由财务再进入审核,用来判断设备购置和报销金额是否合理,这样改动起来影响较大,还不排除客户之后会如何改变流程的执行,所有决定采用JBPM(Activiti)技术,客户在页面上方便选择下一个任务的办理人(使用流程变量),让流程根据指定连线给下一个任务的办理人,由办理人审核,如果通过,就按照申请的信息执行,如果不通过回退到申请(或者指定审核不通过,由申请人重新填写单据,发出申请),此时由设备购置科室人员再次提交申请,领导再次审核,直至完成流程。从而实现了流程更加灵活控制,而且还可以应对各种需求变更。 

8:做完这个项目你有哪些收货?
1:经历了软件生命周期的每个阶段,立项,需求调用,需求设计,编码,测试,上线,维护,验收等阶段,对每个阶段要做的事情有深刻的经验和总结。
2:学到了如何分析问题,设计问题,解决问题的能力。
3:实践和巩固了很多技术点的开发,如lucene,JBPM(Activiti)工作流,webservice(axis2)服务,struts2,hibernate,spring,javascript,jquery,ajax,poi报表,jxl报表,JFreechart报表,FusionChartsFree(FCF)报表等
4:在设计阶段,根据需求设计数据库表的能力得到了加强,SQL语句的拼装和优化也得到了很多锻炼和提高,业务代码的封装也更加严谨。
5:项目中大量使用js特效,ajax,jquery,在javascript和jquery上得到了巩固和加强
6:为了控制系统安全,项目经理让我研究权限管理控制,挑战很大,我使用拦截器、过滤器、定义注解对应权限的思想设计并实现了权限控制,保证系统的访问安全

总结:项目不大,但是学到和用到的技术知识很多,非常高兴,也认识了很多同事和朋友,也希望我会的技术能贵公司带来帮助

二:项目中具体模块技术点抽取(国电设备管理)
1:SSH框架整合
第一步:创建数据库(格式:UTF-8)
创建表:

第三步:持久层
(1)在cn.itcast.elec.domain中创建ElecText.java
public class ElecText implements java.io.Serializable {

讯享网private String textID; //主键ID private String textName; //测试名称 private Date textDate; //测试日期 private String textRemark; //测试备注 public String getTextID() { return textID; } public void setTextID(String textID) { this.textID = textID; } public String getTextName() { return textName; } public void setTextName(String textName) { this.textName = textName; } public Date getTextDate() { return textDate; } public void setTextDate(Date textDate) { this.textDate = textDate; } public String getTextRemark() { return textRemark; } public void setTextRemark(String textRemark) { this.textRemark = textRemark; } 
<?xml version="1.0" encoding="UTF-8"?>

(3)在src下创建hibernate.cfg.xml的配置文件

<?xml version="1.0" encoding="UTF-8"?> com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/itcastElec?useUnicode=true&characterEncoding=utf8 root root
 <!-- 其他的配置 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.show_sql">true</property> <!-- 加载映射文件 --> <mapping resource="cn/itcast/elec/domain/ElecText.hbm.xml"/> </session-factory> 
(4)使用junit在test包中进行测试(并且导入log4j的配置文件) public class TestHibernate { /测试保存*/ @Test public void save(){ Configuration configuration = new Configuration(); configuration.configure();//加载类路径hibernate.cfg.xml和映射文件 SessionFactory sf = configuration.buildSessionFactory(); Session s = sf.openSession(); Transaction tr = s.beginTransaction();
讯享网 //测试操作对象的过程,就是操作数据库表 ElecText elecText = new ElecText(); elecText.setTextName("测试Hibernate名称"); elecText.setTextDate(new Date()); elecText.setTextRemark("测试Hibernate备注"); s.save(elecText); tr.commit(); s.close(); } 

}

第四步:DAO层
(1)在cn.itcast.elec.dao中创建2个接口(公用接口和业务接口)
 公用接口:
public interface ICommonDao {
void save(T entity);
}
 业务接口(需要继承公共接口,并且指定泛型T所对应的对象:
public interface IElecTextDao extends ICommonDao {
public static final String SERVICE_NAME = “cn.itcast.elec.dao.impl.ElecTextDaoImpl”;
}
(2)在cn.itcast.elec.dao.impl中创建2个接口的实现类
 公用类(需要继承HibernateDaoSupport,这样可以方便使用HibernateTemplate对象):
public class CommonDaoImpl extends HibernateDaoSupport implements ICommonDao {

/使用@Resource注入SessionFactory*/ @Resource(name="sessionFactory") public final void setSessionFactoryDi(SessionFactory sessionFactory) { this.setSessionFactory(sessionFactory); } /保存*/ public void save(T entity) { this.getHibernateTemplate().save(entity); } 

}
 业务类(需要继承公用类,这样可以使用公用类中的定义的方法)
@Repository(IElecTextDao.SERVICE_NAME)
public class ElecTextDaoImpl extends CommonDaoImpl implements IElecTextDao {

}

(3)在src创建spring的配置文件(beans.xml)

<?xml version="1.0" encoding="UTF-8"?>

讯享网<!-- 1:开启对注解的支持,组件的自动扫描,扫描在类上定义的@Controller @Service @Repositiry注解,范围是cn.itcast.elec的包 --> <context:component-scan base-package="cn.itcast.elec"/> <!-- 2:? 先不写,大家想想项目中应该添加什么?--> <!-- 3:创建SessionFactory,这是spring整合hibernate的核心 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <!-- 加载类路径下的hibernate.cfg.xml --> 
classpath:hibernate.cfg.xml
<!-- 也可以使用spring的配置文件的方式管理事务 <tx:advice id="aa" transaction-manager="trManager"> <tx:attributes> <tx:method name="save*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/> <tx:method name="update*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/> <tx:method name="delete*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/> <tx:method name="*" read-only="true"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut expression="execution(* cn.itcast.elec.service..*.*(..))" id="bb"/> <aop:advisor advice-ref="aa" pointcut-ref="bb"/> </aop:config>--> 
讯享网/测试保存*/ @Test public void save(){ //加载类路径下的spring容器 ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); //调用接口 IElecTextDao elecTextDao = (IElecTextDao) ac.getBean(IElecTextDao.SERVICE_NAME); //操作对象 ElecText elecText = new ElecText(); elecText.setTextName("测试Dao名称"); elecText.setTextDate(new Date()); elecText.setTextRemark("测试Dao备注"); elecTextDao.save(elecText); } 

true

第五步:Service层
(1) 在cn.itcast.elec.service中创建接口:
public interface IElecTextService {
public static final String SERVICE_NAME = “cn.itcast.elec.service.impl.ElecTextServiceImpl”;
void saveElecText(ElecText elecText);
}

(2) 在cn.itcast.elec.service.impl中创建接口的实现类:
@Service(IElecTextService.SERVICE_NAME)
@Transactional(readOnly=true)
public class ElecTextServiceImpl implements IElecTextService {

@Resource(name=IElecTextDao.SERVICE_NAME) private IElecTextDao elecTextDao; @Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED,readOnly=false) public void saveElecText(ElecText elecText) { elecTextDao.save(elecText); } 

}
(3) 使用junit测试
public class TestService {


讯享网

讯享网/测试保存*/ @Test public void save(){ ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml"); IElecTextService elecTextService = (IElecTextService) ac.getBean(IElecTextService.SERVICE_NAME); //操作对象 ElecText elecText = new ElecText(); elecText.setTextName("测试Service名称"); elecText.setTextDate(new Date()); elecText.setTextRemark("测试Service备注"); elecTextService.saveElecText(elecText); } 

true

第六步:控制层(MVC)
(1)在cn.itcast.elec.web.action中创建Action(业务Action)类和BaseAction(公用Action)
 Action类:(注意:这里要设置成多例,即@Scope(value=prototype),因为struts2的Action是多实例,多线程)
@Controller(“elecTextAction”)
@Scope(value=“prototype”)
public class ElecTextAction extends BaseAction{

ElecText elecText = this.getModel(); @Resource(name=IElecTextService.SERVICE_NAME) private IElecTextService elecTextService; /执行保存*/ public String save(){ //保存 elecTextService.saveElecText(elecText); return "save"; } 

}
 BaseAction类(封装模型驱动对象,HttpServletRequest和HttpServletResponse对象):
public class BaseAction extends ActionSupport implements ModelDriven,ServletRequestAware,ServletResponseAware {

讯享网protected HttpServletRequest request; protected HttpServletResponse response; T entity; public BaseAction(){ /泛型转换成真实类型(范类转换)*/ Class entityClass = TUtils.getTClass(this.getClass()); try { entity = (T) entityClass.newInstance(); } catch (Exception e) { e.printStackTrace(); } } public T getModel() { return entity; } public void setServletRequest(HttpServletRequest req) { this.request = req; } public void setServletResponse(HttpServletResponse res) { this.response = res; } 

}

(2)在cn.itcast.elec.util包下创建公用类(泛型转换)。
泛型转换的目的子类传递真实对象类型,在父类中使用泛型转换成真实对象类型。
以后util包下封装的就是公用类。
public class TUtils {

/泛型转换成真实类型(范类转换)*/ public static Class getTClass(Class entity) { ParameterizedType parameterizedType = (ParameterizedType) entity.getGenericSuperclass(); Class entityClass = (Class) parameterizedType.getActualTypeArguments()[0]; return entityClass; } 

}

(3)在src下创建struts2的配置文件struts.xml

<?xml version="1.0" encoding="UTF-8"?> /system/textAdd.jsp

(4)在web.xml中添加配置:




struts2
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter


struts2
/*



contextConfigLocation
classpath:beans.xml


org.springframework.web.context.ContextLoaderListener


index.jsp


(5)导入css,script,jsp,images进行测试
使用system/textAdd.jsp进行测试:页面如图

2:底层代码封装
 Dao类封装
对公用、频繁调用查询数据库表的方法进行抽取,使用T型代表传递的持久化对象,可以实现根据DAO对应的持久化对象,来操作CommonDao中定义的对应持久化对象的方法。
public class CommonDaoImpl extends HibernateDaoSupport implements ICommonDao {
/*泛型转换,获取真实对象实体/
Class entityClass = TUtils.getTClass(this.getClass());

讯享网/使用@Resource注入SessionFactory*/ @Resource(name="sessionFactory") public final void setSessionFactoryDi(SessionFactory sessionFactory) { this.setSessionFactory(sessionFactory); } /保存*/ public void save(T entity) { this.getHibernateTemplate().save(entity); } /更新*/ public void update(T entity) { this.getHibernateTemplate().update(entity); } /使用主键ID,查询对象*/ public T findObjectByID(Serializable id) { return (T) this.getHibernateTemplate().get(entityClass, id); } /使用主键ID,删除对象(删除一个或者多个对象)*/ public void deleteObjectByIDs(Serializable... ids) { if(ids!=null && ids.length>0){ for(Serializable id:ids){ Object entity = this.findObjectByID(id); this.getHibernateTemplate().delete(entity); } } } /使用封装对象的集合,批量删除对象*/ public void deleteObjectByCollection(List<T> list) { this.getHibernateTemplate().deleteAll(list); } /测试指定查询条件,查询结果集(不分页)*/ / 这里1=1的目的是方便在Service层拼装sql或者hql语句,连接统一使用and * SELECT o FROM ElecText o WHERE 1=1 #Dao层填写 AND o.textName LIKE '%张%' #Service拼装 AND o.textRemark LIKE '%张%' #Service拼装 ORDER BY o.textDate ASC,o.textName desc #Service拼装 */ public List<T> findCollectionByConditionNoPage(String condition, final Object[] params, Map<String, String> orderby) { String hql = "SELECT o FROM "+entityClass.getSimpleName()+" o WHERE 1=1"; String orderByHql = this.initOrderByHql(orderby); final String finalHql = hql + condition + orderByHql; //执行hql语句 /方式一:直接使用HibernateTemplate的find()方法,find方法支持执行hql语句*/ 

// List list = this.getHibernateTemplate().find(finalHql, params);
/*方式二:获取SessionFactory,在获取Session/
// SessionFactory sf = this.getHibernateTemplate().getSessionFactory();
// Session s = sf.getCurrentSession();
// Query query = s.createQuery(finalHql);
// query.setParameter(0, params[0]);
// query.setParameter(1, params[1]);
// List list = query.list();
/*方式三:使用hibernateTemplate调用回调函数/
List list = this.getHibernateTemplate().execute(new HibernateCallback() {
public Object doInHibernate(Session session)
throws HibernateException, SQLException {
Query query = session.createQuery(finalHql);
if(params!=null && params.length>0){
for(int i=0;i<params.length;i++){
query.setParameter(i, params[i]);
}
}
return query.list();
}
});
return list;
}

/组织排序语句,将Map集合转换成String类型*/ private String initOrderByHql(Map<String, String> orderby) { StringBuffer buffer = new StringBuffer(""); if(orderby!=null && orderby.size()>0){ buffer.append(" ORDER BY "); for(Map.Entry<String, String> map:orderby.entrySet()){ buffer.append(map.getKey()+" "+map.getValue()+","); } //删除最后一个逗号 buffer.deleteCharAt(buffer.length()-1); } return buffer.toString(); } 

}

子类调用只需要继承CommonDaoImpl即可,无需在定义相似的方法:
@Repository(IElecTextDao.SERVICE_NAME)
public class ElecTextDaoImpl extends CommonDaoImpl implements IElecTextDao {

}
 Action类封装
由于Action类使用javabean对象(VO对象)用来接收页面传递的参数,在struts2中叫做模型驱动对象,将模型驱动对象放置到BaseAction类中,这样只需要传递真正的类型,对应BaseAction类中的T型就会访问并找到对应的真实VO对象,使得每个业务Action类的调用VO对象只需要定义,无需实现。
BaseAction类
public class BaseAction extends ActionSupport implements ModelDriven,ServletRequestAware,ServletResponseAware {

讯享网protected HttpServletRequest request; protected HttpServletResponse response; T entity; public BaseAction(){ /泛型转换成真实类型(范类转换)*/ Class entityClass = TUtils.getTClass(this.getClass()); try { entity = (T) entityClass.newInstance(); } catch (Exception e) { e.printStackTrace(); } } public T getModel() { return entity; } public void setServletRequest(HttpServletRequest req) { this.request = req; } public void setServletResponse(HttpServletResponse res) { this.response = res; } 

}
业务Action类
@Controller(“elecTextAction”)
@Scope(value=“prototype”)
public class ElecTextAction extends BaseAction{

ElecText elecText = this.getModel(); @Resource(name=IElecTextService.SERVICE_NAME) private IElecTextService elecTextService; /执行保存*/ public String save(){ //保存 elecTextService.saveElecText(elecText); return "save"; } 

}

 Utils类封装

  1. 报表导入、导出操作
  2. Lucene指定索引库位置,存放索引库,查询索引库操作
  3. 分页操作等
    3:数据库“运行监控”设计

使用Ckeditor+ckFinder文本编辑器实现:
如果项目中使用文本编辑器,那么字段无法存放过大数据怎么办?
解决方案:

操作:

实现方式
有2种,
 一种是单纯的进度条
 一种是带有百分比效果的进度条(使用ajax技术):
分析原理:

面试的问到:如何实现:

 文本编辑器
将fckEdit部署到myeclipse下,发布项目,并运行fckEdit的项目。
效果,如图:

注意:如果项目加载大量的js操作,使用eclipse或者myeclipse开发都会在右下角去校验js,此时会非常浪费时间。由于我们这里使用的CkEditor+CKFinder也使用很多的js,所有要去掉校验,否则大家开发的时候都把时间用在了校验上。

同时:点击项目,点击Builders属性,配置,去掉对应的复选框的

如果以后大家开发extjs项目,或者开发jquery easyUI的项目,要求按照该方法去配置。
这里注意:CKEditor表示文本编辑器,效果:
此时不支持文件上传
要想支持文件上传,可以使用CKFinder整合CKEditor,在这个插件中定义了文件上传的功能。

这里强调,可以改变ckeditor包中config.js的配置,可以改变文本编辑器的显示效果:
例如:
config.skin = ‘office2003’; //编辑器皮肤样式
// 使用基础工具栏
//config.toolbar = “Basic”;
// 使用全能工具栏
//config.toolbar = “Full”;
// 使用自定义工具栏
config.toolbar =
[
[‘Source’, ‘Preview’, ‘-’],
[‘Cut’, ‘Copy’, ‘Paste’, ‘PasteText’, ‘PasteFromWord’, ],
[‘Undo’, ‘Redo’, ‘-’, ‘Find’, ‘Replace’, ‘-’, ‘SelectAll’, ‘RemoveFormat’],
[‘Image’, ‘Flash’, ‘Table’, ‘HorizontalRule’, ‘Smiley’, ‘SpecialChar’,‘PageBreak’],
‘/’,
[‘Bold’, ‘Italic’, ‘Underline’, ‘-’, ‘Subscript’, ‘Superscript’],
[‘NumberedList’, ‘BulletedList’, ‘-’, ‘Outdent’, ‘Indent’, ‘Blockquote’],
[‘JustifyLeft’, ‘JustifyCenter’, ‘JustifyRight’, ‘JustifyBlock’],
[‘Link’, ‘Unlink’, ‘Anchor’],
‘/’,
[‘Format’, ‘Font’, ‘FontSize’],
[‘TextColor’, ‘BGColor’],
[‘Maximize’, ‘ShowBlocks’, ‘-’, ‘About’]
];

用来定义编辑器显示工具栏的效果:

5:数据字典数据库设计

存放的数据:

6:使用webservice(axis2)发布数据字典远程服务并调用
北京国家电网总公司作为服务器端使用webservice的axis远程技术发布电力系统功能元数据,供各个分公司调用,比如各个分公司的设备监控平台,元数据统计指标都依赖于本系统,如监控指标、故障类型等。
需求:

实质上分三步操作:
创建一个服务器端(总部电力系统),和一个客户端(分公司)
第一步:使用服务器端提供的接口,生成.wsdl文件
第二步:使用.wsdl文件,在电力系统中生成服务器端的代码
第三步:使用.wsdl文件
(http://localhost:8080/itcast0306elec/services/IWebSystemDDLService?wsdl)
生成客户端的代码

7:用户管理数据库设计

这里一个用户对应多个用户职称附件,所有用户表和用户职称附件表是一个一对多的关系。

8:性能优化:hibernate二级缓存,提供查询效率
优点:对应查询结果相同的数据,可以减少频繁检索数据库的操作。
分析:
项目中使用数据字典的时候,经常会遇见

  • 使用数据类型和数据项的编号,获取数据项的值
  • 使用数据类型和数据项的值,获取数据项的编号
  • 使用数据类型,加载对应数据类型的下的集合
    解决方案:
    使用hibernate的二级缓存优化。
    二级缓存中存放的数据结构

二级缓存整合项目:
第一步:导入jar包:
需要引入三个jar包
在hibernate下能找到
hibernate-distribution-3.5.6-Final\lib\optional\ehcache\ehcache-1.5.0.jar
在srping下能找到
…\lib\concurrent\backport-util-concurrent.jar
…\lib\jakarta-commons\commons-logging.jar

第二步:在hibernate.cfg.xml中添加配置:

<?xml version="1.0" encoding="UTF-8"?> true org.hibernate.cache.EhCacheProvider true
讯享网 <!-- 加载映射文件 --> <mapping resource="cn/itcast/elec/domain/ElecSystemDDL.hbm.xml"/> <!-- 指定使用二级缓存的类 放在maping下面 --> <!-- 配置类级别的二级缓存 --> <class-cache usage="read-write" class="cn.itcast.elec.domain.ElecSystemDDL"/> </session-factory> 

第三步:在DAO中执行的hql语句的时候,调用setCacheable(true),例如:
public List findCollectionByConditionNoPageWithCache(String condition,
final Object[] params, Map<String, String> orderby) {
String hql = “SELECT o FROM “+entityClass.getSimpleName()+” o WHERE 1=1”;
String orderByHql = this.initOrderByHql(orderby);
final String finalHql = hql + condition + orderByHql;
//执行hql语句
/*方式三/
List list = this.getHibernateTemplate().execute(new HibernateCallback() {

 public Object doInHibernate(Session session) throws HibernateException, SQLException { Query query = session.createQuery(finalHql); if(params!=null && params.length>0){ for(int i=0;i<params.length;i++){ query.setParameter(i, params[i]); } } query.setCacheable(true); return query.list(); } }); return list; } 

9:角色管理数据库设计

所以项目页面的设计:使用角色查找权限和用户:

需要的表

10:角色权限控制系统
(1)使用角色控制系统功能键的URL连接
在访问页面之前,判断当前用户具有的角色,如果是系统管理员就传递系统管理员的URL连接到页面上,在页面的按钮或者连接上动态设置URL连接,这样就实现同一个按钮不同操作功能。
(2)使用权限控制页面上的菜单是否显示
 struts2标签
 自定义标签
代码:
(1) 使用struts2标签:
<s:set value="%{#session.globle_popedom}" var=“popedom” scope=“request”></s:set>
<s:if test="#request.popedom.contains(‘ec’)">

</s:if>
(2) 使用自定义标签:
1、在WebRoot/WEB-INF下建立RoleTagLib.tld文件:内容
<?xml version="1.0" encoding="UTF-8"?>

1.0
f
http://openhome.cc/jstl/fake

if
cn.itcast.elec.util.ConditionalTagUtil
scriptless


pattern
String



2、|在cn.itcast.elec.util中创建ConditionalTagUtil
package cn.itcast.elec.util;

讯享网 import java.io.IOException; import javax.servlet.jsp.JspException; import javax.servlet.jsp.tagext.SimpleTagSupport; import org.apache.struts2.ServletActionContext; public class ConditionalTagUtil extends SimpleTagSupport { private String pattern; /标签中要处理的内容*/ @Override public void doTag() throws JspException, IOException { String popedom = (String) ServletActionContext.getRequest().getSession().getAttribute("globle_popedom"); // <u:if pattern="aa"> if(popedom.contains(pattern)){ this.getJspBody().invoke(null); } } public void setPattern(String pattern) { this.pattern = pattern; } } 

3、在jsp页面中使用
<%@taglib uri="/WEB-INF/RoleTagLib.tld" prefix=“u” %>
<u:if pattern=“ec”>

</u:if>

Left.jsp中使用
  • ,定义id和class,树型结构显示就是在
    • 组件上显示的
小讯
上一篇 2025-03-10 10:00
下一篇 2025-01-23 18:36

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/26323.html