Versant数据库实验
Versant是面向对象数据库,本文主要做了一个关于瑞士军刀的数据库。
实验环境Versant+JSP+Tomcat
所有类如下图:
增加配件(Accessories)页面如下:
addAccessories.jsp代码如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <%@ page contentType="text/html;Charset=gb2312"%>
2 <%@ page import="com.versant.trans.*" %>
3 <%@ page import="versant.*" %>
4 <%@ page import="java.util.*" %>
5 <%
6 String classtype=request.getParameter("classtype");
7 String name=request.getParameter("name");
8 if(name!=null){
9 ToVersant toversant=new ToVersant();
10 int model=Integer.parseInt(request.getParameter("model"));
11 int length=Integer.parseInt(request.getParameter("length"));//长度
12 int width=Integer.parseInt(request.getParameter("width"));//宽度
13 int thickness=Integer.parseInt(request.getParameter("thickness"));//厚度
14 int hardness;//硬度
15 int mouth;//开口
16 String stringtype;//螺纹
17 Size size=new Size(length,width,thickness);//尺寸
18 if(classtype.equals("Knife")){
19 hardness=Integer.parseInt(request.getParameter("hardness"));
20 Knife knife=new Knife( model, name, size, hardness);
21 toversant.session.makePersistent(knife);
22 }
23 else if(classtype.equals("Saw")){
24 hardness=Integer.parseInt(request.getParameter("hardness"));
25 Saw saw=new Saw( model, name, size, hardness);
26 toversant.session.makePersistent(saw);
27 }
28 else if(classtype.equals("SteelFile")){
29 hardness=Integer.parseInt(request.getParameter("hardness"));
30 SteelFile steelfile=new SteelFile( model, name, size, hardness);
31 toversant.session.makePersistent(steelfile);
32 }
33 else if(classtype.equals("Tweezers")){
34 mouth=Integer.parseInt(request.getParameter("mouth"));
35 Tweezers tweezers=new Tweezers( model, name, size, mouth);
36 toversant.session.makePersistent(tweezers);
37 }
38 else if(classtype.equals("ScrewDriver")){
39 Boolean type=false;
40 stringtype=request.getParameter("type");
41 if(stringtype.equals("正")){
42 type=true;
43 }
44 ScrewDriver screwdriver=new ScrewDriver( model, name, size, type);
45 toversant.session.makePersistent(screwdriver);
46 }
47 else if(classtype.equals("BottleOpener")){
48 BottleOpener bottleopener=new BottleOpener( model, name, size);
49 toversant.session.makePersistent(bottleopener);
50 }
51 else if(classtype.equals("WineOpener")){
52 WineOpener wineopener=new WineOpener( model, name, size);
53 toversant.session.makePersistent(wineopener);
54 }
55 else if(classtype.equals("Scissor")){
56 int leftmodel=Integer.parseInt(request.getParameter("leftmodel"));
57 int rightmodel=Integer.parseInt(request.getParameter("rightmodel"));
58 mouth=Integer.parseInt(request.getParameter("mouth"));
59 Knife left,right;
60 Enumeration e=toversant.queryResult("select selfoid from versant.Knife where model="+leftmodel);
61 left=(Knife)e.nextElement();
62 e=toversant.queryResult("select selfoid from versant.Knife where model="+rightmodel);
63 right=(Knife)e.nextElement();
64 Scissor scissor=new Scissor( model, name, size, left, right, mouth);
65 toversant.session.makePersistent(scissor);
66 }
67 toversant.endSession();
68 }
69 %>
70 <html>
71 <head>
72 <title>增加Accessories对象</title>
73 </head>
74 <body>
75 <table align="center" width="300" cellSpacing="1" cellPadding="1" border="0">
76 <tr>
77 <td><a href="delete.jsp">删除</td>
78 <td><a href="updatemain.jsp">修改</td>
79 <td><a href="query.jsp">查询</td>
80 <td><a href="main.jsp">主页 </td>
81 <td><a href="addmain.jsp">返回 </td>
82 </tr>
83 </table>
84 <form action="addAccessories.jsp" method="post" >
85 <table align="center" width="300" cellSpacing="1" cellPadding="1" border="0">
86 <tr><td>类型:</td><td><input type=text name="classtype" value=<%=classtype%>></td></tr>
87 <tr><td>型号:</td><td><input type=text name="model"></td></tr>
88 <tr><td>名称:</td><td><input type=text name="name"></td></tr>
89 <tr><td>尺寸(长):</td><td><input type=text name=length></td></tr>
90 <tr><td>尺寸(宽):</td><td><input type=text name=width></td></tr>
91 <tr><td>尺寸(厚):</td><td><input type=text name=thickness></td></tr>
92 <%
93 if(classtype.equals("Scissor")){
94 out.println("<tr><td>左刀型号:</td><td><input type=text name=leftmodel></td></tr>");
95 out.println("<tr><td>右刀型号:</td><td><input type=text name=rightmodel></td></tr>");
96 out.println("<tr><td>开口:</td><td><input type=text name=mouth></td></tr>");
97 }
98 else{
99 if(classtype.equals("Knife")||classtype.equals("Saw")||classtype.equals("SteelFile")){
100 out.println("<tr><td>硬度:</td><td><input type=text name=hardness></td></tr>");
101 }
102 if(classtype.equals("Tweezers")){
103 out.println("<tr><td>开口:</td><td><input type=text name=mouth></td></tr>");
104 }
105 if(classtype.equals("ScrewDriver")){
106 out.println("<tr><td>螺纹(一/十):</td><td><input type=text name=type></td></tr>");
107 }
108 }
109 %>
110 <tr><input type="submit" value="增加"></tr>
111 </table>
112 </form>
113 </body>
114 </html>
query.jsp代码如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <%@ page contentType="text/html;Charset=gb2312"%>
2 <%@ page import="com.versant.trans.*" %>
3 <%@ page import="versant.*" %>
4 <%@ page import="java.util.*" %>
5 <%
6 String classtype=request.getParameter("classtype");
7 ToVersant toversant=new ToVersant();
8 %>
9 <html>
10 <head>
11 <title>查询</title>
12 </head>
13 <body>
14 <table align="center" width="300" cellSpacing="1" cellPadding="1" border="0">
15 <tr>
16 <td><a href="addmain.jsp">增加</td>
17 <td><a href="delete.jsp">删除</td>
18 <td><a href="updatemain.jsp">修改</td>
19 <td><a href="main.jsp">主页</td>
20 </tr>
21 </table>
22 <form action="query.jsp" method="post" >
23 <table align="center" width="300" cellSpacing="0" cellPadding="0" border="1">
24 <tr><td><select name="classtype">
25 <option value="versant.Accessories" >配件 </option>
26 <option value="versant.BottleOpener">开瓶器 </option>
27 <option value="versant.Knife">刀 </option>
28 <option value="versant.Saw">锯子 </option>
29 <option value="versant.Scissor">剪刀 </option>
30 <option value="versant.ScrewDriver">螺丝刀 </option>
31 <option value="versant.SteelFile">钢锉 </option>
32 <option value="versant.Tweezers">镊子 </option>
33 <option value="versant.WineOpener">红酒开瓶器 </option>
34 </select></td><td></td>
35 <td><input type="submit" value="查询"></td></tr>
36 <tr><td>型号</td><td>名称</td><td>尺寸</td></tr>
37 <%
38 if(classtype!=null){
39 String querystring="select selfoid from "+classtype;
40 Enumeration e=toversant.queryResult(querystring);
41 while (e.hasMoreElements()){
42 out.println(e.nextElement());
43 }
44 }
45 toversant.endSession();
46 %>
47 </table>
48 </form>
49 </body>
50 </html>
由于时间原因东西做的很简陋,有很多地方都逃避实现了。
实验总结
首先在这次实验过程中学到了很多新的东西,具体包括Jsp+tomcat+Versant环境的搭建,Versant数据库的使用以及Jsp,这些以前都是没接触过的。
在实验过程中碰到很多问题也解决了一些,但还有一些问题没解决。
1没有把修改和删除按钮捆绑到查询界面里,因为在查询过程中,可以选择类型进行查询,不同的类具有不同的属性,为了偷懒,不论查询的类是什么,我只输出了他们基类Accessories的属性,一种较笨的改进方法是根据查询类别编写不同的查询输出页面。但是这样代码复杂度很高,而且一旦在瑞士军刀里面增加了新的配件子类,就必须修改jsp页面。也就是说没有实现多态查询。
我也想过实现多态查询,具体方法是在基类里新建一个整体属性输出方法:
public string showData(){
return "<tr><td>"+属性1+</td><td>....
}
然后每个子类对该方法进行重载。问题是versant查询语句返回的结果是放到Enumeration接口里的
String querystring="select selfoid from "+classtype;//classtype是下拉单选择的类的名字
Enumeration e=toversant.queryResult(querystring);
而Enumeration接口是通过E e.nextElement()方法返回一个个对象的,但是这里须指定类进行类型强制转换。
因为如果不转换到对应类型,那就无法调用对应类型的showData()方法,悲剧的地方就在这里。
但是这里我发现了一个另类,就是重写toString()方法,其方法实现功能同showData()。
发现这样可以在对象不进行类型转换的条件下就能调用对应类的toString()。
我的实验就是这么做的。
但是这个多态有个缺点,比如我查询配件Accessories。
输出的属性就无法统一,例如
1 2
1 2 3 4
1 2 4
不同的实例有不同的属性,这里调用的toString是各个子类的,而不是他们作为基类Accessories的方法。
也就是说还是需要对对象进行强制转化,这样才能让对象以你所喜欢的类型出现。那么该怎么办呢。
唯一可以利用的就是开始通过下拉菜单指定了要查询的类的名字。
于是我想到了反射,根据类的名字可以找到类,但是对反射不熟悉,折腾了很久还是不知道怎么用反射对对象类型进行强制转化
Freeze在这里希望各位高人能够指导下,不甚感激。
2删除对象页面里面,即需要指定对象类型,又需要输入对象型号即ID。这是不合理的。
因为事实上对象类型已经隐含在对象型号里了,对象型号比如11(型号是int),头一个数字就指定了对象的类型。
解决方法获得型号的第一个数字,在基类Accessories里建立一个方法,这个方法可以输入数字并返回对应类的名字。
最后罗列一下Versant数据库在B/S模式下碰到的一些状况
1查询语句里面最好不要有字符串的比较
必如数据库里有String name 那么查询语句是select selfoid from databasename name=findname
这么是错的,无法找到数据,select selfoid from databasename name.equals(findname)也不行,悲剧啊
2Accessories是基类
Accessories-》Knife-》Saw (被继承-》继承)
发现在jsp里面,Accessories不可见但Knife可见(类都已经导入了)
刚开始怀疑Accessories是基类所以不可见,但是后来发现Knife也是基类但却可见。
3文中提到的多态查询问题
4安装目录下面Versant Tools/Object inspector可以查看数据库里的内容
...
其它的问题都可以在Versant文档里面找到,这里就不说了