如何使用java.util.Collections来模拟SQL内部联接操作?
如何使用Java集合模拟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
在数据库中,我有: 餐桌上的人
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(){
私人物品清单;
}
依我看,你可以用两种方法
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