《医药销售管理系统说明.docx》由会员分享,可在线阅读,更多相关《医药销售管理系统说明.docx(33页珍藏版)》请在三一办公上搜索。
1、医药销售管理系统1 系统分析31.1 开发背景31.2 需求分析32 系统设计32.1 系统目标32.2 系统功能结构42.3 系统流程图43 软件架构63.1 逻辑分层结构设计63.2 系统文件夹组织结构73.3 实体对象设计73.4 定义ActionForm83.5 持久层结构设计83.6 业务层结构设计103.7 页面结构设计114 配置文件114.1 配置web.xml114.2 配置struts-config.xml124.3 配置hibernate.cfg.xml125 实体及映射125.1 药品实体映射125.2 药品类别实体映射135.3 销售明细实体映射135.4 用户实体映
2、射146 公共类设计146.1 Hibernate过滤器146.2 SupperDao类166.3 BaseAction类176.4 DeleteAction类186.5 字符串工具类187 国际化187.1 国际化资源文件187.2 国际化实现198 系统登陆模块198.1 查询用户198.2 登陆请求198.3 登录页面199 药品类别信息管理209.1 药品类别持久层设计209.2 药品类别的添加219.2.1 类别添加、修改请求处理219.2.2 类别添加页面219.3 分页查看类别信息219.3.1 查询与删除请求处理229.3.2 类别信息列表页面229.4 类别的修改与删除229
3、.5 药品类别统计229.5.1 JFreeChat工具类239.5.2 Action请求239.5.3 显示报表2310 药品信息管理2310.1 药品对象持久层设计2410.2 药品信息的添加与修改2410.2.1 药品添加的请求处理2410.2.2 药品添加页面2510.3 分页查看所有药品2510.4 查看药品详细信息2510.5 模糊查询药品2610.5.1 药品模糊查询请求处理2610.5.2 药品模糊查询页面2610.6 高级查询2710.7 查看库存2710.8 药品批量删除2710.8.1 批量删除请求处理2810.8.2 映射JSP页面中的按钮2811 购买药品2811.1
4、 选购药品2811.2 结账2912 销售管理2912.1 明细信息查询2912.2 销售排行统计3013 进货/需求管理3014 系统管理3114.1 添加管理员3114.2 修改密码3214.3 系统初始化3215 运行项目321 系统分析随着计计算机技术的不断发展,应用软件迅速普及,大到厂矿校企,小到图书、餐饮、医药管理等,随处都可看到它的身影。在以往依靠人工为主的医药销售管理方面,计算机和计算机系统逐步唱起了主角,凭借省时、省力、低误差等优点,从根本上改变了医药管理的传统模式,节省了物理资源,提高了工作效率。1.1 开发背景XX医药抄手坐落于XX小区内,多年来本着经济、实惠、高质量服务
5、的宗旨,赢得了小区百姓的信赖,药品供应量非常大。面对庞大的信息量,经常出现统计失误、药量供应不足的情况,医药超市经理决定使用一套合理、有效、使用的管理系统,对医药超市进行统一的管理。笔者受医药超市经理委托,开发一个医药销售管理系统,其宗旨是实现医药超市管理的系统化、规范化、实用化,对药品进行统一管理。1.2 需求分析在日常医药管理中,面对众多的药品和众多不同需求的顾客,每天都会产生大量的数据信息。以传统的手工方式来处理这些信息,操作比较繁琐,且效率低下。此时,一套合理、有效、实用的医药销售管理系统就显得十分必要。利用其提供的药品查询、统计功能,可以进行高效的管理,更好地为顾客服务。笔者通过对医
6、药超市的实地考察,从经营者和消费者的角度出发,以高效管理、快速满足消费者为原则,要求本系统具有以下特点。 具有良好的系统性能、友好的用户界面。 较高的处理效率,便于用户使用。 采用成熟的技术开发,全系统具有较高的技术水平和较长的生命周期。 对销售信息进行统计排行 尽可能地简化药品管理员的重复工作,提高工作效率。2 系统设计2.1 系统目标根据医药超市的管理要求,指定医药销售管理系统目标如下。 灵活的人机交互界面,操作简单方便、界面简洁美观。 系统提供中、英文语言,实现国际化 药品分类管理,并提供类别统计功能。 实现各种查询,如多条件查询、模糊查询等。 提供创建管理员账户及修改口令功能。 可对系
7、统销售信息进行统计分析。 系统运行稳定、安全可靠。2.2 系统功能结构医药销售管理系统提供了四大功能,分别为“基本信息管理”、“进货/需求管理”、“药品管理”、“系统管理”,具体结构如图1.1所示医药销售管理系统基本信息管理进货/需求管理药品销售管理系统管理药品信息管理药品类别管理库存信息查看药品需求管理药品进货管理销售明细管理销售排行统计销售时间统计系统初始化管理员帐号管理图1.1 医药销售管理系统功能结构图2.3 系统流程图医药销售管理系统流程如图1.2所示。管理员登录医药销售管理系统管理员进货/需求管理基本信息管理药品销售管理系统管理药品信息管理删除药品药品类别管理查询药品修改药品添加药
8、品修改类别查询类别删除类别添加类别修改需求查询需求删除需求添加需求销售排行统计查询销售明细当日销售明细库存修改系统初始化查询管理员密码修改添加管理员类别统计图1.2 医药销售管理系统流程图3 软件架构在开发项目前,首先要对软件的结构进行设计,也称之为软件架构。此过程是对软件整体结构的设计,如软件的逻辑分层结构、结构的实现、数据库等,特别是在Java的大型项目中,还需要设计出程序中的包结构及接口等,非常复杂,需要程序员进行全面的考虑。对于医药销售管理系统的整体涉及如下:3.1 逻辑分层结构设计医药销售管理系统由4层结构组成,并遵循MVC结构进行设计。4层结构分别为表示层、业务逻辑层、持久层与数据
9、库层,如图1.3所示。医药销售管理系统表示层(Struts框架)业务逻辑层(Struts框架)持久层(Hibernate框架)数据库层(MySQL数据库)图1.3 逻辑分层其中,表示层与业务逻辑层均由Struts框架组成,表示层用于提供程序与用户交互的界面,项目中主要通过JSP、ActionForm及Struts标签库进行展现;业务逻辑层用于处理程序中的各种业务逻辑,项目中通过Struts框架的中央控制器及Action对象对业务请求进行处理;持久层由Hibernate框架组成,负责应用程序与关系型数据库之间的操作;数据库层为应用程序所使用的数据库,本实例中为MySQL数据库。对于4层结构的具体
10、实现如图1.4所示。医药销售管理系统视图JSP、ActionForm、Struts标签控制器Action、struts-config.xml持久化Hibernate API、Hibernate.cfg.xmlMySQL数据图1.4 逻辑分层实现3.2 系统文件夹组织结构规范系统的整体架构是一个项目开发的标准,特别是在团队开发项目中,在编写代码之前,必须定制好项目的系统文件夹组织结构,以使程序条理清晰,利于后期的项目整合。在Java项目中可以将不同作用、功能相类似的文件放置于同一个包中,这样既可以保证团队开发的一致性,又可以将系统的整体结构规范化。创建完系统中可能用到的文件夹或Java包之后,在
11、开发时只需将所创建的类文件或资源文件保存到相应的文件夹即可。医药销售管理系统的文件夹组织结构如图1.5所示。图1.5 医药销售管理系统的文件夹组织结构3.3 实体对象设计在应用Hibernate框架的项目中,实体对象的确立是其中的关键。实体对象与数据库中的数据表相对应,并通过O/R映射建立实体与数据库的联系,Hibernate完全通过操作实体来操作数据库,所以首先要确定项目中的实体对象。在医药销售管理系统中,实体对象及关系如图1.6所示。图1.6 医药销售管理系统中的实体对象及其关系从图1.6中可以看到,药品实体对象为Medicine类,药品类别实体对象为Category类,销售明细实体为Se
12、llDetail类,操作用户实体为User类,这4个实体对象为医药销售管理系统的核心实体对象,它们所对应的映射文件均为“类名+hbm.xml”文件。其中,药品信息与药品类别为多对一关联关系,一个类别中包含多个药品对象;药品信息与销售明细为一对多关联关系,多个销售明细对应一个药品对象;销售明细与用户之间为多对多的关联关系,多个销售明细信息对应多个操作用户。3.4 定义ActionFormActionForm是简单的JavaBean,主要用来保存用户所输入的表单数据,Action要获取这些数据需要通过ActionForm对象进行传递。ActionForm对表单的数据进行了封装,在JSP页面与Act
13、ion对象中提供了交互访问的方法。在使用过程中,可通过继承org.apache.struts.action.ActionForm对象来创建需要的ActionForm对象,项目中所涉及到的ActionForm对象如图1.7所示。图1.7 项目中所涉及到的ActionForm对象3.5 持久层结构设计持久层结构通过Hibernate框架进行设计。由于Hibernate对不同对象的增、删、改、查等操作具有一定的共性,如添加数据使用save()方法、删除数据使用delete()方法等,项目中将这些具有共性的操作抽取出来,封装成一个类,其他数据库操作对象可继承此类来拥有这些方法,从而减少程序中的多余代码
14、,如图1.8所示。图1.8 持久层结构SupperDao类为所有数据库操作对象的父类,在此类中定义了对数据库进行操作的常用方法,具体方法及说明如表1.1所示。表1.1 SupperDao方法及说明方法说明save()用于保存一个对象saveOrUpdate()用于保存或更新一个对象delete(Object obj)用于删除一个对象,入口参数为Object类型findByHQL()通过HQL语句查询数据,入口参数为String类型的HQL语句deleteByHQL()通过HQL语句删除数据,入口参数为String类型的HQL语句uniqueResult()单值检索数据,入口参数hql为HQL查
15、询语句、where为查询条件findPaging()分页查询数据,入口参数hql为HQL查询语句、offset为结果集的起始位置、length为返回结果集的条目数、where为查询条件这些方法均为数据库操作的常用方法,所以将其封装在单独的一个类中,对于各个对象的数据库相关操作,可通过继承此类来获取这些常用方法。其子类对象有CategoryDao类、MedicineDao类、SellDao类、UserDao类,其功能分别介绍如下。CategoryDao类:药品类别数据库操作对象,用于封装与药品类别相关的数据库操作方法。MedicineDao类:药品信息数据库操作对象,用于封装与药品信息相关的数据
16、库操作方法。SellDao类:药品销售数据库操作对象,用于封装与药品销售相关的数据库操作方法。UserDao类:用户数据库操作对象,用于封装与管理员及系统相关的数据库操作方法。3.6 业务层结构设计业务层结构主要通过Struts框架进行设计,由Struts的中央控制器对各种操作请求进行控制,并通过相应的Action对其进行业务处理,项目中所用到的Action对象及关系如图1.9所示。图1.9 Action对象及关系Action、DispatchAction与LookUpDispatchAction为Struts封装的Action对象,具有不同的特点及作用,项目中通过继承这几个对象实现对不同业务
17、请求的处理。除这3个对象外,图1.9中其余的Action对象均为自定义的Action对象。在这些自定义的Action对象中,LanguageAction与LoginAction用于处理国际化语言及用户登录操作。由于二者不涉及过多的业务逻辑,它们都直接继承于Action对象。BaseAction对象与DeleteAction对象为重要的Action对象,二者都继承了DispatchAction对象。项目中封装这两个对象的目的在于简化程序中的业务逻辑、提高程序的安全性。在这两个对象中均对用户登录身份做出了严格的验证,其子类对象通过继承不必再考虑用户登录的安全问题,而更专注于业务逻辑,同时通过继承还
18、可以减少程序的代码量。其中BaseAction对象的子类及作用如表1.2所示。表1.2 BaseAction对象的子类及其作用子类作用SellAction封装药品销售的相关操作,处理封装药品销售请求SystemAction封装系统相关操作,处理系统级的请求CategoryAction封装药品类别相关操作,处理药品类别相关操作MedicineAction封装药品信息相关操作,处理封装药品信息的相关请求RequireAction封装药品需求及库存相关操作,处理药品需求相关请求DeleteAction对象继承了LookUpDispatchAction对象,此类通过重写getKeyMethodMap(
19、)方法对数据进行批量删除操作,其子类对象及其作用如表1.3所示。表1.3 DeleteAction对象的子类及其作用子类作用DeleteMedicineAction封装药品信息删除操作,用于批量删除药品信息DeleteReqMedAction封装药品需求信息删除操作,用于批量删除药品需求信息3.7 页面结构设计医药销售管理系统的页面结构采用框架进行设计,通过HTML语言中的标签及标签将页面分成3个部分,分别为页面头部、页面导航及内容页面,如图1.10所示。图1.10 页面布局此种布局方式将每一个页面单独置于一个框架之中,其中“页面头部”和“页面导航”在登录之后是固定不变的,对于用户的操作将在“
20、内容页面”显示结果。使用这种方式的有点在于:(1)避免了JSP页面中大量引用动作标签。(2)避免浏览器反复加载“页面头部”及“页面导航”等同样的内容,加快浏览器速度。4 配置文件在编写代码之前,需要做一些准备工作,如项目环境的搭建、项目所涉及到的第三方类库的支持、web.xml的配置等。在医药销售管理系统中,主要涉及到Struts框架、Hibernate框架及JFreeChart组件的应用,因此在项目开发之前,需要添加其类库支持。4.1 配置web.xmlweb.xml文件是Web项目的配置文件,在医药销售管理系统中,此文件需要配置Struts框架、JFreeChart组件和过滤器等信息。4.
21、2 配置struts-config.xmlStruts框架实现了MVC模式,web.xml和struts-config.xml文件是其两个重要的配置文件,其中web.xml文件实现了Struts的初始化加载,而struts-config.xml是它的核心配置文件。Struts-config.xml所做的工作比较多,包括ActionForm对象的定义、用户请求和Action之间的映射、异常处理等重要的配置。其中标签用于注册实例中所涉及到的ActionForm对象,标签用于设置全局跳转,标签配置用户请求Action对象的映射。4.3 配置hibernate.cfg.xmlHibernate.cfg
22、.xml文件是Hibernate的配置文件,在项目中,此文件配置了数据库的方言、数据库链接信息、自动建表属性和打印SQL语句等属性。5 实体及映射Hibernate是一个ORM产品,它完全可以操作对象的方式进行数据库操作,其实体对象与数据表之间通过映射文件建立映射关系。因此,在医药销售管理系统中需要建立实体对象与数据表之间的映射。5.1 药品实体映射药品实体对象的持久化类为Medicine类,此类封装了药品相关属性提供相应的getXX()和setXXX()方法。药品对象与药品类别对象为多对一关联关系,所以在Medicine类中加入了药品类别属性category,其关联关系通过映射文件Medic
23、ine.hbm.xml进行映射。映射文件Medicine.hbm.xml将实体对象Medicine映射为tb_medicine表,主键的生成策略采用自动生成方式。此映射文件中,对于数据表的部分字段还通过not-null、length、unique等属性映射字段的属性,其中not-null用于映射字段的非空属性、length用于映射字段的长度、unique用于映射字段是否唯一。映射后的数据表如图1.11所示。图1.11 tb_medicine表5.2 药品类别实体映射药品类别实体用于封装药品类别属性信息,其持久化类为Category类,与药品对象存在一对多关联关系。药品对象与药品类别对象为多对一
24、关联关系,但从药品类别一端来看,药品类别对象与药品对象又是一对多的关系,所以程序中采用了多对一双向关联进行映射。药品类别实体对象的映射文件为Category.hbm.xml。Category类所映射的数据表为tb_category,其中标签用于映射药品类别实体与药品实体间的一对多关联关系,此种映射方式将在药品数据表中添加categoryId字段。映射后的数据表tb_category如图1.12所示。图1.12 tb_categoy表5.3 销售明细实体映射销售明细用于描述药品销售时的具体情况,如销售时间、销售人员、销售数量等。这些信息十分重要,需要记录到数据库中,实例中将其封装为SellDet
25、ail类。为了方便查看销售明细的总额信息,在SellDetail类中加入了sellTotal()属性,此属性并不进行数据表的映射,它只有一个与之对应的get()方法,在此方法中通过单价与数量的运算对sellTotal进行赋值,并将其返回。销售明细实体的映射文件为SellDetail.hbm.xml,此映射文件中映射了两个多对一关联关系,分别为与药品对象的多对一关系及操作用户间的多对一关系。销售明细实体映射的数据表为tb_selldetail。在映射文件SellDetail.hbm.xml中,通过两个标签分别映射与药品对象及操作用户的多对一关联关系,并配置了级联操作类型为save-update。
26、映射后的数据表结构如图1.13所示。图1.13 tb_selldetail表5.4 用户实体映射在医药销售管理系统中,用户实体用于封装管理员的基本信息,如登录的用户名、密码等属性,其类名为User。User类中属性相对较少,其映射过程也相对简单。其映射文件为User.hbm.xml。用户实体所映射的数据表为tb_user,其结构如图1.14所示。图1.14 tb_user表6 公共类设计在Java程序开发中,如果一个功能反复被调用,则可将该功能抽取出来封装为一个类作为公共类,在需要此功能的地方通过此类进行实现。公共类实质是代码的重用的一种方式,在面向对象的开发模式中经常使用它来简化程序中的代码
27、,提高程序的可读性。下面是医药销售管理系统找那个的公共类设计。6.1 Hibernate过滤器在没有使用Spring管理Hibernate的情况下,对Hibernate的管理仍然存在一定的难度,特别是在J2EE开发中,线程安全、SessionFactory对象、Session对象、Hibernate缓存及延迟加载等是程序设计中的难题,管理不当将会对程序造成极为严重的影响。在医药销售管理系统中,将SessionFactory对象、Session对象置于过滤器中,由过滤器对其进行管理,从而解决了这些问题。在Web项目中,以普通方式使用Hibernate将无法解决Hibernate延迟加载,如图1.
28、15所示。当有一个业务请求查询数据时,首先要开启Session对象,然后Hibernate对数据进行查询。在关闭Session对象,最后通过JSP页面来显示数据。在这一过程中,如果查询数据时使用了延迟加载,当JSP页面显示数据信息时,Hibernate将抛出异常信息,因为此时Session对象已经关闭,Hibernate不能再对数据进行操作。开启Session查询数据(Lazy)关闭SessionJSP页面业务请求图1.15 普通方式通过过滤器管理Hibernate的Session对象则可以避免此问题,其实现过程如图1.16所示。业务请求Init()方法初始化SessionFactorydoF
29、ilter()过滤处理业务处理destroy()方法销毁SessionFactoryJSP页面SessinFactory关闭SessionResponseResponseRequestRequest图1.16 Hibernate过滤器在Web容器启动时,过滤器被初始化,它将执行init()方法,在后续的操作中不会再次被执行;而当容器关闭时,过滤器将执行destroy()方法。这两个方法恰好符合SessionFactory对象的生命周期,在运行期间只执行一次操作,可用于实例化及销毁SessionFactory对象。对于Session对象的关闭操作,可以在业务逻辑处理结束后、response请求转
30、发大View层之前进行。实例将其封装在HibernateFilter类中,此类继承了Filter类,它是一个过滤器。为了保证线程的安全性,实例中将Session对象存放与ThreadLocal对象中,当用到一个Session对象时,首先从ThreadLocal中获取,在无法获取的情况下才会开启一个新的Session对象。同时,为了保证Session对象能在resopnse请求转发到View层之前被关闭,实例采取了tryfinally语句对Session对象进行关闭。6.2 SupperDao类SupperDao类为项目中所有数据库操作类的父类,此类封装了数据库操作的常用方法。在此类中,由于Hi
31、bernate对数据的操作都需要用到Session接口,类中定义了一个protected类型的Session对象,为其子类提供了方便。save()方法及savaOrUpdate()方法都用于保存一个对象,其入口参数均为Object类型。其中saveOrUpdate()方法比save()方法更智能一些,可以根据实体对象中的标识值来判断保存还是更新操作。SupperDao类中使用这两个方法对实体对象进行保存及更新操作。删除操作的方法为delete(),入口参数为Object类型,此方法通过Session接口的delete()方法进行实现。SupperDao类为项目中所有数据库操作类的父类,在设计时
32、应当考虑全面。Hibernate的HQL查询语言提供了更为灵活的查询方式,在这个超类之中应该加入HQL的操作方法,其中findByHQL()方法用于根据指定的HQL查询语句查询结果集,deleteByHQL()方法用于根据指定的HQL查询语句进行删除操作。Hibernate单值检索在查询后返回单个对象,当返回的结果包含多条数据时,Hibernate将抛出异常。此种操作可用于查询单条数据,如聚合函数count()等。在SupperDao类中,单值检索的方法为uniqueResult()。此方法的入口参数为HQL查询语句及查询条件,其中查询条件为Object数组类型,用于装载查询语句中的参数。例如
33、HQL语句“from Medicine m where m.id=?”,此时即可通过参数where对其进行动态赋值。分页查询在程序开发中经常用到,不但方便查看,还可以减少结果集的返回数量,提高数据访问效率。使用Hibernate的分页查询方法极为简单,只需要传入几个参数即可,但在SupperDao类中对其进行了扩展,加入了HQL语句的动态赋值,其方法名为findPaging()。此方法入口参数有4个,其中参数hql为HQL查询语句,它允许传入参数中带有占位符“?”的HQL语句;参数offset为查询结果集对象的起始位置;参数length为查询结果的偏移量,也是返回数据的条目数;参数where为
34、查询条件,属于Object数组类型,用于装载HQL语句中的参数。通过上述这几个参数基本可以满足项目中所有的分页查询,当然遇到特殊情况时,可以通过子类对象重写此方法。6.3 BaseAction类BaseAction类是业务层,有一个超类对象,它继承了Struts的DispatchAction类,同时还为子类对象提供公用方法。此类首先定义了3个protected类型的变量,分别用于设置每页的记录数、本地语言信息及国际化消息资源。Struts的DispatchAction类继承了Action类,此类处理请求时首先要执行execute()方法,然后通过控制器再转发到相应的方法进行业务处理。根据这一分
35、析,可以在execute()方法中对用户的身份作出验证,其实现过程如图1.17所示。业务请求一业务请求三业务请求二业务请求四业务处理二业务处理三业务处理一业务处理四Execute()方法验证用户身份错误处理验证失败验证成功验证成功图1.17 用户身份验证如果对系统中涉及到的Action均编写一个验证方法,则程序代码的重复性太高,不能体现出面向对象的设计模式,所以需将其单独封装在BaseAction类中,此类通过重写Action类的execute()方法对用户身份进行验证。由于分页查询的应用比较多,所以在业务层将其封装在BaseAction类中,通过getPage()方法进行实现,子类对象可以通
36、过继承来获取此方法。getPage()方法返回一个Map集合对象,该集合用于装载结果集及分页条。其中,结果集对象为一页中的所有数据集合,它是一个List对象;分页条为分页查询后在JSP页面所显示的分页信息,如记录数、页码、上一页、下一页的超链接等,它是一个String类型的字符串。 getPage()方法的入口参数有四个,其中参数hql为分页查询的HQL语句,此语句不可以包括select子句,它从from子句开始,可以传入带有占位符的HQL,但需要通过查询条件参数where传递占位符的值,当HQL语句没有参数时,where参数可以设置为null;参数recPerPage为每一页的记录数;cur
37、rPage为当前的页码;action为分页所请求的Action地址。getPage()方法提供这些参数的目的在于提高程序代码的重用性,因为在医药销售管理系统中,通过这些参数,getPage()方法已满足所有的分页查询,用到分页查询的地方都调用了此方法。此外,在其他项目中此方法的重用价值也是非常高的。分页查询在业务层的实现比较繁琐,因为在分页条中要考虑到国际化的实现,所以在分页条中所有文字信息均通过MessageResources对象读取国际化资源文件来获取。MessageResources对象是Struts中的对象,此对象根据Locale信息读取相应的国际化消息资源文件。6.4 DeleteA
38、ction类公共类DeleteAction主要用于对项目中LookupDispatchAction的请求进行处理。它继承了LookupDispatchAction类,重写了execute()方法对用户的身份作出验证,当用户身份验证失败时将进行错误处理;同时,此类还重写了LookupDispatchAction类中的getKeyMethodMap()方法,添加了两个按钮对象的key。6.5 字符串工具类在一个Web项目中,字符串是经常被操作的对象。为了简化程序的代码及提高程序的可读性,对于经常用到的字符串处理方法,可以封装一个字符串工具类对其进行操作。例如JSP页面的多选框,它提交的参数值为数组
39、类型,在数据库的操作过程中需要将其转换为字符串类型;在超链接中,如果加入中文参数将不能被浏览器解析,需要对其进行一定的处理才可以使用。类似于这种操作在程序中使用的非常频繁,将其封装为一个公共类无疑是一种较好的解决方案。在医药销售管理系统中,封装了一个名为StringUtil的字符串工具类,用于对字符的特殊处理。此类中均为静态方法。在HQL语句中,如果删除多个对象可以使用where id in(1,2,3)的方式进行删除。arr2Str()方法用于将数组转换为字符串,可以将JSP表单传递id值转换为此种方式;encodeURL()方法可对字符串进行URL编码,主要用于对含有中文的超链接进行处理;
40、encodeZh()方法用于对字符串中的中文乱码进行处理。7 国际化国际化是Struts的一项强大功能,它以不同国家的语言构建本地化的页面,方便不同国家、不同语言的用户浏览访问。在医药销售管理系统中,分别构建了中文和英文两种语言环境,根据使用者浏览器的默认语言环境呈现不同的语言显示方式。7.1 国际化资源文件医药销售管理系统对所有涉及到语言信息的地方均进行了国际化设置,包括JSP页面文字信息及JS脚本提示信息等。主要包含3个国际化资源文件,其中属性文件为MessageResources.properties为默认的资源文件,实例中将其设置为中文;属性文件MessageResources_en_
41、US.properties为英文国际化资源文件;MessageResources_zh_CN.properties为中文国际化资源文件。在编写属性文件时应该注意,属性文件以Unicode编码,在处理中文时应该对其进行转码。Java提供了将中文转换为Unicode编码格式的工具,在命令窗口中直接输入“native2ascii”,再输入中文,然后按回车键,将输出中文对应的Unicode码。7.2 国际化实现实例中除了对用户浏览器语言的自动匹配外,还为使用者提供了中文和英文的语言链接,用户在使用过程中可对语言进行自动切换。此请求由LanguageAction类进行处理。本地语言信息存放在Sessio
42、n会话中的Globals.LOCALE_KEY值中,它是Struts的默认配置,可以通过Strtus的API帮助文档和源码得到。对于中、英文两种请求,实例中分别创建了中、英文所对应的Locale对象,并将其设置到Globals.LOCALE_KEY值中,实现了语言的自动切换。8 系统登陆模块系统登录是一个用户身份验证的过程,只有登录成功的用户才可以对系统进行操作,否则不能对系统进行管理维护。形象地说,它就是系统的一道安全门。8.1 查询用户创建名为UserDao的类,封装对用户及系统级的数据操作。在此类中编写login()方法,用于根据用户名及密码查询用户对象。在用户登录的过程中,需要判断数据
43、库用户对象是否存在,当用户提交登录信息时,调用此方法可返回查询后的用户对象,如果查询不到将返回null值。8.2 登陆请求用户登录请求由LoginAction类进行处理,此类继承了Action对象,它重写execute()方法对用户登录请求进行验证。UserForm对象为用户ActionForm对象,Struts自动将JSP页面表单信息封装在此对象中,所以可以直接获取ActionForm对象中的属性信息。LoginAction类通过UserForm中的用户名和密码属性,调用UserDao对象中的login()方法对用户信息进行查询,当数据库中存在与之匹配的数据,则登录成功,否则登录失败。8.3
44、 登录页面在Web文件夹的根目录中创建login.jsp文件,即系统中的用户登录页面,在其中放置用户登录的表单。在此页面中,首先通过标签判断是否存在error值,如果存在即表示用户登录发生错误,将在登录页面显示错误信息。Login.jsp页面运行结果如图1.21所示。图1.21 系统登录页面9 药品类别信息管理药品超市经营的药品众多,为方便产看、统计,需要对其进行分类。药品类别信息管理模块主要是对药品类别信息进行统一管理,其中包括对药品类别的添加、查看、统计等操作。9.1 药品类别持久层设计CategoryDao类是药品类别的数据库操作类,它继承了SupperDao类,提供对药品类别的数据库操
45、作方法。其中loadCategory()方法用于查询指定id的药品类别信息,其入口参数为int型药品id。在添加药品信息时,需要添加与之对应的类别信息,所以还需要提供一个查询所有药品类别信息的方法findAllCategory()。为方便药品类别数据的统计,实例中对药品类别中药品的数量进行统计的操作被定义在findCategoryAndCount(),由HQL语句的内连接查询进行实现。findCategoryAndCount()方法中的hql属性为内连接查询语句,可对药品数量按药品类别进行分组统计,查询后返回其结果集对象。9.2 药品类别的添加药品类别的添加是指将药品类别信息写入数据库,实现过
46、程如下。9.2.1 类别添加、修改请求处理实例中将药品类别的相关请求封装在CategoryAction类中,此类继承了BaseAction对象,所以在对类别信息进行处理时,不必考虑用户是否登录的安全问题。此类中处理添加类别信息请求的方法为add(),由于CategoryAction类是一个DispatchAction对象,所以当请求的参数为add时,将由此方法进行处理。此方法调用了CategoryDao对象的saveOrUpdate()方法,所以药品类别信息的添加与修改操作均可通过此方法进行实现;当传递的CategoryForm对象含有id值时,则进行修改操作。9.2.2 类别添加页面类别添加页面即category_add.jsp文件,此页面中主要放置了类别添加的表单。此页面中使用Struts的标签设置药品类别的id属性值,如果此属性不为空,则意味着操作为修改操作。类别添加页面运行结果如图1.22所示。图1.22 类别添加页面9.3 分页查看类别信息在添加药品信息后,系统将跳转到类别信息列表页面。在此页面中将对类别信息进行分页显示,