parse-dashboard --appId ncloudmaster --masterKey "SnkK12*&sunq2#@20!" --serverURL https://server.fmode.cn/parse --appName NovaCloud
# 不同的版本
test&&server
薛连丽 4/23 09:20:35
https://cloud.fmode.cn/common/manage/_User;equalTo=type:user;rid=uhzm9anHNN
薛连丽 4/23 09:20:47
parse-dashboard --appId ncloudmaster --masterKey "NCM_@)@#" --serverURL https://server.fmode.cn/parse --appName NovaCloud
The dashboard is now available at http://0.0.0.0:4040/
薛连丽 4/23 09:30:29
https://cloud.fmode.cn/这是总部后台
Parse SDK 是一个强大的后端服务工具,用于快速构建应用程序的后端逻辑。它提供了对数据的增删改查(CRUD)操作接口,并支持多种实现方式。以下是 Parse SDK 中实现增删改查的详细说明,以及它们之间的区别和适用场景。
Parse.Object
创建对象并保存const GameScore = Parse.Object.extend("GameScore");
const gameScore = new GameScore();
gameScore.set("score", 1337);
gameScore.set("playerName", "Sean Plott");
gameScore.save().then((object) => {
console.log("New object created with objectId: " + object.id);
}, (error) => {
console.error("Failed to create object: " + error.message);
});
Parse.Object.saveAll()
批量创建const objects = [
new GameScore({ score: 100, playerName: "Alice" }),
new GameScore({ score: 200, playerName: "Bob" })
];
Parse.Object.saveAll(objects).then((savedObjects) => {
console.log("Batch creation successful.");
}, (error) => {
console.error("Batch creation failed: " + error.message);
});
const query = new Parse.Query(GameScore);
query.equalTo("playerName", "Sean Plott");
query.find().then((results) => {
console.log("Found " + results.length + " results.");
}, (error) => {
console.error("Error: " + error.message);
});
const query = new Parse.Query(GameScore);
query.greaterThan("score", 1000);
query.limit(10); // 限制返回结果数量
query.skip(20); // 分页跳过前 20 条
query.find().then((results) => {
console.log("Complex query results:", results);
});
const subscription = await new Parse.Query(GameScore)
.subscribe();
subscription.on('create', (object) => {
console.log("New object created:", object);
});
subscription.on('update', (object) => {
console.log("Object updated:", object);
});
const query = new Parse.Query(GameScore);
query.get("objectId").then((object) => {
object.set("score", 2000);
return object.save();
}).then((updatedObject) => {
console.log("Updated object:", updatedObject);
});
const query = new Parse.Query(GameScore);
query.get("objectId").then((object) => {
object.increment("score", 50); // 原子性增加分数
return object.save();
}).then((updatedObject) => {
console.log("Incremented score:", updatedObject);
});
const query = new Parse.Query(GameScore);
query.get("objectId").then((object) => {
return object.destroy();
}).then(() => {
console.log("Object deleted successfully.");
});
const query = new Parse.Query(GameScore);
query.find().then((objects) => {
return Parse.Object.destroyAll(objects);
}).then(() => {
console.log("Batch deletion successful.");
});
操作类型 | 方法 | 适用场景 |
---|---|---|
Create | 单条保存 | 插入少量数据时使用,逻辑简单。 |
批量保存 | 需要一次性插入大量数据时使用,提升性能。 | |
Read | 基本查询 | 简单查询条件,如按某个字段筛选。 |
复杂查询 | 需要分页、排序、多条件组合查询时使用。 | |
实时订阅 | 数据需要实时更新时使用,如聊天消息、实时通知等。 | |
Update | 直接更新 | 明确知道要更新哪些字段时使用。 |
原子操作 | 并发环境下需要保证数据一致性时使用,如计数器、库存管理等。 | |
Delete | 单条删除 | 删除少量数据时使用,逻辑简单。 |
批量删除 | 需要一次性删除多个对象时使用,提升性能。 |
优化性能:
saveAll
和 destroyAll
)减少网络请求次数。limit
和 skip
实现分页,避免一次性加载过多数据。保证数据一致性:
increment
、add
等)。实时性需求:
// 创建一个 Parse.Query 对象,用于查询 GameScore 表
const subscription = await new Parse.Query(GameScore)
.subscribe(); // 订阅该查询的实时更新
// 监听 'create' 事件,当有新的对象被创建时触发
subscription.on('create', (object) => {
console.log("New object created:", object); // 打印新创建的对象信息
});
// 监听 'update' 事件,当有对象被更新时触发
subscription.on('update', (object) => {
console.log("Object updated:", object); // 打印更新后的对象信息
});
Parse.Query:
Parse.Query
是 Parse SDK 提供的一个类,用于构建对数据库的查询。GameScore
表的查询。.subscribe()
:
.subscribe()
方法后,客户端会与服务器建立 WebSocket 连接,监听指定查询范围内的数据变化。事件监听:
subscription.on('create', callback)
:监听新对象的创建事件。当有新对象插入到 GameScore
表中且符合查询条件时,触发回调函数。subscription.on('update', callback)
:监听对象更新事件。当已存在的对象被修改且符合查询条件时,触发回调函数。适用场景:
// 创建一个 Parse.Query 对象,用于查询 GameScore 表
const query = new Parse.Query(GameScore);
// 根据 objectId 查询特定的对象
query.get("objectId").then((object) => {
// 使用原子操作 increment 增加 score 字段的值
object.increment("score", 50); // 原子性增加分数
return object.save(); // 保存更新后的对象
}).then((updatedObject) => {
// 打印更新后的对象信息
console.log("Incremented score:", updatedObject);
});
Parse.Query:
Parse.Query
构建查询,目标是获取 GameScore
表中某个特定的对象。.get("objectId")
:
objectId
获取指定的对象。objectId
是 Parse 数据库中每个对象的唯一标识符。原子性操作 increment
:
increment
是 Parse 提供的一种原子操作方法,用于在服务器端直接对字段进行增加或减少操作。increment
可以确保结果正确。.save()
:
save()
方法将更新后的对象保存到数据库。适用场景:
increment
、add
、remove
等)是在服务器端实现的。increment
时,Parse 会生成一个特殊的更新指令,并将其发送到服务器。increment
的底层实现假设有一个字段 score
,当前值为 100
,两个用户同时尝试增加 50
和 30
:
score
的值为 100
。score
的值为 100
。score
更新为 150
。score
更新为 130
。130
,丢失了用户 A 的更新。increment
操作时:
increment(50)
指令。increment(30)
指令。180
。不能直接调整底层实现:
可以通过其他方式模拟类似行为: 如果需要自定义逻辑,可以通过事务(Transactions)或其他数据库工具实现类似效果。例如:
$inc
操作符手动实现类似的原子性操作。// 创建一个 Parse.Query 对象,用于查询 GameScore 表
const subscription = await new Parse.Query(GameScore)
.subscribe(); // 订阅该查询的实时更新
// 监听 'create' 事件
subscription.on('create', (object) => {
console.log("New object created:", object); // 打印新创建的对象信息
});
// 监听 'update' 事件
subscription.on('update', (object) => {
console.log("Object updated:", object); // 打印更新后的对象信息
});
// 创建一个 Parse.Query 对象,用于查询 GameScore 表
const query = new Parse.Query(GameScore);
// 根据 objectId 查询特定的对象
query.get("objectId").then((object) => {
// 使用原子操作 increment 增加 score 字段的值
object.increment("score", 50); // 原子性增加分数
return object.save(); // 保存更新后的对象
}).then((updatedObject) => {
// 打印更新后的对象信息
console.log("Incremented score:", updatedObject);
});
Parse SDK 是一个开源的后端服务平台,旨在帮助开发者快速构建 Web 和移动应用程序。它提供了一系列工具和服务,包括数据存储、用户认证、推送通知、文件存储等。Parse 的核心功能是通过其强大的 API 和 SDK 来实现的,支持多种编程语言(如 JavaScript、Java、Python 等)。
Parse 的主要特点:
Parse SDK 提供了许多内置函数来简化常见的操作,例如增删改查(CRUD)、查询、关系管理等。以下是一些常用的函数:
Parse.Object.extend(className)
:创建一个新的类(表)。object.set(key, value)
:设置对象的字段值。object.save()
:保存对象到数据库。object.destroy()
:删除对象。Parse.Object.saveAll(objects)
:批量保存对象。Parse.Object.destroyAll(objects)
:批量删除对象。new Parse.Query(className)
:创建一个查询对象。query.get(objectId)
:根据 objectId 获取单个对象。query.find()
:执行查询并返回结果列表。query.first()
:返回查询结果中的第一个对象。query.equalTo(key, value)
:添加等于条件的过滤器。query.greaterThan(key, value)
:添加大于条件的过滤器。query.limit(n)
:限制返回结果的数量。query.skip(n)
:跳过前 n 条记录(用于分页)。query.include(key)
:包含关联对象的字段。query.subscribe()
:订阅实时更新(LiveQuery)。Parse.User.signUp(username, password, attrs)
:注册新用户。Parse.User.logIn(username, password)
:用户登录。Parse.User.current()
:获取当前登录用户。Parse.User.logOut()
:登出用户。new Parse.File(name, fileData)
:创建文件对象。file.save()
:上传文件到服务器。Parse SDK 提供了灵活的查询接口,允许开发者通过组合多个条件来自定义查询语句。以下是自定义查询的详细步骤和示例。
使用 Parse.Query
类创建一个查询对象,并指定目标类(表)。
const query = new Parse.Query("GameScore");
Parse 提供了多种方法来添加查询条件,例如等于、大于、小于、包含等。
等于:equalTo
query.equalTo("playerName", "John");
不等于:notEqualTo
query.notEqualTo("playerName", "John");
大于:greaterThan
query.greaterThan("score", 1000);
小于:lessThan
query.lessThan("score", 500);
范围:greaterThanOrEqualTo
和 lessThanOrEqualTo
query.greaterThanOrEqualTo("score", 500);
query.lessThanOrEqualTo("score", 1000);
包含在数组中:containedIn
query.containedIn("playerName", ["John", "Alice"]);
不在数组中:notContainedIn
query.notContainedIn("playerName", ["Bob"]);
存在性检查:exists
和 doesNotExist
query.exists("score"); // 检查 score 字段是否存在
query.doesNotExist("score"); // 检查 score 字段是否不存在
可以使用 and
或 or
方法组合多个条件。
默认情况下,所有条件会被视为 AND 关系。
query.equalTo("playerName", "John");
query.greaterThan("score", 1000);
使用 Parse.Query.or
方法创建 OR 条件。
const query1 = new Parse.Query("GameScore");
query1.equalTo("playerName", "John");
const query2 = new Parse.Query("GameScore");
query2.greaterThan("score", 1000);
const mainQuery = Parse.Query.or(query1, query2);
mainQuery.find().then((results) => {
console.log("Results:", results);
});
排序:
query.ascending("score"); // 升序
query.descending("score"); // 降序
分页:
query.limit(10); // 每页返回 10 条记录
query.skip(20); // 跳过前 20 条记录
如果某个字段是关联对象,可以使用 include
方法加载相关数据。
const query = new Parse.Query("Post");
query.include("author"); // 加载 Post 表中的 author 字段(假设是一个 Pointer 类型)
query.find().then((posts) => {
posts.forEach((post) => {
console.log(post.get("author").get("username")); // 访问关联对象的字段
});
});
以下是一个复杂查询的完整示例,包含多个条件、排序和分页。
const query = new Parse.Query("GameScore");
// 添加查询条件
query.equalTo("playerName", "John");
query.greaterThan("score", 1000);
query.lessThan("score", 5000);
// 排序
query.descending("score");
// 分页
query.limit(10);
query.skip(20);
// 执行查询
query.find().then((results) => {
console.log("Found " + results.length + " results.");
results.forEach((result) => {
console.log(result.get("score"));
});
}, (error) => {
console.error("Error:", error.message);
});
query.include
的作用与使用方法query.include
用于在查询中加载关联对象的数据。Parse 数据库支持指针(Pointer)和关系(Relation)类型字段,这些字段通常指向其他表中的对象。默认情况下,查询结果只会返回指针的 objectId
,而不会自动加载关联对象的详细信息。使用 query.include
可以在一次查询中同时加载关联对象的完整数据。
假设有一个 Post
表和一个 User
表,Post
表中的 author
字段是一个指向 User
表的指针。如果想在查询 Post
时同时获取 author
的详细信息(如用户名、邮箱等),可以使用 include
。
const query = new Parse.Query("Post");
query.include("author"); // 加载 author 字段指向的 User 对象
query.find().then((posts) => {
posts.forEach((post) => {
const author = post.get("author"); // 获取关联的 User 对象
console.log("Post Title:", post.get("title"));
console.log("Author Name:", author.get("username")); // 访问 User 对象的字段
});
});
limit
和 skip
query.limit(10); // 每页返回 10 条记录
query.skip(20); // 跳过前 20 条记录
query.limit(10)
:
query.skip(20)
:
结合在一起的意思是:跳过前 20 条记录,然后返回接下来的 10 条记录。
分页的核心思想是通过 skip
和 limit
控制查询结果的范围。例如:
skip(0)
,limit(10)
→ 返回第 1 到第 10 条记录。skip(10)
,limit(10)
→ 返回第 11 到第 20 条记录。skip(20)
,limit(10)
→ 返回第 21 到第 30 条记录。因此,query.limit(10)
和 query.skip(20)
的组合表示:跳过前 20 条记录,返回接下来的 10 条记录。
query.limit(10)
表示每页最多返回 10 条记录。可以通过检查返回结果的长度来确定当前页实际有多少条数据。
query.limit(10);
query.skip(20);
query.find().then((results) => {
console.log("Number of records on this page:", results.length); // 当前页的记录数
results.forEach((result) => {
console.log(result.id); // 打印每条记录的 objectId
});
});
为了实现完整的分页功能,你需要以下几个步骤:
使用 query.count()
方法获取符合条件的总记录数。
const query = new Parse.Query("GameScore");
query.count().then((totalCount) => {
console.log("Total records:", totalCount);
});
根据用户请求的页码和每页大小,动态设置 skip
和 limit
。
const pageSize = 10; // 每页显示 10 条记录
const currentPage = 3; // 当前页码(从 1 开始)
const query = new Parse.Query("GameScore");
query.limit(pageSize);
query.skip((currentPage - 1) * pageSize); // 跳过前面的记录
query.find().then((results) => {
console.log("Records on current page:", results);
});
根据总记录数和每页大小,计算总页数。
const pageSize = 10;
let totalCount = 0;
const query = new Parse.Query("GameScore");
// 获取总记录数
query.count().then((count) => {
totalCount = count;
const totalPages = Math.ceil(totalCount / pageSize); // 总页数
console.log("Total pages:", totalPages);
// 查询当前页数据
const currentPage = 3;
query.limit(pageSize);
query.skip((currentPage - 1) * pageSize);
return query.find();
}).then((results) => {
console.log("Records on current page:", results);
});
query.include
query.include("author")
。query.limit(n)
:设置每页返回的记录数。query.skip(n)
:跳过前 n 条记录。skip
和 limit
实现多页查询。results.length
)。query.count()
获取总记录数。skip
和 limit
参数。通过以上方法,你可以灵活地实现分页功能,并高效地操作 Parse 数据库。