学习ORMX的连表查询功能,包括INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN等连接类型,以及多表连接和Join上下文的使用方法。 关键字:连表查询, Join, InnerJoin, LeftJoin, RightJoin, FullJoin, 多表连接, DTO映射
第九章:连表查询
9.1 Join 概述
Join 是关系型数据库中最强大的功能之一,它允许您根据两个表之间的关系,将它们的数据组合在一起。ORMX 提供了完整的 Join 支持,包括:
- 内连接(INNER JOIN):只返回两个表中匹配的行
- 左连接(LEFT JOIN):返回左表的所有行,以及右表中匹配的行
- 右连接(RIGHT JOIN):返回右表的所有行,以及左表中匹配的行
- 全连接(FULL JOIN):返回两个表中的所有行
9.1.1 为什么需要 Join?
在实际应用中,数据通常分布在多个表中:
// 用户表
public class User
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
// 订单表
public class Order
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
public int UserId { get; set; } // 外键,关联到 User 表
public decimal Amount { get; set; }
public DateTime OrderDate { get; set; }
}
// 产品表
public class Product
{
[Column(IsPrimaryKey = true, IsAutoIncrement = true)]
public int Id { get; set; }
public int OrderId { get; set; } // 外键,关联到 Order 表
public string ProductName { get; set; }
public decimal Price { get; set; }
}
使用 Join,您可以轻松地查询这些关联数据:
// 查询用户及其订单
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GetList();
9.2 Join 最佳实践
在使用 Join 功能时,遵循以下最佳实践可以提高代码质量和可维护性。
9.2.1 使用 DTO 对象
创建专门的 DTO 对象来接收 Join 查询结果:
public class UserOrderDto
{
public int UserId { get; set; }
public string UserName { get; set; }
public int? OrderId { get; set; }
public decimal? OrderAmount { get; set; }
}
优势:
- 明确的数据结构,避免使用匿名类型
- 可以在多个地方复用
- 便于单元测试和维护
9.2.2 使用有意义的别名
在 DTO 中使用有意义的属性名:
public class UserOrderDto
{
public int UserId { get; set; } // 用户 ID
public string UserName { get; set; } // 用户名
public int? OrderId { get; set; } // 订单 ID
public decimal? OrderAmount { get; set; } // 订单金额
}
建议:
- 使用表名作为前缀,如
UserId、UserName、OrderId - 避免使用
Id、Name等通用名称 - 添加注释说明字段的含义
9.2.3 DTO 映射机制
ORMX 框架提供灵活的 DTO 映射机制,支持多种映射方式:
9.2.3.1 基本映射(属性名匹配)
DTO 属性名称需与数据库列名称一致:
public class UserOrderSimpleDto
{
public int Id { get; set; }
public string? Name { get; set; }
public int Age { get; set; }
public string? ProductName { get; set; }
public decimal? Price { get; set; }
public int? Quantity { get; set; }
}
9.2.3.2 别名映射(ColumnAttribute)
使用 ColumnAttribute 指定数据库列名:
using JCode.ORMX.Attributes;
public class UserOrderDto
{
[Column("Name")]
public string? UserName { get; set; }
[Column("Age")]
public int? UserAge { get; set; }
[Column("Price")]
public decimal? OrderPrice { get; set; }
[Column("Quantity")]
public int? OrderQuantity { get; set; }
}
9.2.3.3 自动前缀映射
ORMX 支持自动表前缀映射,无需显式指定 ColumnAttribute:
public class UserOrderAutoDto
{
// 自动映射规则:
// UserId -> User.Id 列
// UserName -> User.Name 列
// UserAge -> User.Age 列
// OrderId -> Order.Id 列
// OrderPrice -> Order.Price 列
// OrderQuantity -> Order.Quantity 列
public int UserId { get; set; }
public string? UserName { get; set; }
public int UserAge { get; set; }
public int OrderId { get; set; }
public decimal OrderPrice { get; set; }
public int OrderQuantity { get; set; }
}
映射优先级:
ColumnAttribute指定的列名(最高优先级)- 直接属性名匹配
- 自动前缀映射(如
UserId→User.Id、OrderPrice→Order.Price)
自动前缀映射规则:
- 当属性名以表名开头时,会自动移除表名前缀,映射到对应列
- 例如:
UserId映射到User.Id,OrderPrice映射到Order.Price - 注意: 不支持直接的后缀映射(如
Name→UserName),仅支持前缀移除
9.2.4 DTO 命名规范
使用统一的命名规范可以提高代码的可读性和可维护性。通常使用以下命名规范:
XxxDto:通用的数据传输对象
- 示例:
UserOrderDto、OrderProductDto、UserOrderStats - 用途:用于接收查询结果、API 响应等
- 示例:
XxxViewModel:用于视图展示的数据对象
- 示例:
UserOrderViewModel、OrderListViewModel - 用途:用于 UI 展示,可能包含格式化后的数据
- 示例:
XxxResponse:用于 API 响应的数据对象
- 示例:
UserOrderResponse、CreateOrderResponse - 用途:用于 Web API 的响应数据
- 示例:
XxxRequest:用于 API 请求的数据对象
- 示例:
CreateOrderRequest、UpdateUserRequest - 用途:用于 Web API 的请求数据
- 示例:
在 ORMX 中推荐使用 Dto 后缀,如:
// Join 查询结果
public class UserOrderDto { }
public class OrderProductDto { }
public class UserOrderStats { }
// 聚合查询结果
public class UserAgeGroupDto { }
public class DepartmentSalesDto { }
命名建议:
- 使用完整的表名:
UserOrderDto而不是UO_Dto - 使用有意义的组合:
UserOrderDto表示用户和订单的组合 - 保持一致性:整个项目中使用相同的命名规范
- 避免缩写:
UserOrderDto而不是UsrOrdDto
9.2.5 DTO 使用示例
9.2.5.1 基本 DTO 使用
// 定义简单 DTO
public class UserOrderSimpleDto
{
public int Id { get; set; }
public string? Name { get; set; }
public int Age { get; set; }
public string? ProductName { get; set; }
public decimal? Price { get; set; }
}
// 查询并映射到 DTO
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GetList<UserOrderSimpleDto>();
9.2.5.2 别名 DTO 使用
// 定义带别名的 DTO
public class UserOrderDto
{
[Column("Name")]
public string? UserName { get; set; }
[Column("Age")]
public int? UserAge { get; set; }
[Column("Price")]
public decimal? OrderPrice { get; set; }
}
// 查询并映射到 DTO
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GetList<UserOrderDto>();
9.2.5.3 自动前缀 DTO 使用
// 定义自动前缀 DTO
public class UserOrderAutoDto
{
public int UserId { get; set; }
public string? UserName { get; set; }
public int UserAge { get; set; }
public int OrderId { get; set; }
public decimal OrderPrice { get; set; }
public int OrderQuantity { get; set; }
}
// 查询并映射到 DTO
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GetList<UserOrderAutoDto>();
9.2.6 使用类型安全的上下文
使用 As<T>() 方法访问连接的表,确保类型安全:
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.Where(ctx => ctx.As<User>().Age > 25)
.OrderByDesc(ctx => ctx.As<Order>().OrderDate)
.GetList<UserOrderDto>();
优势:
- 编译时类型检查
- IntelliSense 支持
- 避免拼写错误
9.3 基本 Join 操作
9.3.1 内连接(INNER JOIN)
内连接只返回两个表中匹配的行。这是最常用的 Join 类型。
using var userTable = tableManager.Table<User>();
// 查询有订单的用户
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GetList<UserOrderDto>();
生成的 SQL:
SELECT * FROM User
INNER JOIN Order ON User."Id" = Order."UserId"
使用场景:
- 只需要两个表中都存在的数据
- 例如:查询有订单的用户
9.3.2 左连接(LEFT JOIN)
左连接返回左表(主表)的所有行,以及右表中匹配的行。如果右表中没有匹配的行,则返回 NULL。
// 查询所有用户,包括没有订单的用户
var result = userTable
.LeftJoin<Order>((u, o) => u.Id == o.UserId)
.GetList<UserOrderDto>();
生成的 SQL:
SELECT * FROM User
LEFT JOIN Order ON User."Id" = Order."UserId"
使用场景:
- 需要主表的所有数据,即使关联表中没有匹配的数据
- 例如:查询所有用户,包括没有订单的用户
9.3.3 右连接(RIGHT JOIN)
右连接返回右表的所有行,以及左表中匹配的行。如果左表中没有匹配的行,则返回 NULL。
// 查询所有订单,包括没有关联用户的订单
var result = userTable
.RightJoin<Order>((u, o) => u.Id == o.UserId)
.GetList<UserOrderDto>();
生成的 SQL:
SELECT * FROM User
RIGHT JOIN Order ON User."Id" = Order."UserId"
使用场景:
- 需要关联表的所有数据,即使主表中没有匹配的数据
- 例如:查询所有订单,包括没有关联用户的订单
9.3.4 全连接(FULL JOIN)
全连接返回两个表中的所有行。如果某行在另一个表中没有匹配的行,则返回 NULL。
// 查询所有用户和所有订单
var result = userTable
.FullJoin<Order>((u, o) => u.Id == o.UserId)
.GetList<UserOrderDto>();
生成的 SQL:
SELECT * FROM User
FULL JOIN Order ON User."Id" = Order."UserId"
使用场景:
- 需要两个表的所有数据
- 例如:查询所有用户和所有订单的完整列表
9.4 Join 条件
9.4.1 简单 Join 条件
最简单的 Join 条件是使用相等比较:
// 使用主键和外键关联
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GetList<UserOrderDto>();
9.4.2 复杂 Join 条件
您可以使用各种比较运算符和逻辑运算符:
// 使用多个条件
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId && o.Amount > 100)
.GetList<UserOrderDto>();
// 使用不等运算符
var result = userTable
.InnerJoin<Order>((u, o) => u.Id != o.UserId)
.GetList<UserOrderDto>();
// 使用范围条件
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId && o.OrderDate >= DateTime.Now.AddDays(-30))
.GetList<UserOrderDto>();
9.5 Join 上下文
Join 上下文提供了类型安全的表访问方法。使用 As<T>() 方法,您可以安全地访问已连接的表:
9.5.1 访问连接的表
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.Where(ctx => ctx.As<User>().Age > 25 && ctx.As<Order>().Amount > 100)
.GetList<UserOrderDto>();
9.5.2 在聚合函数中使用
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GroupBy(ctx => ctx.As<User>().Id)
.Max(ctx => ctx.As<Order>().Amount, "MaxAmount")
.Count(ctx => ctx.As<Order>().Id, "OrderCount")
.GetList<UserOrderStats>();
关于聚合函数的详细用法,请查阅聚合函数。
9.5.3 在排序中使用
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.OrderByDesc(ctx => ctx.As<Order>().OrderDate)
.GetList<UserOrderDto>();
9.6 Join 专用查询方法
Join 后,您可以使用专用的查询方法来访问连接的表:
9.6.1 Join Where 方法
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.Where(ctx => ctx.As<User>().Age > 25)
.Where(ctx => ctx.As<Order>().Amount > 100)
.GetList<UserOrderDto>();
9.6.2 Join Between 方法
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.Between(ctx => ctx.As<Order>().Amount, 100, 1000)
.GetList<UserOrderDto>();
9.6.3 Join In 方法
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.In(ctx => ctx.As<Order>().Status, 1, 2, 3)
.GetList<UserOrderDto>();
9.6.4 Join Like 方法
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.Like(ctx => ctx.As<User>().Name, "张%")
.GetList<UserOrderDto>();
9.6.5 Join WhereComplex 复杂条件组合
WhereComplex 方法允许在 Join 操作中组合多个 Where 条件,支持复杂的逻辑运算(AND、OR、括号)。这对于构建复杂的多表查询条件非常有用。
9.6.5.1 基本用法
// 组合主表和连接表的条件
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.WhereComplex(w => w.Between(u => u.Age, 18, 60) && w.In(ctx => ctx.As<Order>().Price, 100, 200))
.GetList();
// 生成 SQL: SELECT * FROM User INNER JOIN "Orders" ON "User"."Id" = "Orders"."UserId"
// WHERE ("User"."Age" BETWEEN @p0 AND @p1) AND ("Orders"."Price" IN (@p2, @p3))
9.6.5.2 使用 OR 逻辑
// 使用 OR 逻辑组合条件
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.WhereComplex(w => w.Between(u => u.Age, 18, 30) || w.Like(ctx => ctx.As<Order>().ProductName, "%Urgent%"))
.GetList();
// 生成 SQL: SELECT * FROM User INNER JOIN "Orders" ON "User"."Id" = "Orders"."UserId"
// WHERE ("User"."Age" BETWEEN @p0 AND @p1) OR ("Orders"."ProductName" LIKE @p2)
9.6.5.3 复杂嵌套条件
// 复杂嵌套条件(使用括号)
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.WhereComplex(w =>
(w.Between(u => u.Age, 18, 30) && w.Like(u => u.Name, "%John%")) ||
(w.In(ctx => ctx.As<Order>().Price, 100, 200) && w.NotLike(ctx => ctx.As<Order>().ProductName, "%Old%"))
)
.GetList();
// 生成 SQL: SELECT * FROM User INNER JOIN "Orders" ON "User"."Id" = "Orders"."UserId"
// WHERE (("User"."Age" BETWEEN @p0 AND @p1) AND ("User"."Name" LIKE @p2)) OR
// (("Orders"."Price" IN (@p3, @p4)) AND ("Orders"."ProductName" NOT LIKE @p5))
9.6.5.4 多表 Join 的 WhereComplex
// 三表 Join 的复杂条件
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.InnerJoin<UserProfile>((ctx, up) => ctx.As<User>().Id == up.UserId)
.WhereComplex(w =>
w.Between(u => u.Age, 18, 60) &&
w.In(ctx => ctx.As<Order>().Price, 100, 200, 300)
)
.GetList();
Join WhereComplex 的优势:
- 支持复杂的逻辑运算(AND、OR、括号)
- 可以在一个表达式中组合多个表的条件
- 生成的 SQL 更清晰,可读性更好
- 适合构建复杂的多表查询条件
9.7 级联 Join(多表 Join)
ORMX 支持无限级联 Join,您可以连接多个表:
9.7.1 三表 Join
连接用户、订单和产品表:
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.InnerJoin<Product>((o, p) => o.Id == p.OrderId)
.GetList<UserOrderProductDto>();
生成的 SQL:
SELECT * FROM User
INNER JOIN Order ON User."Id" = Order."UserId"
INNER JOIN Product ON Order."Id" = Product."OrderId"
9.7.2 四表 Join
连接更多表:
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.InnerJoin<Product>((o, p) => o.Id == p.OrderId)
.InnerJoin<Category>((p, c) => p.CategoryId == c.Id)
.GetList<UserOrderProductCategoryDto>();
9.7.3 混合 Join 类型
您可以混合使用不同类型的 Join:
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.LeftJoin<Product>((o, p) => o.Id == p.OrderId)
.GetList<UserOrderProductDto>();
9.8 Join 后的查询操作
Join 后,您可以继续使用各种查询操作:
9.8.1 Where 条件
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.Where(ctx => ctx.As<User>().Name.Contains("张"))
.GetList<UserOrderDto>();
9.8.2 OrderBy 排序
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.OrderByDesc(ctx => ctx.As<Order>().OrderDate)
.GetList<UserOrderDto>();
9.8.3 Limit/Offset 分页
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.Page(pageNumber: 1, pageSize: 20)
.GetList<UserOrderDto>();
9.8.4 GroupBy 分组
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GroupBy(ctx => ctx.As<User>().Id)
.Max(ctx => ctx.As<Order>().Amount, "MaxAmount")
.Sum(ctx => ctx.As<Order>().Amount, "TotalAmount")
.GetList<UserOrderStats>();
关于聚合函数的详细用法,请查阅聚合函数。
9.9 实际应用示例
9.9.1 用户订单查询
查询用户及其订单信息:
public class UserOrderDto
{
public int UserId { get; set; }
public string UserName { get; set; }
public string UserEmail { get; set; }
public int? OrderId { get; set; }
public decimal? OrderAmount { get; set; }
public DateTime? OrderDate { get; set; }
}
var result = userTable
.LeftJoin<Order>((u, o) => u.Id == o.UserId)
.GetList<UserOrderDto>();
9.9.2 订单产品查询
查询订单及其产品信息:
public class OrderProductDto
{
public int OrderId { get; set; }
public decimal OrderAmount { get; set; }
public int? ProductId { get; set; }
public string? ProductName { get; set; }
public decimal? ProductPrice { get; set; }
}
var result = orderTable
.LeftJoin<Product>((o, p) => o.Id == p.OrderId)
.GetList<OrderProductDto>();
9.9.3 用户订单产品完整查询
查询用户、订单和产品的完整信息:
public class UserOrderProductDto
{
public int UserId { get; set; }
public string UserName { get; set; }
public int? OrderId { get; set; }
public decimal? OrderAmount { get; set; }
public DateTime? OrderDate { get; set; }
public int? ProductId { get; set; }
public string? ProductName { get; set; }
public decimal? ProductPrice { get; set; }
}
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.LeftJoin<Product>((o, p) => o.Id == p.OrderId)
.GetList<UserOrderProductDto>();
9.9.4 用户订单统计
按用户统计订单信息:
public class UserOrderStats
{
public int UserId { get; set; }
public string UserName { get; set; }
public int OrderCount { get; set; }
public decimal TotalAmount { get; set; }
public decimal MaxAmount { get; set; }
public decimal MinAmount { get; set; }
public decimal AvgAmount { get; set; }
}
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.GroupBy(ctx => ctx.As<User>().Id)
.Count(ctx => ctx.As<Order>().Id, "OrderCount")
.Sum(ctx => ctx.As<Order>().Amount, "TotalAmount")
.Max(ctx => ctx.As<Order>().Amount, "MaxAmount")
.Min(ctx => ctx.As<Order>().Amount, "MinAmount")
.Avg(ctx => ctx.As<Order>().Amount, "AvgAmount")
.GetList<UserOrderStats>();
9.9.5 最近订单查询
查询每个用户的最近订单:
public class UserRecentOrderDto
{
public int UserId { get; set; }
public string UserName { get; set; }
public int? OrderId { get; set; }
public decimal? OrderAmount { get; set; }
public DateTime? OrderDate { get; set; }
}
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.OrderByDesc(ctx => ctx.As<Order>().OrderDate)
.GetList<UserRecentOrderDto>();
9.10 Join 性能优化
9.10.1 使用索引
确保 Join 条件中的字段有索引:
// 为外键创建索引
sqlExecutor.ExecuteNonQuery("CREATE INDEX idx_order_userid ON Order(UserId)");
sqlExecutor.ExecuteNonQuery("CREATE INDEX idx_product_orderid ON Product(OrderId)");
9.10.2 选择合适的 Join 类型
- INNER JOIN:当只需要匹配的数据时使用
- LEFT JOIN:当需要主表的所有数据时使用
- RIGHT JOIN:当需要关联表的所有数据时使用
- FULL JOIN:当需要两个表的所有数据时使用
9.10.3 限制结果集
使用 Limit/Offset 限制返回的数据量:
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.Page(pageNumber: 1, pageSize: 20)
.GetList<UserOrderDto>();
9.10.4 只选择需要的列
使用 Column 方法只选择需要的列:
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.Column(ctx => new {
ctx.As<User>().Id,
ctx.As<User>().Name,
ctx.As<Order>().Amount
})
.GetList<UserOrderDto>();
9.11 NoSQL 连接查询
ORMX 不仅支持 SQL 数据库的连接查询,还支持 NoSQL 数据库的连接操作,提供了与 SQL 一致的 API 接口。
9.11.1 NoSQL 连接查询概述
NoSQL 数据库(如 MongoDB)通常不原生支持连接查询,但 ORMX 通过内存计算和映射机制,为 NoSQL 提供了类似 SQL 的连接查询能力。
9.11.2 基本用法
NoSQL 连接查询的基本用法与 SQL 相同:
// NoSQL 内连接
var result = userTable
.InnerJoin<Order>((u, o) => u.Id == o.UserId)
.AsFind().GetList();
// NoSQL 左连接
var result = userTable
.LeftJoin<Order>((u, o) => u.Id == o.UserId)
.AsFind().GetList();
9.11.3 使用 ctx 上下文
在 NoSQL 中,您同样可以使用 ctx 上下文来访问连接的表:
// 使用 ctx 上下文的 NoSQL 连接查询
var result = userTable
.InnerJoin<Order>((ctx, o) => ctx.As<User>().Id == o.UserId)
.Where(ctx => ctx.As<User>().Age > 25 && ctx.As<Order>().Amount > 100)
.OrderByDesc(ctx => ctx.As<Order>().OrderDate)
.AsFind().GetList();
9.11.4 复杂 NoSQL 连接查询
您可以在 NoSQL 中使用复杂的连接查询,包括多表连接和复杂条件:
// 多表连接
var result = userTable
.InnerJoin<Order>((ctx, o) => ctx.As<User>().Id == o.UserId)
.InnerJoin<Product>((ctx, p) => ctx.As<Order>().Id == p.OrderId)
.Where(ctx => ctx.As<User>().Age > 25 && ctx.As<Product>().Price > 50)
.AsFind().GetList();
9.11.5 NoSQL 连接查询的性能考虑
由于 NoSQL 数据库的特性,连接查询的性能可能与 SQL 数据库有所不同:
- 内存消耗:NoSQL 连接查询可能需要更多内存来处理数据
- 性能影响:对于大规模数据,连接查询可能会影响性能
- 最佳实践:
- 对于频繁的连接查询,考虑在数据模型设计时进行适当的冗余
- 在大规模数据操作时进行性能测试
- 合理使用索引来优化查询性能
9.11.6 NoSQL 与 SQL 连接查询的区别
| 特性 | SQL 连接查询 | NoSQL 连接查询 |
|---|---|---|
| 执行方式 | 数据库引擎执行 | ORMX 内存计算 |
| 性能 | 通常更好 | 可能较慢,特别是大规模数据 |
| 功能支持 | 完整支持 | 支持基本和复杂连接 |
| API 接口 | 统一 | 与 SQL 相同的 API |
| 适用场景 | 关系型数据,复杂查询 | 文档型数据,简单到中等复杂度查询 |
总结
本章介绍了 ORMX 框架的连表查询功能,包括 INNER JOIN、LEFT JOIN、RIGHT JOIN、FULL JOIN 等连接类型的使用方法。ORMX 支持多表连接、复杂 Join 条件和 Join 上下文,提供了灵活的 DTO 映射机制。合理使用 Join 功能,可以高效地查询关联数据。同时,ORMX 也为 NoSQL 数据库提供了连接查询支持,通过内存计算实现类似 SQL 的连接功能。
扩展思考
在复杂的多表连接场景下,如何优化查询性能?是否需要使用索引、查询计划分析等技术?对于大规模数据的连接查询,如何避免内存溢出和性能问题?在分布式系统中,如何实现跨节点的连接查询?这些问题值得在深入使用 ORMX 后进一步思考。