如何使用java.util.Collections来模拟SQL内部联接操作?

如何使用java.util.Collections来模拟SQL内部联接操作?,java,mysql,sql,hashmap,Java,Mysql,Sql,Hashmap,如何使用Java集合模拟SQL内部联接操作 在数据库中,我有: 餐桌上的人 KEY NAME 11 Senor other non-important entries... 餐桌用品 KEY ITEM AA Moustache BB Sombrero CC HotSauce other non-important entries... 餐桌用品 PERSON_KEY THING_KEY HAS 11 AA Y 11

如何使用Java集合模拟SQL内部联接操作


在数据库中,我有:

餐桌上的人

KEY  NAME
11   Senor
other non-important entries...
餐桌用品

KEY  ITEM
AA   Moustache
BB   Sombrero
CC   HotSauce
other non-important entries...
餐桌用品

PERSON_KEY  THING_KEY  HAS
11          AA         Y
11          BB         N
11          CC         Y
other non-important entries...

我想模拟SQL语句:

SELECT Person.NAME, Thing.ITEM, PersonToThing.HAS 
FROM Person 
INNER JOIN PersonToThing ON Person.KEY=PersonToThing.PERSON_PKEY
INNER JOIN Thing ON Thing.KEY=PersonToThing.THING_KEY
WHERE Person.NAME="Senor";
这将生成结果集:

NAME   ITEM       HAS
Senor  Moustache  Y
Senor  Sombrero   N
Senor  HotSauce   Y
我想把每个表放在一个Java映射中

我已将表导出到INSERT TABLE语句中

我将通过循环INSERT TABLE语句来填充映射


不幸的是,运行关系数据库建模系统根本不可能


我不明白的是如何组织集合或地图,以及如何将它们链接在一起以模拟内部连接操作



提前感谢您的时间和您所能提供的任何帮助。

在您的示例中,人与物之间存在一对多的关系。对我来说,从数据库的角度考虑这种关系比从Java/OOP的角度考虑更难

在DB中,将person表连接到thing表,以提供每个人拥有的东西的列表

这可以作为一个事物地图进入您的应用程序,每个事物都有一个拥有每个事物的人的列表,或者作为一个人物地图,每个人都有一个他们拥有的事物的列表

因此,在Java中,您本质上是在问如何对此进行建模:

public class Person() {    
   private List<Thing> things;
}

...

public class SomeClass() {
    private List<Person> peopleWithThings;
}  
公共类Person(){
私人物品清单;
}
...
公共类SomeClass(){
私人物品清单;
}  
依我看,你可以用两种方法

  • 只需像我上面所做的那样在您的域中使用普通的旧Java对象
  • 使用类似于Guava的multimap的东西来创建一个字符串(人名)映射到一个事物列表
  • 使用多重贴图时,您可能会遇到以下情况:

    String key = "Senor";
    Multimap<String, Thing> map = ArrayListMultimap.create();
    
    map.put(key, thing1);
    map.put(key, thing2);
    
    assertEquals(2, map.size());
    
    String key=“Senor”;
    Multimap map=ArrayListMultimap.create();
    地图。放(钥匙,东西1);
    地图。放(钥匙,东西2);
    assertEquals(2,map.size());
    
    在集合论中,内部连接本质上是一种交集运算。Java集合中没有完全相同的内置集合论函数,但它们有相似的union(addAll)和intersection(RETAINAL)函数。有关如何使用集合或其他集合实现内部联接/交集的详细信息,请参见

    这里使用集合论的主要挑战是存在三种不同的对象类型,它们都不是相互继承的,这是人们在适当的关系模型中可能期望的。例如,如果Person和Thing都作为父类继承自PersonTohing,则会大大简化事情:

    class Person extends PersonToThing {
        // ...
    }
    
    class Thing extends PersonToThing {
        // ...
    }
    
    class PersonToThing {
        // now Person_Key and Thing_Key can be inherited
        String personKey;
        String thingKey;
        // etc...
    }
    
    使用此模型,我们现在可以拥有PersonToThing对象的集合,并正确地说明一对多关系:

    Set<PersonToThing> people = selectAllFrom("Person");
    Set<PersonToThing> thing = selectAllFrom("Thing");
    Set<PersonToThing> innerJoin = people;
    people.addAll(thing);
    innerJoin.retainAll(thing);
    
    之所以这样做是因为Set使用
    equals()
    检查两个对象是否相同。这样,当它这样做时,我们就像连接一样比较键


    我留下了selectAllFrom()函数摘要的详细信息,因为您没有提供任何特定于数据库的样板代码,但它应该很容易实现,不管您需要什么。

    好吧,这似乎不容易,但却是可能的。
    首先做一些准备-为了使用简单的注释生成getter/setter和构造函数,只需创建一个Maven项目并将此依赖项添加到其中:

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.4</version>
        <scope>provided</scope>
    </dependency>
    

    “运行关系数据库建模系统根本不可能”——为了论证起见,在Java中可以使用H2包含嵌入式数据库。整个应用程序(包括数据库)都在一个jar文件中。如果你不能使用数据库,为什么这个文件会被标记为MySQL?为什么不能使用内存中的数据库(如H2、SQLite)或类似数据库?你尝试过什么,遇到了什么问题?你打算加入的剧组有多大?集合是否已经排序,还是按随机顺序排序?
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.4</version>
        <scope>provided</scope>
    </dependency>
    
    @AllArgsConstructor @Getter
    public static class Person {
        private String key, name;
    }
    
    @AllArgsConstructor @Getter
    public static class Thing {
        private String key, item;
    }
    
    @AllArgsConstructor @Getter
    public static class PersonToThing {
        private String personKey, thingKey, has;
    }
    
    static Collection<Person> tablePerson = Arrays.asList(
            new Person("11", "Senor"),
            new Person("22", "Tom"));
    
    static Collection<Thing> tableThing = Arrays.asList(
            new Thing("AA", "Moustache"),
            new Thing("BB", "Sombrero"),
            new Thing("CC", "HotSauce"),
            new Thing("XX", "Not important")
    );
    
    static Collection<PersonToThing> tablePerson2Thing = Arrays.asList(
            new PersonToThing("11", "AA","Y"),
            new PersonToThing("11", "BB","N"),
            new PersonToThing("11", "CC","Y"));
    
    @AllArgsConstructor(staticName = "of") @Getter
    public static class Tuple<V1,V2>{
        private V1 v1;
        private V2 v2;
    }
    
    @AllArgsConstructor(staticName = "of") @Getter
    public static class Triple<V1,V2,V3>{
        private V1 v1;
        private V2 v2;
        private V3 v3;
    }
    
    public static void main(String[] args) {
        tablePerson.stream()
                // WHERE Person.NAME="Senor";
                .filter(x->x.getName()=="Senor")
                // INNER JOIN PersonToThing
                .flatMap( p -> tablePerson2Thing.stream()
                        .map(p2t-> Tuple.of(p,p2t))
                        // ON Person.KEY=PersonToThing.PERSON_PKEY
                        .filter(t->t.getV1().getKey()==t.getV2().getPersonKey())
                )
                // INNER JOIN Thing
                .flatMap( p2t-> tableThing.stream()
                        .map(t-> Triple.of(p2t.getV1(),p2t.getV2(),t))
                        // ON Thing.KEY=PersonToThing.THING_KEY
                        .filter(t->t.getV2().getThingKey()==t.getV3().getKey())
                )
                // SELECT Person.NAME, Thing.ITEM, PersonToThing.HAS 
                .forEach(x->System.out.println(x.getV1().getName()+ " / " + x.getV3().getItem() + " /  " + x.getV2().getHas()));
    }
    
    Senor / Moustache /  Y
    Senor / Sombrero /  N
    Senor / HotSauce /  Y