electron中prisma使用

1,273 阅读2分钟

背景: 业务场景从阿里云切换为了单机模式,后端在本机启动了docker服务,并且已经初始化好了表。所以这里就不使用prisma migrate 来初始化表了。

prisma官方文档 首先,在.env 上配置好prisma对象的路径

  DATABASE_URL="mysql://root:dev@localhost:3306/mair?schema=public"

执行prisma初始化

 npx prisma init

✔ Your Prisma schema was created at prisma/schema.prisma
  You can now open it in your favorite editor.

warn You already have a .gitignore file. Don't forget to add `.env` in it to not commit any private information.

Next steps:
1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started
2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb.
3. Run npx prisma db pull to turn your database schema into a Prisma schema.
4. Run npx prisma generate to generate the Prisma Client. You can then start querying your database.

将后端表关联到前端prisma 对象上。

  npx prisma db pull

最后将表关联到 prisma client上

  npx prisma generate 

接下来就可以使用了。 实际运行中,需要将下面的命令配置在 package.json中 start-main: npx prisma db pull && npx prisma generate && webpack [config 配置文件] && electron path/main.js

在electron 中,prisma需要运行在node.js环境中,不能在renderer进程下使用,只能在main进程使用了。

下面是一个存储最后一次登录账号名的逻辑。(localStorage 存在丢数据的可能)

方式1

定义prismaClient 对象,

import { PrismaClient } from '@prisma/client';
const prismaAir = new PrismaClient();

const setConfig = async (group_name: string, name: string, value: string) => {
  try{
    let res = await prismaAir.air_front_config.upsert({
      where:{
        group_name_name: {
          group_name,
          name,
        },
      },
      create: {
        group_name,
        name,
        value,
        created_at: new Date(),
        updated_at: new Date(),
      },
      update: {
        value,
      },
    });

    console.log('insert db', res);
  }catch (e) {
    console.log('err message',e);
  }
};

const getConfig = async (group_name: string, name: string) => {
  const config = await prismaAir.air_front_config.findFirst({
    where: {
      group_name,
      name,
    },
  });

  return config;
};
export {
  prismaAir,
  setConfig,
  getConfig,
};

在main中使用

    import { setConfig } from '@/main/lib/airPrisma';
    
    await setConfig('init', 'lastAccount', loginDto.username);

需要注意,在窗口关闭是,销毁prismaClient实例

    prismaAir.$disconnect();

以上方式需要采用 electron 的ipc通信方式;使用起来需要较多的配置。

方式2

采用electon中的contextBridge来将main中的对象和方法暴露给render;但是采用contextBridge时,需要contextIsolation = true; 这是官方要求的。

但是我的项目 webpack 热更新 导致global is undefined; 所以采用不安全的处理方式;

main进程中main.js

new BrowserWindow({
    width: 1920,
    height: 1080,
    webPreferences: {
      // 启用node.js 集成
      nodeIntegration: true,
      // 开启沙箱 和上下文隔离
      contextIsolation: false,
      webSecurity: false,
      preload: path.join(__dirname, 'preload.js'),
    },
  });

preload.js

const PrismaClient = require('@prisma/client').PrismaClient;
const prismaAir1 = new PrismaClient();

window.myAPI = {
  prisma: prismaAir1,
};

render进程中 login.tsx

    useEffect(() =>{
        const prismaDb = window.myAPI.prisma;
        console.log('window', await prismaDb.air_front_config.findMany());
        // 这里是可行,可以取到 config表中所有数据
    }, []);