SQLite:如何在普通SQL中实现ORM“渴望加载”?

SQLite:如何在普通SQL中实现ORM“渴望加载”?,sql,database,sqlite,Sql,Database,Sqlite,我有一个包含电影、演员和标签的SQLite数据库 电影与演员、电影与标签之间存在着多对多的关系 在我的应用程序中,我想列出所有电影及其相应的演员和标签,例如: 史密斯夫妇:演员:布拉德·皮特,安吉丽娜·朱莉,标签:动作,喜剧,犯罪 乘客:演员:詹妮弗·劳伦斯、克里斯·普拉特,标签:冒险、戏剧、浪漫 我想知道实现这一点的正确SQL语句是什么 我的数据库中的表定义如下: CREATE TABLE "Movie" ( id INTEGER PRIMARY KEY, name VAR

我有一个包含电影、演员和标签的SQLite数据库

电影与演员、电影与标签之间存在着多对多的关系

在我的应用程序中,我想列出所有电影及其相应的演员和标签,例如:

史密斯夫妇:演员:布拉德·皮特,安吉丽娜·朱莉,标签:动作,喜剧,犯罪

乘客:演员:詹妮弗·劳伦斯、克里斯·普拉特,标签:冒险、戏剧、浪漫

我想知道实现这一点的正确SQL语句是什么

我的数据库中的表定义如下:

CREATE TABLE "Movie" 
(
    id INTEGER PRIMARY KEY, 
    name VARCHAR
)

CREATE TABLE "Actor"  
(
    id INTEGER PRIMARY KEY, 
    name VARCHAR
)

CREATE TABLE "Tag" 
( 
    id INTEGER PRIMARY KEY, 
    name VARCHAR
)

CREATE TABLE "Movie_Actor" 
( 
    movie_id INTEGER,
    actor_id INTEGER,
    FOREIGN KEY(movie_id) REFERENCES "Movie" (id), 
    FOREIGN KEY(actor_id) REFERENCES "Actor" (id),
    UNIQUE(movie_id, actor_id)
);

CREATE TABLE "Movie_Tag" 
( 
    movie_id INTEGER,
    tag_id INTEGER,
    FOREIGN KEY(movie_id) REFERENCES "Movie" (id), 
    FOREIGN KEY(tag_id) REFERENCES "Tag" (id),
    UNIQUE(movie_id, tag_id)
);
要获得包含演员和标记的单个电影,我使用以下3个查询,例如movie.id=1:

要获取电影行,请执行以下操作:

SELECT * 
FROM Movie 
WHERE id = 1
要获得演员:

SELECT *
FROM 
    (SELECT * FROM Actor) AS T1
JOIN 
    (SELECT * FROM Movie_Actor WHERE Movie_Actor.movie_id = 1) AS T2 ON T1.id = T2.actor_id
要获取标签,请执行以下操作:

SELECT *
FROM 
    (SELECT * FROM Tag) AS T1
JOIN 
    (SELECT * FROM Movie_Tag WHERE Movie_Tag.movie_id = 1) AS T2 ON T1.id = T2.tag_id
我的问题是,当我从电影中获取电影列表(如SELECT*FROM Movie)时,我应该如何检索标签和演员

许多ORM都有一个选项可以选择“急切加载”关系,我想知道如何在普通SQL中实现这一点

我是否需要对从SELECT*from Movie获得的每一行执行额外的2个查询

谢谢。

要获得id为1的电影以及与该电影相关的所有演员,请执行以下操作:

SELECT * FROM Movie
    LEFT JOIN Movie_Actor ON Movie_Actor.movie_id = Movie.id
    LEFT JOIN Actor ON Actor.id = Movie_Actor.actor_id
    WHERE id = 1 
要同时获取所有标记,请继续连接关联表Movie_Tag和Tag

您可能会认为这将是非常低效的,因为许多信息将被复制,例如,电影的名称将被提取不止一次,而是NA*NT次,其中NA是提取的演员数量,NT是提取的标签数量

实际上,数据库在这方面往往很聪明,正是因为这是一种非常流行的检索数据的机制,尽可能少地往返于数据库,所以在它们的通信协议中,它们包含特殊的措施,以避免在行与行之间传输相同的字段值。因此,实际传输的数据量非常接近单独查询每个表时传输的数据量


当然,这样做的好处是,您将遭受到一次数据库往返的惩罚,而不是多次往返,每个表一次。

谢谢!这很有帮助。我现在正试图弄清楚如何解析得到的行。在我将行放入:Hashmap之前。因此,对于每个返回的电影,我都有一个包含行内容的Hashmap。是的,解码结果的算法有点复杂。除了Movie的列之外,您的地图还需要有两个伪列,一个用于演员,一个用于标记,其对应的值将是collections。是的,我可能需要为地图创建一个既可以有单个值也可以有集合的特定对象。我现在面临的另一个问题是如何限制结果。假设我只想得到5部电影,解决这个问题的唯一方法是生成一个子查询,如SELECT*FROM movies LIMIT 5,然后用标记和演员将其连接起来……这不是有效的SQL。SQLite不是客户机/服务器数据库,所以@CL。那么您的建议是对每部电影进行两次单独的查询?例如,在对每行的标签和演员的SELECT*FROM MONIVE查询结果进行迭代时?