返回介绍

数据库基本操作

发布于 2024-09-11 01:11:56 字数 5031 浏览 0 评论 0 收藏 0

增加数据

增加一条数据:

src/renderer/window/WindowMain/Contact.vue

const insertData = async () => {
  let model = new ModelChat();
  model.fromName = "聊天对象";
  model.sendTime = Date.now();
  model.lastMsg = "这是此会话的最后一条消息";
  model.avatar = `https://pic3.zhimg.com/v2-306cd8f07a20cba46873209739c6395d_im.jpg?source=32738c0c`;
  await db("Chat").insert(model);
};

如果要在同一张表中增加多行数据,那么可以直接把一个数组提交给数据库:

const insertMultiData = async () => {
  let result = [];
  for (let i = 0; i < 10; i++) {
    let model = new ModelChat();
    model.fromName = "聊天对象" + i;
    model.sendTime = Date.now();
    model.lastMsg = "这是此会话的最后一条消息" + i;
    model.avatar = `https://pic3.zhimg.com/v2-306cd8f07a20cba46873209739c6395d_im.jpg?source=32738c0c`;
    result.push(model);
  }
  result[5].isSelected = true;
  await db("Chat").insert(result);
};

查询数据

const selectData = async () => {
  let data = await db("Chat").where({ id: `256d6532-fcfe-4b81-a3f8-ee940f2de3e3` }).first();
  console.log(data);
};

修改数据

const updateData = async () => {
  let data = await db("Chat").update({ fromName: "三岛由纪夫", lastMsg: "就在刀刃猛然刺入腹部的瞬间,一轮红日在眼睑背面粲然升了上来。" }).where({ id: `256d6532-fcfe-4b81-a3f8-ee940f2de3e3` });
  console.log(data);
};

需要使用 where 方法确定更新范围,不然整个表的数据都将被修改 (数据库操作返回的值 data 为受影响的行数) 。

删除数据

let deleteData = async () => {
  let data = await db("Chat").where({ id: `256d6532-fcfe-4b81-a3f8-ee940f2de3e3` }).delete();
  console.log(data);
};

需要使用 where 方法确定删除范围,不然整个表的数据都将被删除(数据库操作返回的值 data 为受影响的行数)。

事务

数据库的事务是一个操作序列,包含了一组数据库操作指令。

事务把这组指令作为一个整体向数据库提交操作请求,这一组数据库命令要么都执行,要么都不执行,是一个不可分割的工作逻辑单元。

const transaction = async () => {
  try {
    await db.transaction(async (trx) => {
      let chat = new ModelChat();
      chat.fromName = "聊天对象 aaa";
      chat.sendTime = Date.now();
      chat.lastMsg = "这是此会话的最后一条消息";
      chat.avatar = `https://pic3.zhimg.com/v2-306cd8f07a20cba46873209739c6395d_im.jpg?source=32738c0c`;
      await trx("Chat").insert(chat);
      // throw "throw a error";
      let message = new ModelMessage();
      message.fromName = "聊天对象";
      message.chatId = chat.id;
      message.createTime = Date.now();
      message.isInMsg = true;
      message.messageContent = "这是我发给你的消息";
      message.receiveTime = Date.now();
      message.avatar = `https://pic3.zhimg.com/v2-306cd8f07a20cba46873209739c6395d_im.jpg?source=32738c0c`;
      await trx("Message").insert(message);
    });
  } catch (error) {
    console.error(error);
  }
};

把两个插入操作封装到了一个事务中,两个插入操作要么都成功执行,要么一个也不执行,可以把 throw "throw a error" 语句取消注释,观察一下数据库的数据更新情况。

db.transaction 方法的回调函数中 trx 就是 Knex 封装的数据库事务对象。

分页查询

分页从数据库中获取数据。

import { ref, Ref } from 'vue';

// 当前是第几页
let currentPageIndex: Ref<number> = ref(0);
// 每页数据行数
let rowCountPerPage: Ref<number> = ref(6);
// 总页数
let pageCount: Ref<number> = ref(-1);

// 获取某一页数据
const getOnePageData = async () => {
  let data = await db('Chat')
    .orderBy('sendTime', 'desc')
    .offset(currentPageIndex.value * rowCountPerPage.value)
    .limit(rowCountPerPage.value);
  console.log(data);
}

// 获取第一页数据
const getFirstPage = async () => {
  if (pageCount.value === -1) {
    // @ts-ignore
    let { count } = await db('Chat').count('id as count').first();
    count = count as number;
    pageCount.value = count / rowCountPerPage.value as number;
  }
  currentPageIndex.value = 0;
  await getOnePageData();
}

// 获取下一页数据
const getNextPage = async () => {
  currentPageIndex.value = currentPageIndex.value + 1 >= pageCount.value ? Math.ceil(pageCount.value) - 1 : currentPageIndex.value + 1;
  await getOnePageData();
}

// 获取上一页数据
const getPrevPage = async () => {
  currentPageIndex.value = currentPageIndex.value - 1 < 0 ? 0 : currentPageIndex.value - 1;
  await getOnePageData();
}

// 获取最后一页数据
const getLastPage = async () => {
  currentPageIndex.value = Math.ceil(pageCount.value) - 1;
  await getOnePageData();
}
  • 获取第一页数据时,初始化总页数和当前页码数,总页数是通过数据库中的总行数除以每页行数得到的,这个值有可能包含小数部分。当前页码数是从零开始的整数。第一页时,它的值为 0。
  • 获取下一页数据时,判断当前页码数是不是到达了最后一页,如果没有,那么就把当前页码数加 1,考虑到总页数存在小数的可能,所以最后一页的当前页码数应为:Math.ceil(pageCount) - 1。Math.ceil() 函数返回大于或等于一个给定数字的最小整数。 Math.ceil(6.11) 的结果为 7,Math.ceil(6) 的结果为 6。
  • 获取上一页数据时,判断当前页码数是不是小于 0,如果是,就把当前页码数置为 0,如果不是就把当前页码数减一。
  • 获取最后一页数据时,把当前页码数置为 Math.ceil(pageCount) - 1 即可。
  • 每次获取数据都调用 getOnePageData 方法。这个方法中需要注意 offset 和 limit 方法的使用,offset 方法是跳过 n 行的意思,limit 方法是确保返回的结果中不多于 n 行的意思。当最后一页数据不足 rowCountPerPage(值为 6)时,就返回数据库表中剩余的所有数据。
  • 分页获取数据最好提供明确的排序规则:注意 orderBy 的使用。
  • 在实际的桌面应用中一般不会要求用户点击上一页、下一页等按钮分页获取数据,大部分情况都是根据滚动条滚动时的触底或触顶事件来触发数据获取的逻辑,从数据库中读取数据的逻辑还是大同小异的,都是一页一页读取的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文