摘 要 这篇文章研究了在校园网环境下合理利用原有异构数据库建立相关的部门管理系统的方法,介绍了基于WebLogic应用服务器进行教材综合管理系统的设计和实现的过程。
关键词 数据库;J2EE; EJB;WebLogic
引 言
随着科学技术的不断提高,计算机网络的功能已为人们深刻认识,它已进入人类社会的各个领域并发挥着越来越重要的作用。同样各类学校的校园网也运行了多个年头,但还有不少学校的管理系统缺少统一规划,单机运行的信息孤岛还为数不少,所以有必要进一步研究在校园网环境下合理利用原有异构数据库建立相关部门的管理系统的方法。
在某高校中教务和教材仓库都已经有了各自独立的数据库管理系统,但教材选订等工作都是人工进行,工作人员的劳动量,效率很低。校园网环境下利用现有的资源建立教材综合管理系统之必要性是不言而喻的!本文介绍基于WebLogic应用服务器进行教材综合管理系统的设计和实现的过程。
系统结构
系统包含教材选取、查询、修改、订购子系统,系统所需的教务信息和教材库存信息来自网上原有数据库,如图1所示。其中,教研室通过B/S模式可以进行教材选取、查询、修改等工作,教材管理在教材委员会通过C/S模式本地完成,主要是教材订购及系统管理工作。
列名 | 数据类型 | 长度 | 允许为空 |
id | Bigint | 8 | 否 |
num | int | 4 | 是 |
列名 | 数据类型 | 长度 | 允许为空 |
id | Bigint | 8 | 否 |
cid | Int | 4 | 否 |
cname | Varchar | 50 | 是 |
teachunit | Varchar | 50 | 是 |
sname | Varchar | 50 | 是 |
列名 | 数据类型 | 长度 | 允许为空 |
bid | Int | 4 | 否 |
bname | Varchar | 50 | 是 |
bnote | Varchar | 50 | 是 |
bauthor | Varchar | 50 | 是 |
bpublisher | Varchar | 50 | 是 |
bprice | Float | 8 | 是 |
bnum | Int | 4 | 是 |
列名 | 数据类型 | 长度 | 允许为空 |
cid | Int | 4 | 否 |
bid | Int | 4 | 是 |
cname | Varchar | 50 | 是 |
bname | Varchar | 50 | 是 |
teachunit | Varchar | 50 | 是 |
列名 | 数据类型 | 长度 | 允许为空 |
id | Bigint | 8 | 否 |
bname | Varchar | 50 | 是 |
numneed | Int | 4 | 是 |
列名 | 数据类型 | 长度 | 允许为空 |
teachunit | Varchar | 50 | 否 |
pw | Char | 10 | 是 |
图2 连接池配置 |
图3 数据源配置 |
3、建立实体EJB
系统要对三个异地数据库共六张表,进行操作,因此要逐个引进并建立相应的实体Bean,这里将三个数据库中本系统要用到的的表都引进到同一个EJB Module中。
在JBuilder中生成的实体Bean中会自动识别并生成对应表的名称,数据段的名称、属性,根据程序员设置的本地或远程的home接口文件,封装了操作数据库的基本动作,如通过主键查找记录的功能,在查找到的记录中得到和设置数据项的函数等,为了后面子系统的需要还要添加一些函数:
在课程安排表Entity Bean中添加两个Finder:
一个finder名为findall,功能是得到教务数据库课程安排表的所有信息。将要在往选教材表中写入所有课程信息时使用。
另一个名为findbycid,功能是根据输入的课程信息找到选了这些课程的专业。
在选教材表中添加两个Finder:
一个名为findall,为了得到所有的选教材表的信息。
另一个名为findbybid,功能是得到输入教材号所对应的专业好。
在Baobiao中添加一个Finder为 findall,得到所有订单表里的信息。
这样就完成了本系统实体bean的建立。
4、建立会话EJB
使用会话bean 可对某一客户的处理或控制对象建模,对工作流、任务和管理活动等建模,协调多个实体bean,控制实体bean之间的交互将业务应用逻辑从客户端转移到服务器端,本系统考虑到数据不是特别庞大。仅用了具有远程接口的一个无状态会话EJB(connectEJBs)完成所有与实体EJB打交道的任务。
为了系统功能的需要,在其中添加了6个私有变量,6个公有变量,初始化后用以访问六张表对应的实体EJB。初始化代码为:
try{ Context context=new InitialContext(); Object ref=context.lookup("java:/comp/env/Coursearrangement"); crthome=(CoursearrangementHome) ref; ref=context.lookup("java:/comp/env/Xk"); xkhome=(XkHome) ref; ref=context.lookup("java:/comp/env/Tp"); tphome=(TpHome) ref; ref=context.lookup("java:/comp/env/Number"); numberhome=(NumberHome) ref; ref=context.lookup("java:/comp/env/Ck"); ckhome=(CkHome) ref; ref=context.lookup("java:/comp/env/Baobiao"); baobiaohome=(BaobiaoHome) ref; }catch(Exception e){e.printStackTrace();} |
这样就能通过会话EJB的远程接口访问实体EJB里自动生成的和自己添加的方法或函数了,前提是这个方法或函数包含在实体EJB的home接口里。
还添加了一些本地公有函数和多个远程公有函数,用来修改或访问实体EJB并作初步的处理。增加的函数必须在JBuilder中先右击代表会话Bean的图形添加方法(add method),设置各项参数后方可右击会话Bean选择View Bean Sourse菜单,进入代码区编辑方法主体,否则工程将产生编译错误。这里提供了整个系统所需的与数据库打交道的函数,这些接口在后文中都有用到。
3个本地公有函数:为了解决不能连续在同一个函数里多次写入信息而独立出来的函数
①public void writecidcname(Integer cid, String cname, String teachunit)
这是往选教材表写课程信息。
②public void writebook(Integer bid, String bname)
这时保教材信息写入订单表。
③public void writealltp(String unit, String pw)
同理,为了往密码表里写入密码信息而编写。
远程公有函数:以下的函数是订单子系统要用到的接口
⑴public java.util.Collection couinfo()
这个函数是负责从教务处得到开设课程的信息。返回值是Collection对象。
⑵public boolean writexk(java.util.Collection rst)
这个函数在运行订单子系统自动调用。它负责在初始化系统时将从教务处得到的课程信息写进选教材表中,保证既使新增了新的教研室也能实时地获得。它的参数就是函数zhuanyi()的返回值,在程序主体调用了本地函数①。
⑶public java.util.Collection selectunit()
这个函数是为了从选教材表中得到所有开设了课程的教研室的名称。既为了在B/S的登录界面上得到教研室名下拉框的需要,又为了在密码表中得到教研室名而编写。注意这里有重复信息,需要再调用它的函数中过滤掉。
⑷public boolean writetp(Collection rst, String pw)
这是为了建立教研室密码表而编写,在函数⑵后调用,当表中没有教研室或是有了新的教研室的时候,它会自动加到密码表中并分配原始密码。是教员能登陆再现的教材录入子系统。
⑸public boolean reflushbaobiao()
这是C/S界面用户刷新订单信息时,将选教材表中的已经选了的教材信息写进订单表中。它在获得相应教材应定的数量之前调用。
●这以下是为了获得订单中所需要订购的书的数目而写的函数,因为不能在一个函数中操作多个数据库,所以用了下面多个函数以实现。
得到订单表里所有的教材号:
public Collection readbaobiaoforgetnum() |
从选教材表中得到已经选好的课本对应的课程号:
public Integer readxkforgetnum(Integer bid) |
再从教务处课程安排表中得到开了这个课程号所代表的课程的专业,可能不止一个:
public Collection readcouforgetnum(Integer cid) |
然后从教务处人数表中查到这些专业的人数:
public Integer readnumforgetnum(Long id) |
再找出仓库里这本书的库存量,如果所需数量大于库存量,就要在订单中显示出定购量:
public Integer readckforgetnum(Integer bid, int numall) |
○●○此以下的函数为教员在线教材选取和相关单位查询要用到的函数。
⑴public String login(String unit)
这在用户登陆时系统检查密码是否匹配时使用,就是根据用户名查询到相应的密码并返回。在用户修改密码时验证是否为登陆用户也用到了它。
⑵public String login(String unit)
这个函数从名字得知,是用户登陆时系统检查密码是否匹配时使用的,就是根据用户名查询到相应的密码并返回。在用户修改密码时验证是否为登陆用户也用到了它。
⑶public boolean writein(Integer cid, Integer bid, String name)
这个函数是用户填写了课程信息后将这些信息写入到相应的数据库记录中。
⑷public boolean setpw(String unit, String pw)
此函数在用户修改密码时使用的。
⑸public boolean isbooksame(Integer bid)
此函数是用户填写教材信息是否重复输入,或是输入了别的课程已经选取的教材时判断用的,防止数据库主键重复插入。
⑹public Object getbidname(Integer cid)
这是为了教研室查询已选教材准备的接口,为选取教材提供参考。
5、订单子系统
为了实现教材委员会对整个教材选取系统的控制,得到教材订单报表,本系统在 C/S端达到上述目的。它是不发布的,是教材委员会的本地客户端,其中的订单界面如图4。
图4 订单子系统中的订单界面 |
conhome= (connectEJBsHome) PortableRemoteObject.narrow(ref, connectEJBsHome.class); try { con=conhome.create(); if(con.writexk(con.zhuanyi())) { System.err.print("你已成功转移了数据!"); } }catch(Exception ex) { ex.printStackTrace(); System.err.print("数据转移失败!"); } |
try { con=conhome.create(); if(con.writetp(con.zhuanyi(),”888888”) { System.err.print("密码分配成功!"); } }catch(Exception ex) { ex.printStackTrace(); System.err.print("密码分配失败!"); } |
conhome= (connectEJBsHome) PortableRemoteObject.narrow(ref, connectEJBsHome.class); try { con=conhome.create(); if(con.writebaobiao()) { System.err.print("得到报表数据!"); if(this.getnum()) { System.err.print("取到了书的数目!"); } } } catch(Exception ex) { ex.printStackTrace(); System.err.print("生成报表失败!"); } |
图5教材选取系统的选取界面 |