如何选择合适的Java数据结构来建模1-n关系映射?

情境

我将尽可能简洁.基本上参考classdiag,我有一个外观管理一个SocketManager列表(管理一个Socket连接).每个SocketManager使用唯一的SocketUserId登录到远程服务器.此外,每个SocketManager都会接受来自客户端的消息,这些消息发往特定的收件人列表.为了便于讨论,请将这些接收方视为由名称标识的远程数据段.

客户将发送如下数据:

SocketFacade facade = ...;

byte[] data = ...

facade.sendData( receipient, data );

当SocketFacade启动时,它将查询一个mysql表,该表返回SocketUserId和Receipients之间的1-m关系.我将使用MultiValuedMap表示这种1-m关系.然后,将通过遍历映射来启动多个SocketManager.

(1) Map< SocketUserId, List<Receipient> > 

例如假设我们有2个SocketManager,其SocketUserIds为“ alice”&分别为“ tom”

            +----SocketManager1 ( "alice" ) for Receipients { "B", "C" }
            |
 SocketFacade 
            |
            +----SocketManager2 ( "tom" ) for Receipients { "A", "D" }

关于如何实现sendData方法,我处于困境.基本上,我需要一种从接收者(例如“ B”)映射到其负责的SocketManager(例如SocketManager1)的方法.

假设我这样做

(2) Map< SocketUserId, SocketManager >
(3) Map< Receipient, SocketUserId >

>(2)中的值是否需要SoftReference?
>我是否应该直接从Receipient映射到SocketManager?
> SocketFacade还支持将使(1)表示的关系发生变异的方法.如果我写入数据库,则(1),(2)和& (3)将需要同步更改. SocketFacade也必须是线程安全的.最初的想法是拥有某种发布订阅系统,通过该系统,对数据库的添加/删除将导致更改通过回调传播.

interface Callback
{
    void receipientAdded( Receipient r );
    void receipientDeleted( Receipient r );
}

解决方法:

在每个收件人中保留对SocketManager的引用.这样,您就可以避免映射(它需要更多的RAM,速度较慢,并且不添加任何值).

在SocketManager中,保留收件人列表.添加和删​​除接收方时,请更新指向SocketManager的指针.

在SocketFacade中,您需要一个使用SocketUserId并返回SocketManager的映射.该地图是通过查询地图中的ID来填充的.所有经理都存在后,将收件人添加到每个中.这需要两个SQL查询.

使用任何ORM工具都非常容易映射.

上一篇:数据库模式的C类设计


下一篇:我有这个PDO连接类吗?