一个双实体多对多关系的操作
2007-07-14 16:00
183 查看
在蓝色理想看到了这样一个帖子:
http://bbs.blueidea.com/thread-2768623-1-1.html
他提出了一个问题,就是一个双实体以及其多对多关系的显示问题,原题如下:
一共三个表..
表一(student)
id name
1 A
2 B
3 C
表二(teacher)
id teachername
1 张三
2 李四
3 王五
表三(studenttoteacher)
id studentid teacherid
1 1 1
2 1 2
3 1 3
4 2 1
5 2 3
6 3 2
7 3 3
表三第一二三条记录表示的意思是学生ID为1的学生有三个老师 ID分别是1 2 3,依此类推
输入结果要求如下图..学生老师要求可以再添加
问题抽象其实是这样的
有三个表,分别是实体A、实体B以及两个实体之间的多对多关系,现在的需求是,显示一个html表格,要求在这个表格里面显示两实体之间各记录是否有对应的关系。并且这里面的实体,是可以动态的添加的。
而我的思路是这样的,首先取出两实体A、B的名称,同时获得其条目数,而后定义一个二维数组,用于以矩阵的形式存放二者的关系,而后再进行显示。
我给出的代码如下:
<%
Option Explicit
Dim sConn,oConn,sSql,oRs,i,j
Dim aSet,lRowCount,lColCount,aStudents,aTeachers
Dim lLastID
sConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("source.mdb")
Set oConn = Server.CreateObject("ADODB.Connection")
Set oRs = Server.CreateObject("ADODB.RecordSet")
oConn.Open sConn
'学生部分记录
sSql = "SELECT * FROM [student]"
oRs.Open sSql,oConn,1,1
lLastID = 0
While Not oRs.Eof
For i = 1 To (oRs("id")-lLastID)
aStudents = aStudents & ","
Next
aStudents = aStudents & oRs("name")
lLastID = oRs("id")
oRs.MoveNext
Wend
oRs.MoveLast
lColCount = oRs("id")
oRs.Close
'教师部分记录
sSql = "SELECT * FROM [teacher]"
oRs.Open sSql,oConn,1,1
lLastID = 0
While Not oRs.Eof
For i = 1 To (oRs("id")-lLastID)
aTeachers = aTeachers & ","
Next
aTeachers = aTeachers & oRs("name")
lLastID = oRs("id")
oRs.MoveNext
Wend
oRs.MoveLast
lRowCount = oRs("id")
oRs.Close
'字符恢复为数组
aStudents = Split(aStudents,",")
aTeachers = Split(aTeachers,",")
'获得关系集合数组
ReDim aSet(lColCount,lRowCount)
sSql = "SELECT * FROM [studenttoteacher]"
oRs.Open sSql,oConn
While Not oRs.Eof
aSet(oRs("studentid"),oRs("teacherid")) = "ok"
oRs.MoveNext
Wend
oRs.Close
Set oRs = Nothing
%>
<table border="1">
<!--首行输出教师名称-->
<tr>
<th width="50"> </th>
<%For i = 1 To UBound(aTeachers)%>
<%If aTeachers(i) <> "" Then%>
<th width="50"><%=aTeachers(i)%></th>
<%End If%>
<%Next%>
</tr>
<!--依次输出每个学生的行-->
<%For i = 1 To UBound(aStudents)%>
<tr>
<th width="50"><%=aStudents(i)%></th>
<%For j = 1 To UBound(aTeachers)%>
<%If aTeachers(j) <> "" Then%>
<td align="center">
<%
If aSet(i,j)="ok" Then
Response.Write "√"
Else
Response.Write " "
End If
%>
</td>
<%End If%>
<%Next%>
</tr>
<%Next%>
<%
oRs.Close
Set oRs = Nothing
oConn.Close
Set oConn = Nothing%>
</table>
这里面有两个难点:
第一,效率问题。如果不考虑效率问题,那么我们蛮可以使用循环嵌套,外部循环所有的实体A,内部循环实体B,在内部循环中打开记录集查询关系表中是否有A和B当前条目的对应关系,但是这样的效率太低了,我们需要的记录集查询次数就是A条目数*B条目数+2,如果A和B都很多的话,那么将是一个恐怖的查询。
那么我们解决的方法就是将关系表中的记录全部一次取出,并放在二维数组矩阵中,假如当前第N行第M列有关系,那么设定此成员的值为"ok"。而后在表格的显示中判断当前行列的元素的值是否为"ok"就可以判断当前位置的元素是否应当显示"√"以表示是否有关系了。
第二,动态添加问题。其实这里的添加不仅仅指添加,他主要解决的是数据库内元素的变动问题,设想,假如我删除了某一个实体中的某一条记录,那么此时不加以处理的话,数组就会乱套而无法判定当前行列的记录是否是数据库中指定id的记录,因此我采用了这样的代码:
For i = 1 To (oRs("id")-lLastID)
aTeachers = aTeachers & ","
Next
aTeachers = aTeachers & oRs("name")
lLastID = oRs("id")
oRs.MoveNext
来保持数组中的次序和id保持完全的一致。因为考虑到数据库中数据可能有删除导致id不连续的情况
aSet数组中的下标对应的是id
而aStudents和aTeachers数组的下标对应的是记录在数据库中是第几个,如果中间你删除了student或者teacher的记录,那么这个序号就不对应了,因此我用那个方法,使得aStudents和aTeachers保证对应的是id。
http://bbs.blueidea.com/thread-2768623-1-1.html
他提出了一个问题,就是一个双实体以及其多对多关系的显示问题,原题如下:
一共三个表..
表一(student)
id name
1 A
2 B
3 C
表二(teacher)
id teachername
1 张三
2 李四
3 王五
表三(studenttoteacher)
id studentid teacherid
1 1 1
2 1 2
3 1 3
4 2 1
5 2 3
6 3 2
7 3 3
表三第一二三条记录表示的意思是学生ID为1的学生有三个老师 ID分别是1 2 3,依此类推
输入结果要求如下图..学生老师要求可以再添加
问题抽象其实是这样的
有三个表,分别是实体A、实体B以及两个实体之间的多对多关系,现在的需求是,显示一个html表格,要求在这个表格里面显示两实体之间各记录是否有对应的关系。并且这里面的实体,是可以动态的添加的。
而我的思路是这样的,首先取出两实体A、B的名称,同时获得其条目数,而后定义一个二维数组,用于以矩阵的形式存放二者的关系,而后再进行显示。
我给出的代码如下:
<%
Option Explicit
Dim sConn,oConn,sSql,oRs,i,j
Dim aSet,lRowCount,lColCount,aStudents,aTeachers
Dim lLastID
sConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Server.MapPath("source.mdb")
Set oConn = Server.CreateObject("ADODB.Connection")
Set oRs = Server.CreateObject("ADODB.RecordSet")
oConn.Open sConn
'学生部分记录
sSql = "SELECT * FROM [student]"
oRs.Open sSql,oConn,1,1
lLastID = 0
While Not oRs.Eof
For i = 1 To (oRs("id")-lLastID)
aStudents = aStudents & ","
Next
aStudents = aStudents & oRs("name")
lLastID = oRs("id")
oRs.MoveNext
Wend
oRs.MoveLast
lColCount = oRs("id")
oRs.Close
'教师部分记录
sSql = "SELECT * FROM [teacher]"
oRs.Open sSql,oConn,1,1
lLastID = 0
While Not oRs.Eof
For i = 1 To (oRs("id")-lLastID)
aTeachers = aTeachers & ","
Next
aTeachers = aTeachers & oRs("name")
lLastID = oRs("id")
oRs.MoveNext
Wend
oRs.MoveLast
lRowCount = oRs("id")
oRs.Close
'字符恢复为数组
aStudents = Split(aStudents,",")
aTeachers = Split(aTeachers,",")
'获得关系集合数组
ReDim aSet(lColCount,lRowCount)
sSql = "SELECT * FROM [studenttoteacher]"
oRs.Open sSql,oConn
While Not oRs.Eof
aSet(oRs("studentid"),oRs("teacherid")) = "ok"
oRs.MoveNext
Wend
oRs.Close
Set oRs = Nothing
%>
<table border="1">
<!--首行输出教师名称-->
<tr>
<th width="50"> </th>
<%For i = 1 To UBound(aTeachers)%>
<%If aTeachers(i) <> "" Then%>
<th width="50"><%=aTeachers(i)%></th>
<%End If%>
<%Next%>
</tr>
<!--依次输出每个学生的行-->
<%For i = 1 To UBound(aStudents)%>
<tr>
<th width="50"><%=aStudents(i)%></th>
<%For j = 1 To UBound(aTeachers)%>
<%If aTeachers(j) <> "" Then%>
<td align="center">
<%
If aSet(i,j)="ok" Then
Response.Write "√"
Else
Response.Write " "
End If
%>
</td>
<%End If%>
<%Next%>
</tr>
<%Next%>
<%
oRs.Close
Set oRs = Nothing
oConn.Close
Set oConn = Nothing%>
</table>
这里面有两个难点:
第一,效率问题。如果不考虑效率问题,那么我们蛮可以使用循环嵌套,外部循环所有的实体A,内部循环实体B,在内部循环中打开记录集查询关系表中是否有A和B当前条目的对应关系,但是这样的效率太低了,我们需要的记录集查询次数就是A条目数*B条目数+2,如果A和B都很多的话,那么将是一个恐怖的查询。
那么我们解决的方法就是将关系表中的记录全部一次取出,并放在二维数组矩阵中,假如当前第N行第M列有关系,那么设定此成员的值为"ok"。而后在表格的显示中判断当前行列的元素的值是否为"ok"就可以判断当前位置的元素是否应当显示"√"以表示是否有关系了。
第二,动态添加问题。其实这里的添加不仅仅指添加,他主要解决的是数据库内元素的变动问题,设想,假如我删除了某一个实体中的某一条记录,那么此时不加以处理的话,数组就会乱套而无法判定当前行列的记录是否是数据库中指定id的记录,因此我采用了这样的代码:
For i = 1 To (oRs("id")-lLastID)
aTeachers = aTeachers & ","
Next
aTeachers = aTeachers & oRs("name")
lLastID = oRs("id")
oRs.MoveNext
来保持数组中的次序和id保持完全的一致。因为考虑到数据库中数据可能有删除导致id不连续的情况
aSet数组中的下标对应的是id
而aStudents和aTeachers数组的下标对应的是记录在数据库中是第几个,如果中间你删除了student或者teacher的记录,那么这个序号就不对应了,因此我用那个方法,使得aStudents和aTeachers保证对应的是id。
相关文章推荐
- <如何创建一个实体历史> 时间维度 让 1:n的 产生新的实体 或者关系
- 一个典型的Hibernate实体操作例子
- Hibernate学习-14:实体之间的关系及其配置,级联操作
- android Sqlite操作之-- 自定义ORM关系实体映射类
- 重量级别--何为immutable,在拷贝,快照,而非历史需求中分析,如何利用immutable模式和跨设计实体后的业务实体关系 决定 设计实体 是否immutable , 以后业务操作该如何操作
- 08讲、JPA中的多对多双向关联实体定义、注解设置与各项关系操作
- 光脚丫学LINQ(033):建立映射关系的两个实体类必须分别包含一个主键列成员
- 一个Spring事务中,前后两次数据库操作的影响关系
- JPA学习笔记---JPA实体Bean的建立---链接上一个博文:对实体Bean中属性进行操作:保存日期类型,设置字段的长度,名字,是否为空,可以声明枚举字段;可以存放二进制数据,可以存放
- 光脚丫学LINQ(033):建立映射关系的两个实体类必须分别包含一个主键列成员
- 修改bug 提交出错:操作失败: 无法更改关系,因为一个或多个外键属性不可以为 null
- 一次ORA-4030问题诊断及解决【解决思路不错,说明了对象的统计信息与优化器的优化操作(即选择执行一个SQL语句在该优化参数环境下最佳的执行计划)间的关系】
- [C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例
- .若A,B两个实体是一对多的包含关系。利用存储过程,实现数据访问层层的一个实例。
- [C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例
- 一个具有多值属性的实体怎么映射为关系
- 【极力分享】[C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例
- [C#/.NET]Entity Framework(EF) Code First 多对多关系的实体增,删,改,查操作全程详细示例
- Hibernate/JPA中的继承映射 实体extends的关系(每个子类独立一个表)
- 技巧 改变实体性质(增加一个类型字段) , 增加一种关系 考虑上游下游的影响