请问下,我们对Dexie实体的字段定义,可以使用一个Interface吗,然后使用的时候直接加这个数据结构即可?

在使用Dexie.js的时候,我们可以依据此进行定义一个实体:

// Store Entity定义
export interface Friend {
  id: number;
  name: string;
  age: number;
}

// Database declaration 
export const db = new Dexie('FriendDatabase') as Dexie & {
  friends: EntityTable<Friend, 'id'>;
};
db.version(1).stores({
  friends: '++id, age',
});

1、请问下,我们的这个字段,可以使用一个Interface吗,然后使用的时候直接加这个数据结构即可?

export interface ContactInfo {
  email: string,
  tel: number,
  address: {
    country: string,
    province: string,
    city: string,
    street: string,
    streetNo: number
  }
}

export interface Friend {
  id: number;
  name: string;
  age: number;
  contact: ContactInfo
}

2、如果可以,存储到IndexedDB的数据样式是什么样的呢?
是否是被JSON之后的字符串?
image.png

阅读 698
avatarAI BotBETA

回答

  1. 可以使用Interface定义Dexie实体的字段

    是的,你可以使用Interface来定义Dexie实体的字段。在你的例子中,你已经成功地定义了一个Friend接口,它包含了ContactInfo作为其中的一个字段。这样做是完全可行的,你可以在使用Dexie的时候直接引用这个数据结构。

    export interface ContactInfo {
      email: string;
      tel: number;
      address: {
        country: string;
        province: string;
        city: string;
        street: string;
        streetNo: number;
      };
    }
    
    export interface Friend {
      id: number;
      name: string;
      age: number;
      contact: ContactInfo;
    }

然后在Dexie数据库声明中使用这个接口:

export const db = new Dexie('FriendDatabase') as Dexie & {
  friends: EntityTable<Friend, 'id'>;
};
db.version(1).stores({
  friends: '++id,name,age,[contact+email+tel+address.country+address.province+address.city+address.street+address.streetNo]'
});

注意:在stores方法中,你需要指定所有你想要索引的字段,特别是复杂类型(如对象)的字段,你需要通过[field+subfield1+subfield2...]的方式来索引嵌套的属性。

  1. 存储到IndexedDB的数据样式

    是的,当你将数据存储到IndexedDB时,Dexie会将对象序列化为JSON字符串。这意味着你的Friend对象(包括嵌套的ContactInfo对象)会被转换成JSON格式,然后存储到数据库中。

    存储的数据样式大致如下(这是一个JSON格式的示例,实际存储时是以二进制形式存储的,但逻辑上是这样的):

    {
      "id": 1,
      "name": "John Doe",
      "age": 30,
      "contact": {
        "email": "john.doe@example.com",
        "tel": 1234567890,
        "address": {
          "country": "USA",
          "province": "California",
          "city": "San Francisco",
          "street": "Main Street",
          "streetNo": 100
        }
      }
    }

这个JSON对象会被IndexedDB存储为键值对,其中键是主键(在你的例子中是id),值是JSON字符串。当你从Dexie中检索数据时,Dexie会自动将这个JSON字符串反序列化为JavaScript对象。

1 个回答

测试是可以的:

entities/Friend.ts

export interface Friend {
  id?: number;
  name: string;
  age: number;
  contact: ContactInfo;
}

export interface ContactInfo {
  email: string;
  tel: number;
  address: {
    country: string,
    province: string,
    city: string,
    street: string,
    streetNo: number
  }
}

App.tsx


import { useEffect } from 'react'
import './App.css'

import { Dexie, type EntityTable } from 'dexie';
import { useLiveQuery } from 'dexie-react-hooks';

import { db } from './common/db'
import { Friend, ContactInfo } from './entities/Friend';

function App() {

  const friends = useLiveQuery(() => {
    return db.friends.toArray()
  }, [])


  const handleClick = () => {

    const contact: ContactInfo = {
      email: '123@gmail.com',
      tel: 15982321123,
      address: {
        country: 'china',
        province: 'sichuan',
        street: 'chenghua street',
        city: 'chengdu',
        streetNo: 1321
      }
    }

    const friend: Friend = {
      name: '小明',
      age: 23,
      contact
    }

    db.friends.add(friend).then(() => {
      console.log('添加成功')
    }).catch((err) => {
      console.log(err)
    })
  }

  return (
    <>
      friend count: {friends?.length}

      <button onClick={handleClick}>点击添加数据</button>
    </>
  )
}

export default App

结果:
image.png

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏