„Háttéralkalmazások/Záróvizsgatételek” változatai közötti eltérés
a →5. JPA – általános: Fejezetek rendezése |
a →5. JPA – általános: Magyarra átírás |
||
| (14 közbenső módosítás ugyanattól a felhasználótól nincs mutatva) | |||
| 66. sor: | 66. sor: | ||
Használatával eljárásokat (procedures) és függvényeket (functions), illetve triggereket lehet tárolni az adatbázisban. Lényege, hogy az üzleti logika helyett maga az adatbázis-kezelő szerver ''futtatja'' a beállított szubrutinokat, az előbbi csak ''meghívja'' őket. | Használatával eljárásokat (procedures) és függvényeket (functions), illetve triggereket lehet tárolni az adatbázisban. Lényege, hogy az üzleti logika helyett maga az adatbázis-kezelő szerver ''futtatja'' a beállított szubrutinokat, az előbbi csak ''meghívja'' őket. | ||
{| class="wikitable mw-collapsible mw-collapsed" | {| class="wikitable mw-collapsible mw-collapsed" | ||
|+ | |+A szerveroldali programozás jellemzői | ||
!szempont / tulajdonság | !szempont / tulajdonság | ||
!➕ | !➕ | ||
!➖ | !➖ | ||
|- | |- | ||
|teljesítmény | |'''teljesítmény''' | ||
| | | | ||
* gyorsabb lokális feldolgozás | * gyorsabb lokális feldolgozás | ||
| 81. sor: | 81. sor: | ||
* nem lehet igazán jól skálázni | * nem lehet igazán jól skálázni | ||
|- | |- | ||
|szabvány | |'''szabvány''' | ||
| | | | ||
| | | | ||
| 90. sor: | 90. sor: | ||
* így nehezebben karbantartható a kód | * így nehezebben karbantartható a kód | ||
|- | |- | ||
|adatbiztonság | |'''adatbiztonság''' | ||
| | | | ||
* jobb megfelelés az ACID-elveknek | * jobb megfelelés az ACID-elveknek | ||
| 96. sor: | 96. sor: | ||
| | | | ||
|- | |- | ||
|az üzleti logika bárhonnan meghívhatja a szubrutinokat | |'''az üzleti logika bárhonnan meghívhatja a szubrutinokat''' | ||
| | | | ||
* növeli a kód újrafelhasználhatóságát | * növeli a kód újrafelhasználhatóságát | ||
| 121. sor: | 121. sor: | ||
!van mellékhatása? | !van mellékhatása? | ||
|- | |- | ||
|eljárás | |'''eljárás''' | ||
|🟠 lehet | |🟠 lehet | ||
|🟠 lehet | |🟠 lehet | ||
|- | |- | ||
|függvény | |'''függvény''' | ||
|🟢 igen, mindig | |🟢 igen, mindig | ||
|🔴 nem, soha | |🔴 nem, soha | ||
| 137. sor: | 137. sor: | ||
A shadow-információk az adatbázisban szükséges, de az üzleti logika által nem használt kulcsokat, időbélyegeket és egyéb adatokat takarják. | A shadow-információk az adatbázisban szükséges, de az üzleti logika által nem használt kulcsokat, időbélyegeket és egyéb adatokat takarják. | ||
{| class="wikitable" | {| class="wikitable" | ||
|+ | |+Egymásnak megfeleltethető adattípusok | ||
!üzleti logika | !üzleti logika | ||
!adatbázis | !adatbázis | ||
| 407. sor: | 407. sor: | ||
!előnyei | !előnyei | ||
|- | |- | ||
|automatikus | |'''automatikus''' | ||
|<syntaxhighlight lang="csharp" line="1">public class Book | |<syntaxhighlight lang="csharp" line="1">public class Book | ||
{ | { | ||
| 418. sor: | 418. sor: | ||
* a konvenciók alkalmazása kiváltja a további kód írását | * a konvenciók alkalmazása kiváltja a további kód írását | ||
|- | |- | ||
|annotációk | |'''annotációk''' | ||
|<syntaxhighlight lang="csharp" line="1"> | |<syntaxhighlight lang="csharp" line="1"> | ||
public class Book | public class Book | ||
| 434. sor: | 434. sor: | ||
* egyszerű, ismert szintaxis | * egyszerű, ismert szintaxis | ||
|- | |- | ||
|Fluent API | |'''Fluent API''' | ||
|<syntaxhighlight lang="csharp" line="1">protected override void OnModelCreating(ModelBuilder modelBuilder) | |<syntaxhighlight lang="csharp" line="1">protected override void OnModelCreating(ModelBuilder modelBuilder) | ||
{ | { | ||
| 455. sor: | 455. sor: | ||
!ki / mi készíti? | !ki / mi készíti? | ||
|- | |- | ||
|1. | |'''1.''' | ||
|OO-modell | |OO-modell | ||
| rowspan="2" |a fejlesztő C#-ban | | rowspan="2" |a fejlesztő C#-ban | ||
|- | |- | ||
|2. | |'''2.''' | ||
|ORM | |ORM | ||
|- | |- | ||
|3. | |'''3.''' | ||
|DB-objektumok | |DB-objektumok | ||
|EF Core Migration Tool | |EF Core Migration Tool | ||
| 473. sor: | 473. sor: | ||
!ki / mi készíti? | !ki / mi készíti? | ||
|- | |- | ||
|1. | |'''1.''' | ||
|DB-objektumok | |DB-objektumok | ||
|a fejlesztő SQL-ben | |a fejlesztő SQL-ben | ||
|- | |- | ||
|2. | |'''2.''' | ||
|ORM | |ORM | ||
| rowspan="2" |EF Core Reverse Engineering Tool | | rowspan="2" |EF Core Reverse Engineering Tool | ||
|- | |- | ||
|3. | |'''3.''' | ||
|OO-modell | |OO-modell | ||
|} | |} | ||
=== Hogy néz ki egy entitás, hogyan készítünk kapcsolatokat közöttük? === | === Hogy néz ki egy entitás, hogyan készítünk kapcsolatokat közöttük? === | ||
{| class="wikitable mw-collapsible mw-collapsed" | {| class="wikitable mw-collapsible mw-collapsed" | ||
|+Összehasonlítás | |||
! | ! | ||
!1:N | !1:N | ||
!N:N | !N:N | ||
|- | |- | ||
|annotációkkal | |'''annotációkkal''' | ||
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Blog | |Entitások:<syntaxhighlight lang="csharp" line="1">public class Blog | ||
{ | { | ||
| 546. sor: | 545. sor: | ||
}</syntaxhighlight> | }</syntaxhighlight> | ||
|- | |- | ||
|Fluent API-val | |'''Fluent API-val''' | ||
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Blog | |Entitások:<syntaxhighlight lang="csharp" line="1">public class Blog | ||
{ | { | ||
| 642. sor: | 641. sor: | ||
!<code>dbContext</code>-függvényhívás | !<code>dbContext</code>-függvényhívás | ||
|- | |- | ||
|create | |'''create''' | ||
|<code>.Dogs.Add(newDog);</code> | |<code>.Dogs.Add(newDog);</code> | ||
|- | |- | ||
|read | |'''read''' | ||
|ld. az előző táblázatot | |ld. az előző táblázatot | ||
|- | |- | ||
|update | |'''update''' | ||
|<code>.Dogs.Find(dogId);</code> | |<code>.Dogs.Find(dogId);</code> | ||
<code>dog.BirthDate = birthDate;</code> | <code>dog.BirthDate = birthDate;</code> | ||
|- | |- | ||
|delete | |'''delete''' | ||
|adatbetöltéssel: | |adatbetöltéssel: | ||
<code>.Dogs.Find(dogId);</code> | <code>.Dogs.Find(dogId);</code> | ||
| 738. sor: | 737. sor: | ||
! colspan="2" |a DB-ben | ! colspan="2" |a DB-ben | ||
|- | |- | ||
!nem létezik | |||
!létezik | |||
|- | |- | ||
| rowspan="2" |a memóriában (perzisztenciakontextusban) | | rowspan="2" |'''a memóriában (perzisztenciakontextusban)''' | ||
|nem létezik | |'''nem létezik''' | ||
|– | |– | ||
|'' | |''lecsatolt'' | ||
|- | |- | ||
|létezik | |'''létezik''' | ||
|'' | |''új'' | ||
|'' | |''menedzselt'' vagy ''törölt'' | ||
|} | |} | ||
==== Állapotátmenetek ==== | ==== Állapotátmenetek ==== | ||
<syntaxhighlight> │ | |||
│ | |||
new() │ | |||
│ | |||
▼ | |||
┌──────────────┐ | |||
│ │ | |||
│ új │ | |||
│ │ | |||
└──────────────┘ | |||
│ | |||
│ | |||
persist() │ merge() | |||
│ | |||
▼ | |||
┌───────────────┐remove() ┌──────────────┐ | |||
┌────►│ │────────────►│ │ | |||
refresh() │ │ menedzselt │ │ törölt │ | |||
└─────│ │◄────────────│ │ | |||
└───────────────┘ persist()└──────────────┘ | |||
│ ▲ | |||
megszűnik a │ │ | |||
perzisztenciakontextus │ │ | |||
│ │ merge() | |||
▼ │ | |||
┌──────────────┐ | |||
│ │ | |||
│ lecsatolt │ | |||
│ │ | |||
└──────────────┘</syntaxhighlight> | |||
== 6. JPA – használat == | == 6. JPA – használat == | ||
=== Milyen módokon lehet lekérdezést megfogalmazni a JPA-ban? === | === Milyen módokon lehet lekérdezést megfogalmazni a JPA-ban? === | ||
... | {| class="wikitable mw-collapsible mw-collapsed" | ||
|+Összehasonlítás | |||
!komplexitás | |||
!módszer | |||
!példa | |||
|- | |||
|'''egyszerű''' | |||
|'''elsődleges kulcs alapján''' | |||
|<syntaxhighlight lang="java" line="1">Person p = entityManager.find(Person.class, 42L);</syntaxhighlight> | |||
|- | |||
| rowspan="2" |'''feltételekkel''' | |||
|'''Criteria API''' | |||
|<syntaxhighlight lang="java" line="1">CriteriaBuilder cb = entityManager.getCriteriaBuilder(); | |||
CriteriaQuery<Person> cq = cb.createQuery(Person.class); | |||
Root<Person> root = cq.from(Person.class); | |||
cq.select(root) | |||
.where(cb.equal(root.get("name"), "David")); | |||
Person p = entityManager.createQuery(cq).getSingleResult();</syntaxhighlight> | |||
|- | |||
|'''Query by Example<ref>Nem tananyag, de Tanár Úr jelezte, hogy a Java 2. házit ennek segítségével lehet megoldani legszebben.</ref>''' | |||
|<syntaxhighlight lang="java" line="1">Person probe = new Person(); | |||
ExampleMatcher matcher = ExampleMatcher | |||
.matching() | |||
.withMatcher("firstName", match -> match.regex().ignoreCase()); | |||
probe.setFirstName("^Dav.*"); | |||
Example<Person> example = Example.of(probe, matcher); | |||
List<Person> results = repo.findAll(example);</syntaxhighlight> | |||
|- | |||
| rowspan="2" |'''nyersen''' | |||
'''''(el is lehet nevezni őket)''''' | |||
|'''JPQL''' | |||
|<syntaxhighlight lang="java" line="1">TypedQuery<Person> q = entityManager.createQuery( | |||
"SELECT p FROM Person p WHERE p.age > :age", Person.class | |||
); | |||
q.setParameter("age", 30); | |||
List<Person> list = q.getResultList();</syntaxhighlight> | |||
|- | |||
|'''SQL''' | |||
|<syntaxhighlight lang="java" line="1">List<Object[]> rows = entityManager.createNativeQuery( | |||
"SELECT first_name, last_name FROM person WHERE age > :min" | |||
) | |||
.setParameter("min", 30) | |||
.getResultList(); | |||
for (Object[] row : rows) { | |||
String firstName = (String) row[0]; | |||
String lastName = (String) row[1]; | |||
}</syntaxhighlight> | |||
|} | |||
=== Hogyan bővíti a lehetőségeket a Spring Data JPA a lekérdezések megfogalmazásának területén? === | === Hogyan bővíti a lehetőségeket a Spring Data JPA a lekérdezések megfogalmazásának területén? === | ||
. | {| class="wikitable" | ||
!jellemző | |||
!példakód | |||
!miben segít? | |||
|- | |||
|'''repositoryk''' | |||
'''használata''' | |||
|<syntaxhighlight lang="java" line="1"> | |||
interface BusRepository extends JpaRepository<Bus, Long> { } | |||
</syntaxhighlight> | |||
| rowspan="3" | | |||
* az implementációt a Spring generálja | |||
* kevesebb boilerplate kód | |||
|- | |||
|'''konvenciók''' | |||
'''használata''' | |||
|<syntaxhighlight lang="java" line="1"> | |||
List<Bus> findByLpn(String lpn); | |||
</syntaxhighlight> | |||
|- | |||
|'''rendezés''' | |||
'''és lapozás | |||
támogatása''' | |||
|<syntaxhighlight lang="java" line="1"> | |||
interface BusRepository extends PagingAndSortingRepository<Bus, Long> { | |||
Iterable<Bus> findAll(Sort sort); | |||
Page<Bus> findAll(Pageable pageable); | |||
} | |||
</syntaxhighlight> | |||
|- | |||
|'''egyedi''' | |||
'''lekérdezés''' | |||
|<syntaxhighlight lang="java" line="1">@Query("SELECT DISTINCT b FROM Bus b WHERE b.lpn LIKE :lpn")</syntaxhighlight> | |||
| | |||
* hosszú metódusnevek helyett kézzel meg lehet írni, és a kívánt nevet lehet adni a metódusnak | |||
|} | |||
=== Hogyan valósíthatók meg entitások közti kapcsolatok és az entitások öröklése JPA-ban? === | === Hogyan valósíthatók meg entitások közti kapcsolatok és az entitások öröklése JPA-ban? === | ||
.. | |||
==== Kapcsolatok ==== | |||
{| class="wikitable mw-collapsible mw-collapsed" | |||
|+Példa annotációkra | |||
!típus | |||
!egyirányú | |||
!kétirányú | |||
|- | |||
|<code>'''@OneToOne'''</code> | |||
|<syntaxhighlight lang="java" line="1"> | |||
@Entity | |||
class A { | |||
@OneToOne | |||
@JoinColumn(name="b_id") | |||
B b; | |||
} | |||
@Entity | |||
class B { | |||
@Id | |||
Long id; | |||
} | |||
</syntaxhighlight> | |||
|<syntaxhighlight lang="java" line="1"> | |||
@Entity | |||
class A { | |||
@OneToOne | |||
@JoinColumn(name="b_id") | |||
B b; | |||
} | |||
@Entity | |||
class B { | |||
@OneToOne(mappedBy="b") | |||
A a; | |||
} | |||
</syntaxhighlight> | |||
|- | |||
|<code>'''@OneToMany'''</code> | |||
'''és | |||
<code>@ManyToOne</code>''' | |||
|<syntaxhighlight lang="java" line="1"> | |||
@Entity | |||
class A { | |||
@OneToMany(cascade=CascadeType.ALL) | |||
@JoinColumn(name="a_id") | |||
List<B> bs; | |||
} | |||
@Entity | |||
class B { | |||
@Id | |||
Long id; | |||
} | |||
</syntaxhighlight> | |||
|<syntaxhighlight lang="java" line="1">@Entity | |||
class A { | |||
@OneToMany( | |||
mappedBy="a", | |||
cascade=CascadeType.ALL, | |||
orphanRemoval=true | |||
) | |||
List<B> bs; | |||
} | |||
@Entity | |||
class B { | |||
@ManyToOne | |||
@JoinColumn(name="a_id") | |||
A a; | |||
}</syntaxhighlight> | |||
|- | |||
|<code>'''@ManyToMany'''</code> | |||
|<syntaxhighlight lang="java" line="1">@Entity | |||
class A { | |||
@ManyToMany | |||
@JoinTable( | |||
name="A_B", | |||
joinColumns= | |||
@JoinColumn(name="a_id"), | |||
inverseJoinColumns= | |||
@JoinColumn(name="b_id") | |||
) | |||
Set<B> bs; | |||
} | |||
@Entity | |||
class B { | |||
@Id | |||
Long id; | |||
}</syntaxhighlight> | |||
|<syntaxhighlight lang="java" line="1"> | |||
@Entity | |||
class A { | |||
@ManyToMany | |||
@JoinTable( | |||
name="A_B", | |||
joinColumns= | |||
@JoinColumn(name="a_id"), | |||
inverseJoinColumns= | |||
@JoinColumn(name="b_id") | |||
) | |||
Set<B> bs; | |||
} | |||
@Entity | |||
class B { | |||
@ManyToMany(mappedBy="bs") | |||
Set<A> as; | |||
} | |||
</syntaxhighlight> | |||
|} | |||
==== Öröklés ==== | |||
{| class="wikitable" | |||
|+típusai | |||
!módszer | |||
!<code>@Inheritance(strategy = …)</code> | |||
|- | |||
|[[Háttéralkalmazások/Záróvizsgatételek#Egy táblába, gányul|'''egy táblába, gányul''']] | |||
|<code>SINGLE_TABLE</code> | |||
|- | |||
|[[Háttéralkalmazások/Záróvizsgatételek#Külön táblába a valós osztályokat|'''külön táblába a valós osztályokat''']] | |||
|<code>TABLE_PER_CLASS</code> | |||
|- | |||
|[[Háttéralkalmazások/Záróvizsgatételek#Külön táblába az összes osztályt|'''külön táblába az összes osztályt''']] | |||
|<code>JOINED</code> | |||
|- | |||
|[[Háttéralkalmazások/Záróvizsgatételek#Absztrakt struktúrába|'''absztrakt struktúrába''']] | |||
|– | |||
|} | |||
* <code>@Id</code> attribútuma csak a legfelső ősnek lehet | |||
* absztrakt is lehet egy entitás | |||
** de természetesen nem lehet példányosítani | |||
* nem-entitásból is származhat entitás | |||
** ha szükségünk van az örökölt attribútumokra, akkor <code>@MappedSuperClass</code> annotációt kell tenni az ősre | |||
* entitásból is származhat nem-entitás | |||
** de nem "veszi kezelésbe" a JPA | |||
== 7. Spring == | == 7. Spring == | ||
=== Mik a függőséginjektálás főbb előnyei | === Mik a függőséginjektálás főbb előnyei? === | ||
... | |||
* az injektornak ki van szervezve a függőség betöltése és az objektumgráfok előállítása | |||
** kevesebb kódduplikáció | |||
* könnyű mockolni a függőségeket | |||
=== Hogyan támogatja a Spring? === | |||
A következő annotációkkal: | |||
{| class="wikitable mw-collapsible mw-collapsed" | |||
|+Opciók (a legrosszabbtól a legjobbig) | |||
!lehet injektálni | |||
!példa | |||
|- | |||
|'''mezőbe''' | |||
|<syntaxhighlight lang="java" line="1"> | |||
@Service | |||
public class UserService { | |||
@Autowired | |||
private UserRepository userRepository; | |||
public void getAllUsers() { | |||
userRepository.findAll(); | |||
} | |||
} | |||
</syntaxhighlight> | |||
|- | |||
|'''setterbe''' | |||
|<syntaxhighlight lang="java" line="1"> | |||
@Service | |||
public class UserService { | |||
private UserRepository userRepository; | |||
public void setUserRepository(UserRepository userRepository) { | |||
this.userRepository = userRepository; | |||
} | |||
public void getAllUsers() { | |||
userRepository.findAll(); | |||
} | |||
} | |||
</syntaxhighlight> | |||
|- | |||
|'''konstruktorba''' | |||
|<syntaxhighlight lang="java" line="1"> | |||
@Service | |||
public class UserService { | |||
private final UserRepository userRepository; | |||
public UserService(UserRepository userRepository) { | |||
this.userRepository = userRepository; | |||
} | |||
public void getAllUsers() { | |||
userRepository.findAll(); | |||
} | |||
} | |||
</syntaxhighlight> | |||
|} | |||
Más beaneket is lehet injektálni, melyeket kollaborátoroknak hívják. Több lehetséges jelölt esetén konfigurálni kell, hogy melyiket szeretnénk injektálni. | |||
=== Milyen élettartama lehet egy springes beannek? === | === Milyen élettartama lehet egy springes beannek? === | ||
... | {| class="wikitable" | ||
|+Scope-ok (a leghosszabbtól a legrövidebb életűig) | |||
!típus | |||
!annotáció | |||
!minek az életciklusához van kötve | |||
|- | |||
|'''singleton''' | |||
|''– (ez az alapértelmezett)'' | |||
|semminek, csak egy van belőle az egész alkalmazásban | |||
|- | |||
|'''application''' | |||
|<code>@Scope("application")</code> | |||
|<code>ServletContext</code><ref>Webalkalmazásoknál használatos.</ref> | |||
|- | |||
|'''prototype''' | |||
|<code>@Scope("prototype")</code> | |||
|új példány jön létre minden <code>getBean()</code> (<code>@Autowired</code>) hívásra | |||
|- | |||
|'''websocket''' | |||
|<code>@Scope(scopeName="websocket", proxyMode=...)</code> | |||
|<code>WebSocket</code> session | |||
|- | |||
|'''session''' | |||
|<code>@Scope("session")</code> | |||
|HTTP session | |||
|- | |||
|'''request''' | |||
|<code>@Scope("request")</code> | |||
|HTTP-kérés | |||
|} | |||
=== [[Háttéralkalmazások/Záróvizsgatételek#Hogyan bővíti a lehetőségeket a Spring Data JPA a lekérdezések megfogalmazásának területén?|Hogyan könnyíti meg a JPA használatát a Spring Data JPA?]] === | |||
=== Hogyan támogatja a tranzakciókezelést a Spring? === | |||
Egységes API-ja van, ami mögé ezeket a tranzakciókezelőket lehet berakni: | |||
{| class="wikitable" | |||
|+Tranzakciókezelők (az alacsonyabb szinttől a magasabbig) | |||
!típus | |||
!jellemzői | |||
|- | |||
|'''JDBC''' | |||
|– | |||
|- | |||
|'''EntityTransaction (JPA)''' | |||
|ld.: ''[[Háttéralkalmazások/Záróvizsgatételek#Ismertesd a Java Persistence API architektúráját és főbb jellemzőit!|Ismertesd a Java Persistence API architektúráját és főbb jellemzőit!]]'' | |||
|- | |||
|'''JDO (Java Data Objects)''' | |||
|a ''JTA'' elődje | |||
|- | |||
|'''JTA (Jakarta Transactions)''' | |||
|szolgáltatásokon átívelő tranzakciókat lehet végrehajtani | |||
|} | |||
{| class="wikitable" | |||
|+Tranzakciókezelés módjai (a kevésbé népszerűtől a népszerűbbig) | |||
!típus | |||
!hogyan indítjuk / | |||
zárjuk le a tranzakciókat? | |||
!példa | |||
|- | |||
|'''programozott''' | |||
|a kódban | |||
|<syntaxhighlight lang="java" line="1"> | |||
@Service | |||
public class OrderService { | |||
private final PlatformTransactionManager transactionManager; | |||
public OrderService(PlatformTransactionManager transactionManager) { | |||
this.transactionManager = transactionManager; | |||
} | |||
public void processOrder() { | |||
TransactionStatus transactionStatus = transactionManager | |||
.getTransaction(new DefaultTransactionDefinition()); | |||
try { | |||
validateOrder(); | |||
chargeCustomer(); | |||
saveOrderToDatabase(); | |||
transactionManager.commit(transactionStatus); | |||
System.out.println("Transaction committed successfully!"); | |||
} catch (RuntimeException ex) { | |||
transactionManager.rollback(transactionStatus); | |||
System.out.println( | |||
"Transaction was rolled back due to the following error: " + ex.getMessage() | |||
); | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
|- | |||
|'''deklaratív''' | |||
|metódusannotációkkal | |||
|<syntaxhighlight lang="java" line="1"> | |||
@Service | |||
public class OrderService { | |||
@Transactional | |||
public void processOrder() { | |||
validateOrder(); | |||
chargeCustomer(); | |||
saveOrderToDatabase(); | |||
// kezeletlen kivétel esetén a Spring automatikusan rollbackel | |||
} | |||
== | } | ||
... | </syntaxhighlight> | ||
|} | |||
{| class="wikitable" | |||
|+A <code>@Transactional</code> paraméterei | |||
!paraméter | |||
!értéke | |||
|- | |||
|<code>(no)rollbackFor(ClassName)</code> | |||
|milyen kivételek esetén legyen rollback | |||
|- | |||
|<code>timeout</code> | |||
|az időkorlát másodpercben | |||
|- | |||
|<code>isolation</code> | |||
|izolációs szint (a JPA nem támogatja) | |||
|- | |||
|<code>value</code> | |||
|a tranzakciókezelő azonosítója (több adatbázis esetén fontos) | |||
|- | |||
|<code>propagation</code> | |||
|kompatibilitás egy tranzakcionális metódusból hívott másik tranzakcionális metódussal | |||
|} | |||
{| class="wikitable" | |||
|+A <code>propagation</code> értékei (a megengedőbbtől a szigorúbbig) | |||
! rowspan="2" |érték | |||
! colspan="2" |mit tesz a jelenlegi függvény... | |||
! colspan="2" |mi történik a következő függvénnyel? | |||
|- | |||
!...ha van aktív tranzakció? | |||
!...ha nincs aktív tranzakció? | |||
!...ha van aktív tranzakció? | |||
!...ha nincs aktív tranzakció? | |||
|- | |||
|'''<code>REQUIRED</code>''' | |||
(alapértelmezett) | |||
|azt folytatja | |||
|újat hoz létre | |||
|a jelenlegit folytatja | |||
|– | |||
|- | |||
|'''<code>NESTED</code>''' | |||
|folytatódik, és egy <code>SAVEPOINT</code>-ot hoz létre | |||
|újat hoz létre | |||
|a jelenlegit folytatja – rollback esetén csak a <code>SAVEPOINT</code>-ig áll vissza | |||
|– | |||
|- | |||
|'''<code>REQUIRES_NEW</code>''' | |||
|felfüggeszti | |||
|újat hoz létre | |||
|új tranzakciót használ | |||
|– | |||
|- | |||
|'''<code>SUPPORTS</code>''' | |||
|azt folytatja | |||
|tranzakció nélkül fut | |||
|azt folytatja | |||
|tranzakció nélkül fut | |||
|- | |||
|'''<code>MANDATORY</code>''' | |||
|azt folytatja | |||
|kivételt dob | |||
|azt folytatja | |||
|– | |||
|- | |||
|'''<code>NOT_SUPPORTED</code>''' | |||
|felfüggeszti | |||
|– | |||
|– | |||
|tranzakció nélkül fut | |||
|- | |||
|'''<code>NEVER</code>''' | |||
|kivételt dob | |||
|tranzakció nélkül fut | |||
|– | |||
|tranzakció nélkül fut | |||
|} | |||
== 8. ASP.NET Core == | == 8. ASP.NET Core == | ||
{{Átnézendő szakasz}} | |||
=== Mi az ASP.NET Core? === | === Mi az ASP.NET Core? === | ||
... | Az ASP.NET Core egy .NET-alapú nagyteljesítményű, nyílt forráskódú, platformfüggetlen webalkalmazás‑framework. | ||
=== Mit jelent, hogy egy alkalmazás monolitikus? === | === Mit jelent, hogy egy alkalmazás monolitikus? === | ||
... | Monolitikusnak nevezzük azt az alkalmazást, amelynek összes komponense – pl. UI, üzleti logika és adatkezelés – egyetlen deploy‑egységben (pl. egy futtatható vagy szerveralkalmazásban) fut, nem részeire bontva. | ||
=== Mi a ''clean architecture''? === | === Mi a ''clean architecture''? === | ||
... | A clean architecture egy szoftvertervezési minta, melynek alapvetése a kód rétegekre (pl. domain, application, infrastructure, presentation) bontása. Alkalmazza a dependency inversiont is: a külső rétegek függnek csak az absztrakcióktól, nem fordítva. | ||
=== Sorolj fel min. 3 általános ASP.NET Core által nyújtott | === Sorolj fel min. 3 általános, ASP.NET Core által nyújtott infrastruktúrafunkciót! === | ||
... | * beépített DI | ||
* middleware alapú HTTP–pipeline-kezelés (pl. autentikáció, logging) | |||
* konfigurálhatóság (<code>appsettings.json</code> + környezeti változók) | |||
* moduláris hosting (pl. Kestrel), cross‑platform deployment (IIS, Nginx, Docker stb.) | |||
=== Hogyan indul el egy ASP.NET Core projekt? === | === Hogyan indul el egy ASP.NET Core projekt? === | ||
.. | # <code>dotnet new webapi</code> vagy <code>dotnet new mvc</code> parancs | ||
# a <code>Program.cs</code> és/vagy <code>Startup.cs</code> definiálja a hosztot, regisztrálja a service‑eket és a middleware‑eket | |||
# a <code>dotnet run</code> indítja el a Kestrel szervert | |||
# elérhető az alkalmazás | |||
=== Milyen lépései vannak, hogy egy Web API-n kiajánljunk egy EF Core által nyújtott adatmodellt (lekérdezésre, módosításra)? === | === Milyen lépései vannak, hogy egy Web API-n kiajánljunk egy EF Core által nyújtott adatmodellt (lekérdezésre, módosításra)? === | ||
... | # projekt generálása (<code>dotnet new webapi</code>) | ||
# EF Core-csomagok telepítése (<code>Microsoft.EntityFrameworkCore</code>, SQL server provider) | |||
# <code>DbContext</code> osztály és entitásmodellek létrehozása | |||
# <code>AddDbContext<...>(...)</code> DI a <code>Program.cs</code>-ben / <code>Startup.cs</code>-ben | |||
# kontroller létrehozása (<code>ApiController</code>), mely injektálja a <code>DbContext</code>‑et | |||
# lekérdező metódusok írása: <code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>DELETE</code> endpointok | |||
# használat: <code>context.Entities.ToList()</code>, <code>Find(id)</code>, <code>Add()</code>, <code>Update()</code>, <code>Remove()</code>, majd <code>SaveChanges()</code> | |||
== 9. Razor == | == 9. Razor == | ||
{{Átnézendő szakasz}} | |||
=== Milyen módokon szeparálhatjuk a kliens–szerver alkalmazásrétegeket? === | === Milyen módokon szeparálhatjuk a kliens–szerver alkalmazásrétegeket? === | ||
... | * tiszta szerveroldali renderelés – minden HTML generálását a szerver végzi (pl. ASP.NET MVC, Razor Pages). | ||
* tiszta kliensoldali alkalmazás (SPA) – az UI a böngészőben fut, a szerveren csak API-szolgáltatás van (pl. Angular, React). | |||
* hibrid megközelítés – a kezdeti renderelés szerveren történik, utána a kliens veszi át az irányítást (Pl. Blazor Server, SSR + CSR kombinációk) | |||
=== Mi a szerveroldali renderelés? === | === Mi a szerveroldali renderelés? === | ||
. | A szerver generálja az egész HTML-t a kérésre, és küldi el a kliensnek. Így a böngésző azonnal meg tudja jeleníteni a teljes oldalt. | ||
=== Milyen előnyei/hátrányai vannak a kliensoldalival szemben? === | === Milyen előnyei/hátrányai vannak a kliensoldalival szemben? === | ||
==== Előnyök ==== | |||
* gyorsabb első betöltés – kész HTML érkezik | |||
* jobb SEO-támogatás | |||
==== Hátrányok ==== | |||
* magasabb szerverterhelés, minden kérésnél újrarenderelés | |||
* lassabb interaktivitás és navigáció a teljes oldalletöltések miatt | |||
=== Mi a Razor? === | === Mi a Razor? === | ||
... | A Razor egy HTML-templating szintaxis C# (vagy VB) integrálásával; 2010 óta része az ASP.NET MVC-nek / ASP.NET Core‑nak. <code>.cshtml</code> / <code>.razor</code> fájlokban használatos. | ||
=== Hogyan készül el egy HTML-oldal Razor segítségével és MVC vagy Razor Pages használatával? === | === Hogyan készül el egy HTML-oldal Razor segítségével és MVC vagy Razor Pages használatával? === | ||
==== MVC ==== | |||
# létre kell hozni egy <code>Controller</code> metódust return <code>View(model);</code>-lel | |||
# a <code>ViewName.cshtml</code> fájlban Razor-kód (<code>@model</code>, <code>@foreach</code> stb.) generálja a HTML-t | |||
==== Razor Pages ==== | |||
# létre kell hozni egy <code>.cshtml</code> fájlpárt (<code>Index.cshtml</code> + <code>Index.cshtml.cs</code>), ahol: | |||
## a <code>*.cshtml.cs</code> tartalmazza az oldal logikáját az <code>OnGet()</code> és <code>OnPost()</code> metódusokkal | |||
## a <code>*.cshtml</code> Razor-jelölésekkel hivatkozik a <code>@Model</code> objektumra | |||
== 10. Microservices == | == 10. Microservices == | ||
=== Milyen előnyökkel és hátrányokkal jár a mikroszolgáltatás architektúra a monolitikussal szemben? === | === Milyen előnyökkel és hátrányokkal jár a mikroszolgáltatás architektúra a monolitikussal szemben? === | ||
=== | ==== Előnyök ==== | ||
Előnye, hogy az alkalmazás modulárissá válik. Ebből következik a... | |||
* kisebb kódbázis | |||
** gyorsabb | |||
*** tesztek | |||
*** build | |||
*** IDE | |||
** könnyebb teszteket írni | |||
** könnyebb bekapcsolódni a munkába | |||
** kisebb csapat tud rajta dolgozni | |||
*** kevesebb koordináció szükséges | |||
* külön kezelhető szolgáltatások | |||
** többféle technológia használható | |||
** robosztusabb | |||
*** terheléselosztás | |||
*** SPOF kiküszöbölése | |||
*** automatikus újraindítás | |||
** jobb skálázhatóság | |||
*** elég a bottleneck(ek)et felskálázni | |||
**** gyorsabb indulás | |||
*** alacsonyabb terhelés esetén leskálázni is lehet | |||
** rugalmasabb frissítések | |||
*** könnyebb a rollback is | |||
** részekre bontott költségek | |||
*** üzemeltetésnél | |||
*** frissítéseknél | |||
**** könnyebben eladható a megrendelő számára | |||
***** akár egy szolgáltatás teljes újraírása is | |||
==== | ==== Hátrányok ==== | ||
. | A modularitásnak természetesen vannak hátrányai is. Ezek a következőek: | ||
* komplexebb architektúra, melynek tervezéséhez és üzemeltetéséhez nagyobb szaktudás (pl. utóbbihoz egy képzett DevOpsos) kell | |||
** több (teszt)példány | |||
*** több tesztszerver | |||
** azok között több kapcsolat | |||
*** a hálózati (szolgáltatások közti) kommunikáció továbbra is kötött | |||
** többféle szerveren is futhatnak | |||
** többféle technológiát is használhatnak | |||
** bonyolultabb a verziókezelés | |||
*** nehezebb a kompatibilitás | |||
** nehezebb a CI/CD | |||
*** bonyolultabb a deploy | |||
* több hálózati kommunikáció | |||
** point of faliure | |||
** overhead | |||
* nehezebben megvalósítható atomicitás | |||
* kódduplikáció | |||
Ezekre (részben vagy egészben) megoldást ad... | |||
... | |||
=== | * egy jól elkészített CI/CD | ||
* egy hálózatkiesésre felkészített szolgáltatás | |||
* a fejlesztőcsapatok közti jó kommunikáció | |||
* közös könyvtárak készítése | |||
** amely megint korlátozza a szolgáltatásokban használható nyelveket | |||
=== Ismertesd az alábbi microservice tervezési minták céljait, azok előnyeit, hátrányait! === | |||
{| class="wikitable mw-collapsible mw-collapsed" | |||
|+Összehasonlítás | |||
!tervezési minta | |||
!leírása | |||
!előnyei | |||
!hátrányai | |||
|- | |||
|shared database | |||
|több szolgáltatás egy sémát használ | |||
| | |||
* nem kell több adatbázis | |||
* szabadon lehet joinolni | |||
* egy megkezdett tranzakciót folytathat egy másik szolgáltatás | |||
* az ACID az adatbázis által biztosított | |||
| | |||
* ellentétes a microservices alapelveivel | |||
* egyféle RDBMS használható | |||
* bottleneck | |||
* függőséget teremt a szolgáltatások közt | |||
* ha egy szolgáltatásnak szüksége van indexre, akkor a többi teljesítményét is rontja | |||
* egyeztetni kell a sémamódosításokról | |||
|- | |||
|database per service | |||
|mindegyik szolgáltatás külön privát táblát / külön sémát / külön adatbázist használ | |||
| | |||
* külön adatbázisok esetén nincs SPOF | |||
* akár többféle RDBMS is használható | |||
| | |||
* külön adatbázisok esetén nehezebb és drágább az üzemeltetés | |||
* nehezebb joinolni | |||
* nehezebb tranzakciókat átadni másik szolgáltatásnak | |||
* e kettő általában hibás tervezés jele | |||
* de meg lehet oldani az alábbi két minta valamelyikével | |||
|- | |||
|database per service + '''API composition''' | |||
|a külön privát táblák / külön sémák / külön adatbázisok adatait egy új szolgáltatás joinolja | |||
| | |||
* lehet joinolni | |||
| | |||
* a memóriakorlát miatt továbbra sem lehet szabadon joinolni | |||
|- | |||
|database per service + '''command query responsibility segregation''' | |||
|a külön privát táblák / külön sémák / külön adatbázisok adatait egy külön szolgáltatás módosítja, és azokat egy read-only view adatbázisban is összegyűjtjük (a master–slave replicationhöz hasonlóan) | |||
| | |||
* szabadon lehet joinolni | |||
* a gyakori lekérdezésre lehet optimalizálni a view adatbázis sémáját, ami akár a joinolást is kiküszöbölheti | |||
| | |||
* ez a legbonyolultabb | |||
* esetleges kódduplikáció | |||
* a view adatbázist valahogy szinkronizálni kell a fő adatbázissal | |||
* késleltetés vagy inkonzisztencia is felléphet | |||
|} | |||
== 11. Microservices == | == 11. Microservices == | ||
| 838. sor: | 1 466. sor: | ||
=== [[Háttéralkalmazások/Záróvizsgatételek#Milyen előnyökkel és hátrányokkal jár a mikroszolgáltatás architektúra a monolitikussal szemben?|Milyen előnyökkel és hátrányokkal jár a mikroszolgáltatás architektúra a monolitikussal szemben?]] === | === [[Háttéralkalmazások/Záróvizsgatételek#Milyen előnyökkel és hátrányokkal jár a mikroszolgáltatás architektúra a monolitikussal szemben?|Milyen előnyökkel és hátrányokkal jár a mikroszolgáltatás architektúra a monolitikussal szemben?]] === | ||
=== Ismertesd az | === Ismertesd az alábbi microservice tervezési minták céljait, azok előnyeit, hátrányait! === | ||
. | {| class="wikitable" | ||
|+összehasonlítás | |||
!tervezési minta | |||
!leírása | |||
!előnyei | |||
!hátrányai | |||
|- | |||
|API gateway | |||
|az egyes szolgáltatások közvetlen elérése helyett egy átjárót hívjanak meg a kliensek | |||
| | |||
* egy IP-címet kell ismerni | |||
* protokollváltást is biztosíthat | |||
| | |||
* még egy szolgáltatás | |||
* szükség van service discoveryre és circuit breakerre | |||
* még egy hálózati ugrás | |||
* <ref>Külső eszközökkel történő kommunikáció esetén természetesen autentikáció is szükséges.</ref> | |||
|} | |||
=== Ismertesd a tanult '' | === Ismertesd a tanult ''service discovery'' mintákat! === | ||
. | {| class="wikitable" | ||
|+összehasonlítás | |||
! colspan="2" |típus | |||
!minta | |||
!leírása | |||
!előnyei | |||
!hátrányai | |||
|- | |||
| rowspan="4" |a nyilvántartás | |||
| rowspan="2" |vezetése | |||
|self registration (push) | |||
|minden szolgáltatás maga felelős a regisztrációért és annak törléséért | |||
| | |||
* a szolgáltatás mindig ismeri a saját állapotát | |||
| | |||
* minden szolgáltatásnál implementálni kell | |||
* váratlan leállás esetén nem törli a regisztrációt | |||
|- | |||
|3<sup>rd</sup> party registration | |||
|külön komponens felelős a regisztrációért és annak törléséért | |||
| | |||
* nem kell implementálni mindegyik szolgáltatásnál | |||
* elég egy health check endpoint | |||
| | |||
* külön szolgáltatás szükséges | |||
* ami ráadásul soha nem állhat le | |||
|- | |||
| rowspan="2" |használata | |||
|client-side service discovery | |||
|pl. ilyen a round-robin DNS | |||
| | |||
* egyből meghívja a kliens az adott szolgáltatást | |||
| | |||
* a nyilvántartást továbbra is kell használnia | |||
* aminek implementálni kell az elérését | |||
* meg kell valósítani a terheléselosztást is | |||
|- | |||
|server-side service discovery | |||
|egy router biztosítja a terheléselosztást | |||
| | |||
* nem szükséges további kliensoldali implementáció | |||
* felhőszolgáltatások is biztosítanak ilyet | |||
| | |||
* külön szolgáltatás szükséges | |||
* ami ráadásul soha nem állhat le | |||
* még egy hálózati ugrás | |||
* a routernek akár több protokollt is kell támogatnia | |||
|} | |||
== 12. Cloud == | == 12. Cloud == | ||
=== A számítási felhő fő jellemzői | === A számítási felhő fő jellemzői === | ||
. | |||
* önkiszolgálás bármikor | |||
* nagy rugalmasság | |||
** skálázhatóság | |||
*** akár egy komplex vállalati rendszer is kialakítható | |||
** számlázás fogyasztás alapján | |||
* felhasználók közt megosztott erőforrások | |||
* széleskörű hálózati elérés | |||
** internet | |||
** IoT | |||
=== A számítási felhő fizikai, térbeli kiépítése === | |||
==== Fizikai ==== | |||
* nagy, légkondicionált raktárépületek | |||
* bennük általában már "csak" előreszerelt konténerekkel | |||
==== Térbeli ==== | |||
A nagyobbtól a kisebbig: | |||
* region | |||
* availability zone | |||
** redundancia | |||
* data center | |||
=== Főbb publikus felhőszolgáltatók === | |||
* AWS | |||
* Microsoft Azure | |||
* Google Cloud | |||
* OVH (EU) | |||
=== Felhős szolgáltatásmodellek === | |||
* infrastructure as a service | |||
* platform as a service | |||
* software as a service | |||
{| class="wikitable" | |||
|+Üzemeltetési modellek (a más által kezelttől a saját kezelésűig) | |||
!típus | |||
!jellemzői | |||
!példa | |||
|- | |||
|nyilvános | |||
| | |||
* más által üzemeltetett | |||
* szabadon elérhető | |||
|ld.: ''[[Háttéralkalmazások/Záróvizsgatételek#Főbb publikus felhőszolgáltatók|Főbb publikus felhőszolgáltatók]]'' | |||
|- | |||
|hibrid | |||
| | |||
* nyilvános szolgáltatás | |||
* saját környezetben | |||
|Azure Stack Hub, AWS Outposts | |||
|- | |||
|közösségi | |||
| | |||
* egy csoport tagjai közt megosztott, zárt infrastruktúra | |||
|EESZT | |||
|- | |||
|saját | |||
| | |||
* saját szolgáltatás | |||
* saját környezetben | |||
|– | |||
|} | |||
=== | === Szolgáltatásgaranciák (SLA) === | ||
* magas uptime | |||
* redundancia | |||
** áramellátás | |||
** hálózat | |||
** hardver | |||
*** tárhely | |||
** földrajzi | |||
*** természeti katasztrófák | |||
=== | === Skálázási lehetőségek === | ||
* vertikális | |||
** erőforrások növelése | |||
* horizontális | |||
** példányok bővítése | |||
* automatikusan is lehet | |||
=== | === Példák elérhető szolgáltatásokra === | ||
* AWS | |||
** S3 | |||
** SQS | |||
** EC2 | |||
* Google | |||
** Pub/Sub | |||
=== A felhős modell előnyei, hátrányai | === A felhős modell előnyei, hátrányai === | ||
{| class="wikitable" | |||
|+Összehasonlítás | |||
!előny | |||
!hátrány | |||
|- | |||
|költséghatékony | |||
|drágább is lehet | |||
|- | |||
|használatalapú árazás | |||
|bonyolult árazás | |||
|- | |||
|könnyen skálázható | |||
|nem végtelenül skálázható | |||
|- | |||
|SLA | |||
|a nagyon magas SLA-kért többet kell fizetni | |||
|- | |||
|menedzselt üzemeltetés és biztonság (DRP) | |||
|nem férünk hozzá fizikailag a szerverekhez | |||
|- | |||
|globális | |||
|helyi adatvédelmi megfelelőség esetleges hiánya | |||
|- | |||
|sokféle szolgáltatás | |||
|vendor lock-in (breaking changes) | |||
|} | |||
== 13. Azure == | == 13. Azure == | ||
{{Átnézendő szakasz}} | |||
=== Azure alapszolgáltatások viszonya egymáshoz | === Azure alapszolgáltatások viszonya egymáshoz === | ||
==== Előfizetés ==== | ==== Előfizetés ==== | ||
Azure-szolgáltatások igénybevételének elszámolási és hozzáférési egysége; egy Azure-fiók alatt több előfizetés is lehet, és az éves költési korlátok is erre épülnek. | |||
==== AD ==== | ==== AD ==== | ||
Identitás- és jogosultságkezelés központja, amelyhez előfizetések, felhasználók és szolgáltatások (alkalmazásregisztrációk) kapcsolódnak. | |||
==== Fiók (account) ==== | ==== Fiók (account) ==== | ||
Microsoft-fiók vagy szervezeti (Azure AD) fiók, amellyel be lehet jelentkezni és kapcsolatba lehet hozni az Azure-előfizetéseket. | |||
==== Erőforráscsoport ==== | ==== Erőforráscsoport ==== | ||
. | Logikai gyűjtőkonténer az előfizetésen belül, amelybe kapcsolódó erőforrásokat, pl. VM-eket vagy adatbázisokat csoportosítunk; segíti az RBAC-t és a költségkövetést. | ||
==== Erőforrás ==== | ==== Erőforrás ==== | ||
. | Valós szolgáltatásobjektum (pl. virtuális gép, tárhely, SQL-adatbázis), amely egy előfizetésen belül erőforráscsoportban jön létre. | ||
=== Erőforrások beállítható alapjellemzői | === Erőforrások beállítható alapjellemzői === | ||
.. | * '''név''' – globálisan vagy az előfizetésen belül egyedi azonosító | ||
* '''régió''' – földrajzi hely (pl. <code>eastus</code>, <code>westeurope</code>) | |||
* '''típus és SKU''' – szolgáltatás rétegének és teljesítményének kiválasztása (pl. basic, standard) | |||
* '''címkék''' – kulcs–érték párok a költség- és szervezési szempontú csoportosításhoz | |||
=== Régió kiválasztásának szempontjai | === Régió kiválasztásának szempontjai === | ||
. | * késleltetés | ||
* szabályozás és megfelelőség | |||
** egyes adattípusokra helyhez kötött tárolási előírások vonatkozhatnak | |||
* elérhetőség | |||
** nem minden régió támogat minden szolgáltatást. | |||
* költségek | |||
** régiónként eltérő árszintek lehetnek. | |||
=== Azure SQL és Azure App Service szolgáltatások... === | === Azure SQL és Azure App Service szolgáltatások... === | ||
==== ...bemutatása. ==== | ==== ...bemutatása. ==== | ||
... | * '''Azure SQL Database:''' teljesen menedzselt relációsadatbázis-szolgáltatás automatikus mentéssel, patcheléssel, méretezéssel és beépített teljesítményoptimalizálással. | ||
* '''Azure App Service:''' PaaS típusú app hosting szolgáltatás .NET, Java, Node.js, Python stb. számára. Könnyen skálázható és CI/CD-támogatott. | |||
==== ...felépítése (logikai) erőforrások szintjén. ==== | ==== ...felépítése (logikai) erőforrások szintjén. ==== | ||
* '''Azure SQL''': logikai SQL-szerver → adatbázis(ok) (→ Elastic Pool) | |||
* '''Azure App Service''': App Service Plan (compute és scale) → Web App → deployment slots, konfigurációk stb. | |||
==== ...árazási tényezői. ==== | ==== ...árazási tényezői. ==== | ||
* '''Azure SQL''': vCore- vagy DTU-alapú teljesítmény, adattárolás mérete, elérhetőség (zóna-redundancia), licencek (Azure Hybrid Benefit) | |||
* '''App Service''': service plan típusa (free, shared, basic, standard, premium, isolated), példányszám, skálázás típusa (manual, autoscale), operációs rendszer (Windows / Linux) | |||