\section{Prisma ORM} \begin{frame}{Mi az a Prisma?} \begin{block}{Prisma} Modern ORM (Object-Relational Mapping) Node.js és TypeScript környezethez \end{block} \begin{block}{Főbb jellemzők} \begin{itemize} \item Típusbiztos adatbázis kliens \item Deklaratív séma definíció \item Automatikus migráció kezelés \item Intuitív API CRUD műveletekhez \item Támogatott adatbázisok: PostgreSQL, MySQL, SQLite, MongoDB, stb. \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Prisma telepítése} \begin{block}{NPM telepítés} \begin{lstlisting}[language=bash] # Prisma CLI telepítése dev dependencyként npm install prisma --save-dev # Prisma Client telepítése npm install @prisma/client # Prisma inicializálása npx prisma init \end{lstlisting} \end{block} \begin{block}{Létrejövő fájlok} \begin{itemize} \item \texttt{prisma/schema.prisma} - Adatbázis séma \item \texttt{.env} - Környezeti változók (pl. DATABASE\_URL) \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Prisma Schema alapok} \begin{block}{schema.prisma} \begin{lstlisting}[language=JavaScript] generator client { provider = "prisma-client-js" } datasource db { provider = "postgresql" url = env("DATABASE_URL") } model User { id Int @id @default(autoincrement()) email String @unique name String? createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Prisma migrációk} \begin{block}{Adatbázis migráció létrehozása és futtatása} \begin{lstlisting}[language=bash] # Migráció létrehozása npx prisma migrate dev --name init # Prisma Client újragenerálása npx prisma generate # Adatbázis vizualizáció npx prisma studio \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Prisma Client inicializálása} \begin{block}{prisma.js} \begin{lstlisting}[language=JavaScript] const { PrismaClient } = require('@prisma/client'); const prisma = new PrismaClient(); module.exports = prisma; \end{lstlisting} \end{block} \begin{alertblock}{Singleton pattern} Érdemes egyetlen Prisma Client példányt használni az alkalmazásban. \end{alertblock} \end{frame} \begin{frame}[fragile]{Create - Létrehozás} \begin{block}{Egy rekord létrehozása} \begin{lstlisting}[language=JavaScript] const prisma = require('./prisma'); async function createUser() { const user = await prisma.user.create({ data: { email: 'john@example.com', name: 'John Doe' } }); console.log(user); // { id: 1, email: 'john@example.com', name: 'John Doe', ... } } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Create - Több rekord} \begin{block}{createMany használata} \begin{lstlisting}[language=JavaScript] async function createManyUsers() { const users = await prisma.user.createMany({ data: [ { email: 'alice@example.com', name: 'Alice' }, { email: 'bob@example.com', name: 'Bob' }, { email: 'charlie@example.com', name: 'Charlie' } ] }); console.log(`${users.count} felhasználó létrehozva`); } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Read - Összes rekord} \begin{block}{findMany használata} \begin{lstlisting}[language=JavaScript] async function getAllUsers() { const users = await prisma.user.findMany(); console.log(users); } // Rendezéssel async function getUsersSorted() { const users = await prisma.user.findMany({ orderBy: { name: 'asc' } }); } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Read - Egy rekord} \begin{block}{findUnique és findFirst} \begin{lstlisting}[language=JavaScript] // Egyedi mező alapján (pl. id, email) async function getUserById(id) { const user = await prisma.user.findUnique({ where: { id: id } }); return user; } // Első találat async function getUserByName(name) { const user = await prisma.user.findFirst({ where: { name: name } }); return user; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Read - Szűrés} \begin{block}{Where feltételek} \begin{lstlisting}[language=JavaScript] async function filterUsers() { const users = await prisma.user.findMany({ where: { email: { contains: '@example.com' }, name: { startsWith: 'J' } } }); return users; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Read - Mezők kiválasztása} \begin{block}{Select használata} \begin{lstlisting}[language=JavaScript] async function getUserEmails() { const users = await prisma.user.findMany({ select: { id: true, email: true, name: true } }); return users; // [{ id: 1, email: '...', name: '...' }, ...] } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Update - Módosítás} \begin{block}{Egy rekord frissítése} \begin{lstlisting}[language=JavaScript] async function updateUser(id) { const user = await prisma.user.update({ where: { id: id }, data: { name: 'Jane Doe', email: 'jane@example.com' } }); return user; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Update - Több rekord} \begin{block}{updateMany használata} \begin{lstlisting}[language=JavaScript] async function updateManyUsers() { const result = await prisma.user.updateMany({ where: { email: { contains: '@old-domain.com' } }, data: { email: 'updated@new-domain.com' } }); console.log(`${result.count} rekord frissítve`); } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Delete - Törlés} \begin{block}{Egy rekord törlése} \begin{lstlisting}[language=JavaScript] async function deleteUser(id) { const user = await prisma.user.delete({ where: { id: id } }); return user; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Delete - Több rekord} \begin{block}{deleteMany használata} \begin{lstlisting}[language=JavaScript] async function deleteInactiveUsers() { const result = await prisma.user.deleteMany({ where: { createdAt: { lt: new Date('2020-01-01') } } }); console.log(`${result.count} felhasználó törölve`); } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Relációk - Schema} \begin{block}{Egy-a-többhöz kapcsolat} \begin{lstlisting}[language=JavaScript] model User { id Int @id @default(autoincrement()) name String posts Post[] } model Post { id Int @id @default(autoincrement()) title String content String? authorId Int author User @relation(fields: [authorId], references: [id]) } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Relációk - Include} \begin{block}{Kapcsolt adatok lekérdezése} \begin{lstlisting}[language=JavaScript] async function getUserWithPosts(userId) { const user = await prisma.user.findUnique({ where: { id: userId }, include: { posts: true } }); console.log(user); // { id: 1, name: 'John', posts: [...] } } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Relációk - Nested Write} \begin{block}{Kapcsolt rekordok létrehozása} \begin{lstlisting}[language=JavaScript] async function createUserWithPosts() { const user = await prisma.user.create({ data: { name: 'John Doe', email: 'john@example.com', posts: { create: [ { title: 'First Post', content: 'Hello!' }, { title: 'Second Post', content: 'World!' } ] } } }); } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Tranzakciók} \begin{block}{Több művelet egy tranzakcióban} \begin{lstlisting}[language=JavaScript] async function transferPosts(fromUserId, toUserId) { const result = await prisma.$transaction([ prisma.post.updateMany({ where: { authorId: fromUserId }, data: { authorId: toUserId } }), prisma.user.update({ where: { id: fromUserId }, data: { name: 'Archived User' } }) ]); return result; } \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Express integráció példa} \begin{block}{REST API endpoint Prisma-val} \begin{lstlisting}[language=JavaScript] const express = require('express'); const prisma = require('./prisma'); const app = express(); app.use(express.json()); app.get('/users', async (req, res) => { const users = await prisma.user.findMany(); res.json(users); }); app.post('/users', async (req, res) => { const user = await prisma.user.create({ data: req.body }); res.json(user); }); \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Hibakezelés} \begin{block}{Try-catch használata} \begin{lstlisting}[language=JavaScript] async function safeCreateUser(data) { try { const user = await prisma.user.create({ data: data }); return { success: true, user }; } catch (error) { if (error.code === 'P2002') { return { success: false, error: 'Email már létezik' }; } return { success: false, error: error.message }; } } \end{lstlisting} \end{block} \end{frame} \begin{frame}{Prisma előnyei} \begin{block}{Miért használjuk?} \begin{itemize} \item \textbf{Típusbiztonság} - Auto-complete és típus ellenőrzés \item \textbf{Egyszerű API} - Intuitív, könnyen tanulható \item \textbf{Migráció kezelés} - Automatikus séma szinkronizáció \item \textbf{Teljesítmény} - Optimalizált query-k \item \textbf{Prisma Studio} - Vizuális adatbázis böngésző \item \textbf{Jó dokumentáció} - Részletes guide-ok és példák \end{itemize} \end{block} \end{frame}