„Háttéralkalmazások/Záróvizsgatételek” változatai közötti eltérés

4. EF Core: Tétel kidolgozása
a 5. JPA – általános: Magyarra átírás
 
(17 közbenső módosítás ugyanattól a felhasználótól nincs mutatva)
65. sor: 65. sor:
=== Ismertesse az adatbázisok szerveroldali programozásának koncepcióját, előnyeit, hátrányait! ===
=== Ismertesse az adatbázisok szerveroldali programozásának koncepcióját, előnyeit, hátrányait! ===
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"
{| class="wikitable mw-collapsible mw-collapsed"
|+a szerveroldali programozás jellemzői
|+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
|+Egymásnak megfeleltethető adattípusok
!üzleti logika
!üzleti logika
!adatbázis
!adatbázis
371. sor: 371. sor:


=== Mi az Entity Framework? ===
=== Mi az Entity Framework? ===
Az Entity Framework az ADO.NET-re és a .NET Frameworkre épülő ORM-keretrendszer. A 2016-ban kiadott, .NET Core-alapon újraírt, nyílt forráskódú verzió neve ''Entity Framework '''Core'''''.
Az Entity Framework egy Microsoft által fejlesztett, ADO.NET-re és .NET Frameworkre épülő ORM-keretrendszer. A 2016-ban kiadott, .NET Core-alapon újraírt, nyílt forráskódú verzió neve ''Entity Framework '''Core'''''. A Java nyelvbeli megfelelője a ''[[Háttéralkalmazások/Záróvizsgatételek#5. JPA – általános|Jakarta Persistence]]''.


Teljesen moduláris, az egyes részeit NuGet-csomagokból lehet importálni. A JDBC-hez hasonlóan drivereket biztosít az egyes RDBMS-ekhez. Az ORM mellett a LINQ-eket futásidőben SQL-kódra fordítja le és hajtja végre.
Teljesen moduláris, az egyes részeit NuGet-csomagokból lehet importálni. A JDBC-hez hasonlóan drivereket biztosít az egyes RDBMS-ekhez. Az ORM mellett a LINQ-eket futásidőben SQL-kódra fordítja le és hajtja végre.


=== Mikor használjuk, és mikor nem? ===
=== Mikor használjuk, és mikor nem? ===
==== Mikor nem használjuk ====
==== Mikor nem használjuk ====


396. sor: 395. sor:


=== Mi a <code>DbContext</code>? ===
=== Mi a <code>DbContext</code>? ===
Egy EF Core-beli osztály, mely egy adatbázis-munkamenetet reprezentál. Általában a DAL-ban hozunk létre egy <code>DbContext</code>-ből leszármazó osztályt. Az entitások felderítésében segíti az EF-et, ha <code>DbSet<Entity></code> tagváltozókat is megadunk. Egy <code>DbContextOptions</code> objektum átadásával – mely tartalmazza az adatbázis típusát és connection stringjét – lehet példányosítani.
Egy EF Core-beli osztály, mely egy adatbázis-munkamenetet reprezentál.
 
Általában a DAL-ban hozunk létre egy <code>DbContext</code>-ből leszármazó osztályt. Mivel a <code>DbContext</code> vezeti a nyilvántartást az entitáspéldányokról, azok felderítésében segíti, ha <code>DbSet<Entity></code> tagváltozókat is megadunk a DAL-osztályban. Egy <code>DbContextOptions</code> objektum átadásával – mely tartalmazza az adatbázis típusát és connection stringjét – lehet példányosítani.


A service layernek DI-vel adjuk át a <code>DbContext</code>-et, és annak tagfüggvényeit meghívva lehet LINQ-ket futtatni.
A service layernek DI-vel adjuk át a <code>DbContext</code>-et, és annak tagfüggvényeit meghívva lehet LINQ-ket futtatni.


=== Milyen három modellezési lehetőségünk van adatmodell készítésére? ===
=== Milyen három modellezési lehetőségünk van adatmodell készítésére? ===
{| class="wikitable"
{| class="wikitable mw-collapsible mw-collapsed"
!
!
!példa
!példa
!előnyei
!előnyei
|-
|-
|automatikus
|'''automatikus'''
|<syntaxhighlight lang="csharp" line="1">public class Book
|<syntaxhighlight lang="csharp" line="1">public class Book
{
{
417. 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
433. 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)
{
{
448. sor: 449. sor:


=== Milyen két lehetőségünk van a modell konfigurációjára? ===
=== Milyen két lehetőségünk van a modell konfigurációjára? ===
==== Code first ====
==== Code first ====
{| class="wikitable"
{| class="wikitable"
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? ===
{| class="wikitable mw-collapsible mw-collapsed"
|+Összehasonlítás
!
!1:N
!N:N
|-
|'''annotációkkal'''
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Blog
{
    [Key]
    public int Id { get; set; }
    public string Title { get; set; } = null!;
 
    public List<Post> Posts { get; set; } = new();
}
 
public class Post
{
    [Key]
    public int Id { get; set; }
    public string Content { get; set; } = null!;
 
    [ForeignKey(nameof(Blog))]
    public int BlogId { get; set; }
    public Blog Blog { get; set; } = null!;  // parent navigation
}</syntaxhighlight>
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Student
{
    [Key]
    public int Id { get; set; }
 
    public string Name { get; set; } = null!;
 
    public List<Enrollment> Enrollments { get; set; } = new();
}
 
public class Course
{
    [Key]
    public int Id { get; set; }
 
    public string Title { get; set; } = null!;
 
    public List<Enrollment> Enrollments { get; set; } = new();
}
 
public class Enrollment
{
    [ForeignKey(nameof(Student))]
    public int StudentId { get; set; }
    public Student Student { get; set; } = null!;
 
    [ForeignKey(nameof(Course))]
    public int CourseId { get; set; }
    public Course Course { get; set; } = null!;
 
    public DateTime EnrolledOn { get; set; }
}</syntaxhighlight>
|-
|'''Fluent API-val'''
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Blog
{
    public int Id { get; set; }
    public string Title { get; set; }
 
    public List<Post> Posts { get; set; } = new();
}
 
public class Post
{
    public int Id { get; set; }
    public string Content { get; set; }
 
    public int BlogId { get; set; }          // foreign key
    public Blog Blog { get; set; } = null!;  // parent navigation
}</syntaxhighlight><code>DbContext</code>:<syntaxhighlight lang="csharp" line="1">protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasMany(b => b.Posts)
        .WithOne(p => p.Blog)
        .HasForeignKey(p => p.BlogId);
}</syntaxhighlight>
|Entitások:<syntaxhighlight lang="csharp" line="1">public class Student
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Course> Courses { get; set; } = new();
}


=== Hogy néz ki egy entitás, hogyan készítünk kapcsolatokat közöttük? ===
public class Course
...
{
    public int Id { get; set; }
    public string Title { get; set; }
    public List<Student> Students { get; set; } = new();
}</syntaxhighlight><code>DbContext</code>:<syntaxhighlight lang="csharp" line="1">protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>()
        .HasMany(s => s.Courses)
        .WithMany(c => c.Students)
        .UsingEntity("StudentCourse");
}</syntaxhighlight>A kapcsolótáblát az EF automatikusan létrehozza.
|}


=== Hogyan készítünk lekérdezéseket, hogyan módosítunk adatokat EF Core-ban? ===
=== Hogyan készítünk lekérdezéseket, hogyan módosítunk adatokat EF Core-ban? ===
...
A <code>Dogs</code> entitás példáját véve:
{| class="wikitable"
|+lekérdezések
!típus
!<code>dbContext</code>-függvényhívás
|-
|'''összes találat'''
|<code>.Any(d => !d.Ownerships.Any())</code>
|-
|számlálás
|<code>.Any(…).Count()</code>
|-
|'''projekció'''
|<code>.Select(d => d.Name)</code>
|-
|csoportos projekció és spread
|<code>.SelectMany(d => d.Ownerships)</code>
|-
|'''szelekció'''
|<code>.Where(d => d.Name == "Bodri")</code>
vagy ID alapján:
<code>.Find(dogId)</code>
|-
|egyetlen találat
|<code>.Single(d => d.Name == "Bodri")</code>
vagy
<code>.SingleOrDefault(…)</code>
|-
|első találat
|<code>.First(d => d.Name == "Bodri")</code>
vagy
 
<code>.FirstOrDefault(…)</code>
|-
|'''csoportosítás'''
|<code>.GroupBy(d => d.Ownerships.Count())</code>
|-
|'''rendezés'''
|<code>.OrderBy(d => d.Ownerships.Count())</code>
<code>.ThenBy(d => d.BirthDate)</code>
|-
|lapozás
|<code>.Skip(20)</code>
és
<code>.Take(10);</code>
|}
{| class="wikitable"
|+módosítások
!CRUD
!<code>dbContext</code>-függvényhívás
|-
|'''create'''
|<code>.Dogs.Add(newDog);</code>
|-
|'''read'''
|ld. az előző táblázatot
|-
|'''update'''
|<code>.Dogs.Find(dogId);</code>
<code>dog.BirthDate = birthDate;</code>
|-
|'''delete'''
|adatbetöltéssel:
<code>.Dogs.Find(dogId);</code>
<code>.Dogs.Remove(dog);</code>
adatbetöltés nélkül:
 
az előző táblázatból bármit meghívni az ''első találat'' sorig, majd utána <code>.ExecuteDelete();</code>
|}
...majd utána <code>dbContext.SaveChanges();</code>.


== 5. JPA – általános ==
== 5. JPA – általános ==


=== 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! ===
...
A JPA egy Java ORM-interfészspecifikáció, melyet az Eclipse Foundation tart karban. 2020 óta már ''Jakarta Persistence'' a neve.<ref>https://blogs.oracle.com/javamagazine/post/transition-from-java-ee-to-jakarta-ee</ref>
 
Egyik implementációja a ''Hibernate'', .NET-es megfelelője pedig a ''.NET Persistence API''.
 
==== Architektúra ====
<syntaxhighlight>
┌──────────────────────────┐
│ 1. osztályok (entitások) │  ← annotációkkal ellátva
└──────────────────────────┘
          ↓
┌─────────────────────────────┐
│ 2. perzisztenciabeállítások │  ← a persistence.xml-ben vagy a kódban
└─────────────────────────────┘
          ↓
┌─────────────────────────┐
│ 3. EntityManagerFactory │  ← elindítja a JPA providert
└─────────────────────────┘
          ↓
┌──────────────────┐
│ 4. EntityManager │  ← futásidőben kezeli a perzisztenciakontextust (tranzakciókat, gyorsítótárat stb.)
└──────────────────┘
          ↓
┌───────────────────┐
│ 5. adatbázisréteg │ 
│  - JDBC API      │ 
│  - JDBC driver  │ 
│  - RDBMS        │
└───────────────────┘
</syntaxhighlight>Az elsőt "csak" használja a JPA, a 2–4. elemek pedig a szerves részei.
 
=== Milyen annotációkat kell alkalmazni egy JPA-entitás megírásakor? ===
 
* <code>@Entity</code>
* <code>@Id</code>
 
Szükség esetén:
 
* <code>@GeneratedValue</code> az <code>@Id</code>-hoz
 
* <code>@Table(name=…)</code>, illetve <code>@Column(name=…)</code>
* <code>@Embeddable</code> és <code>@Embedded</code>
* <code>@Convert(converter=…)</code>
 
=== Milyen típusú attribútumokat vehetünk fel benne? ===


=== Milyen annotációkat kell alkalmazni egy JPA-entitás megírásakor, és milyen típusú attribútumokat vehetünk fel benne? ===
* primitívek és ''TitleCase'' wrappereik
...
* szövegek
** <code>String</code>
** <code>char[]</code> és <code>Character[]</code>
* számok
** <code>BigInteger</code> és <code>BigDecimal</code>
* idő
** <code>Calendar</code>, <code>Date</code>, <code>Time</code>, <code>Timestamp</code> stb.
*** <code>java.util.*</code> esetén kötelező használni a <code>@Temporal(DATE/TIME/TIMESTAMP)</code>-et
*** egyéb esetben ajánlott
* Enum
** <code>@Enumerated(ORDINAL/STRING)</code> szükséges
* nyers adatok
** <code>byte[]</code> és <code>Byte[]</code>
** nagyobb adatok esetén <code>@Lob</code> szükséges, hogy <code>BLOB</code>-ként tárolja őket


=== Ismertesd a perzisztenciakontextus fogalmát! ===
=== Ismertesd a perzisztenciakontextus fogalmát! ===
...
A perzisztenciakontextus a perzisztenciaszolgáltató által kezelt, memóriabeli entitások egy része. Hozzáférést biztosít az adatbázishoz az üzleti logikában. A JPA-ban az <code>EntityManager</code>, az EF Core-ban pedig a <code>DbContext</code> végzi ezt a feladatot.
 
Egy perzisztenciakontextus belül egy objektum csak egyetlen példányban létezhet.


=== Mutasd be az entitások életciklusát! ===
=== Mutasd be az entitások életciklusát! ===
...
 
==== Állapotok ====
{| class="wikitable"
! colspan="2" rowspan="2" |
! colspan="2" |a DB-ben
|-
!nem létezik
!létezik
|-
| rowspan="2" |'''a memóriában (perzisztenciakontextusban)'''
|'''nem létezik'''
|–
|''lecsatolt''
|-
|'''létezik'''
|''új''
|''menedzselt'' vagy ''törölt''
|}
 
==== Á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, és hogyan támogatja a Spring? ===
=== 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 {


=== Hogyan könnyíti meg a JPA használatát a Spring Data JPA? ===
    @Transactional
...
    public void processOrder() {
        validateOrder();
        chargeCustomer();
        saveOrderToDatabase();
       
        // kezeletlen kivétel esetén a Spring automatikusan rollbackel
    }


=== Hogyan támogatja a tranzakciókezelést a Spring? ===
}
...
</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 infrastruktúra funkciót! ===
=== 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? ===
...


=== Ismertesd az alábbi microservice tervezési minták céljait, azok előnyeit, hátrányait! ===
==== 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


==== Shared database ====
==== Hátrányok ====
...
A modularitásnak természetesen vannak hátrányai is. Ezek a következőek:


==== Database per service ====
* 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ó


==== API composition ====
Ezekre (részben vagy egészben) megoldást ad...
...


==== CQRS ====
* 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 ==
592. 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 ''API gateway'' tervezési mintát! ===
=== 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 ''Service discovery'' mintákat! ===
=== 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


=== A számítási felhő fizikai, térbeli kiépítése. ===
==== Térbeli ====
...
A nagyobbtól a kisebbig:


=== Főbb publikus felhőszolgáltatók. ===
* region
...
* availability zone
** redundancia
* data center


=== Felhős szolgáltatásmodellek. ===
=== Főbb publikus felhőszolgáltatók ===
...


=== Szolgáltatásgaranciák (SLA). ===
* AWS
...
* Microsoft Azure
* Google Cloud
* OVH (EU)


=== Skálázási lehetőségek. ===
=== Felhős szolgáltatásmodellek ===
...


=== Példák elérhető szolgáltatásokra. ===
* infrastructure as a service
...
* platform as a service
* software as a service


=== A felhős modell előnyei, hátrányai. ===
{| 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 ===
{| 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)