414 lines
9.9 KiB
TeX
414 lines
9.9 KiB
TeX
\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}
|