Zona informaticienilor
tehnologiA informațiilor și comunicațiilor
#lumeavirtuala #informatii #comunicatii #it #software #hardware #serviciicomputerizate
DOMENII CREATIVE: publicitate & marketing, arhitectură, meșteșuguri, design de produs & grafic și de modă, modă, film, TV & video, radio și fotografie, IT & software și servicii computerizate, activități editoriale, muzee, galerii & biblioteci, muzica, artele spectacolului, arte vizuale.
Sursa definiției și clasificării industriilor creative: Wikipedia (conform DCMS, 2015)
NU-ȚI TRĂI VIAȚA ÎN MOD VIRTUAL! Maxim 8 ore pe zi ar trebui să petreci pe internet!
INFORMAȚIILE/ DATELE ÎN LUMEA REALĂ sunt interpretate de om sau de alte viețuitoare, chiar și de plante prin semnale, cuvinte, sunete, imagini.
INFORMAȚIILE/ DATELE ÎN LUMEA VIRTUALĂ (= biți digitali) sunt interpretate, stocate în calculatoare/ alte dispozitive și transmise între acestea sub forma unei serii de biți, reprezentate digital prin coduri (fiecare BIT - ”cifră binară”, cea mai mică unitate de date/ unitate de bază - poate avea valoarea 0 sau 1 - stări binare sau discrete, precum un comutator poate fi oprit sau pornit).
ASCII (American Standard Code for Information Interchange) este un cod binar folosit de calculatoare pentru a reprezenta și interpreta litere, cifre și caractere speciale (fiecare caracter este reprezentat de 8 biți = octet).
1 = 00110001
a = 01100001
A = 01000001
Datele transformate în serii de biți digitali trebuie convertite în semnale/ impulsuri electrice, optice sau unde wireless (radio/ cu infraroșu/ cu microunde) pentru a fi transmise prin mediul de rețea (suportul fizic, adică fir de cupru, cablu de fibră optică sau unde electromagnetice).
Datele cu caracter personal pot fi oferite voluntar (exemplu: rețele sociale), date observate (capturate - cum ar fi cele privind locația) sau date deduse (care se bazează pe analiza de date oferite sau observate).
Calculator
Exemplu de comunicație efectivă/ directă - CE
MESAJUL ÎN LUMEA REALĂ
Exemplu de comunicare prin transmiterea unui mesaj scris între două persoane care cunosc limbi diferite -fiecare persoană are nevoie de un asistent care redactează mesajele (primul nivel al comunicării mesajului), acesta îl dictează traducătoarei (alt nivel al transmiterii mesajului), apoi paginile sunt numerotate și se alcătuiesc mai multe scrisori, care merg la poștă, Poșta transmite plicurile la oficiul poștal al biroului destinatar, poștașul îl duse la destinație, mesajul este preluat de secretara destinatarului, acesta îl predă șefului ei. (Mesajul între cei doi șefi de firmă este virtual, deoarece nu comunică direct. Rutele pentru fiecare plic pot fi diferite.)
MESAJUL ÎN LUMEA VIRTUALĂ
Exemplu de comunicare a unei informații prin intermediul unei rețele de calculatoare sau alte dispozitive inteligente - două persoane folosesc două calculatoare-gazdă (calculatoarele sunt gazdă pentru aplicații) - calculatoarele nu au legături directe între ele, ci prin mai multe routere (care implementează 3 niveluri: fizic, legături de date, rețea), urmând protocoale (mesajul pleacă de la calculatorul Expeditorului - ajunge la server - apoi la routerul rețelei de care este legat serverul - în funcție de IP-ul de destinație, din tabela de routare, alege următorul router din internet - ajunge la destinație)
NIVELURILE COMUNICAȚIEI EFECTIVE ALE FIECĂRUIA DINTRE CELE DOUĂ CALCULATOARE (la fiecare există protocoale de comunicație, seturi de reguli care guvernează formatul și semnificația unităților de date de protocol schimbate între ele de către echipamente care comunică). Pe baza protocoalelor, aceste niveluri pereche - echipamentele - comunică între ele prin intermediul unei interfețe - comunicare virtuală - CV)
Următoarele niveluri sunt specifice calculatoarelor gazdă
Următoarele 3 niveluri sunt comasate într-unul singur în modelul TCP/ IP (sunt operațiuni specifice aplicațiilor
MEDIU DE COMUNICAȚIE PARTAJAT într-un spațiu, în atmosfera comună se propagă sunete, așadar trebuie să existe o ordine în comunicare a celor prezenți (pentru exactitate, se poate menționa nume, prenume și CNP - echivalentul adreselor fizice din nivelul Legături de date).
PROTOCOL MAC (Medium Access) - într-un mediu fizic pe cupru sau wireless trebuie să există reguli (protocol) de transmitere a informațiilor (acces la mediul de comunicație)
ZGOMOTE ÎN COMUNICARE
DETECTAREA ERORILOR - ZGOMOTE ÎN TRANSMITEREA DATELOR ÎN MEDII FIZICE - recepționarea incorectă a informațiilor la destinație, verificarea făcându-se prin calcularea unei sume de control pe baza datelor (cu algoritmi) . Dacă apar erori, nu se fac corecții la nivelul Data Link, doar la următoarele niveluri.
MESAJUL REDUNDANT - spune același lucru de mai multe ori, fără să adauge informații noi.
REDUNDANȚĂ ÎN TRANSMITEREA UNUI MESAJ ÎN REȚEA - mai multe căi de transmitere a mesajului către o destinație printr-o rețea cu comutare de pachete (un mesaj - e-mail/ flux video etc. - este împărțit în blocuri video). Așadar, dacă o cale eșuează, mesajele sunt trimise pe altă cale (rețea tolerantă la erori).
Calculatorul/ telefonul (alt dispozitiv) conectat la rețeaua Internet (printr-un dispozitiv conectat la rețeaua globală se poate comunica sau accesa informații/ date)
Internetul este o colecție de rețele LAN și WAN interconectate.
(un dispozitiv final se poate conecta direct la satelit, dar fără flux de date complet și cu viteze mici)
CONECTARE LA INTERNET
cu calculator sau IoT
sau
CONECTARE LA INTERNET
cu telefon
UTILIZATOR ANONIM
UTILIZATOR CU CONT
(click pe + sau - pentru a desfășura sau restrânge conținutul reperelor)
= ştiinţa scrisului secret (cryptos- ascuns şi grafie- scriere), cu scopul de a ascunde semnificaţia unui mesaj (studiul metodelor matematice legate de securitatea informaţiei).
SISTEME DE CRIPTARE
A/ 0
B/ 1
C/ 2
D/ 3
E/ 4
F/ 5
G/ 6
H/ 7
I/ 8
J/ 9
K/ 10
L/ 11
M/ 12
N/ 13
O/ 14
P/ 15
Q/ 16
R/ 17
S/ 18
U/ 19
T/ 20
V/ 21
W/ 22
X/ 23
Y/ 24
Z/ 25
.
.
.
.
.
.
SIMETRICE CLASICE
SIMETRICE CLASICE
CU CHEIE FLUIDĂ
DES
AES
CU CHEIE PUBLICĂ
DOMENII CREATIVE: publicitate & marketing, arhitectură, meșteșuguri, design de produs & grafic și de modă, modă, film, TV & video, radio și fotografie, IT & software și servicii computerizate, activități editoriale, muzee, galerii & biblioteci, muzica, artele spectacolului, arte vizuale.
Sursa definiției și clasificării industriilor creative: Wikipedia (conform DCMS, 2015)
Hardware & REȚELE
REȚELE - medii de comunicație
Componente ale rețelei (Gazdă - Host Roles, comunicarea în rețea de tip egal-la-egal - Peer to Peer, dispozitive intermediare - Switch, Wireless Router -, dispozitive de destinație - End Devices, medii de comunicație - Network Media - cu cabluri sau fără cabluri)
Medii de comunicație (Network Media - căile prin care informația ajunge de la destinatar la expeditor)
CONEXIUNI (cu cabluri metaliceserial - conectarea fizică între un calculator și un router sau
Conexiune de consolă (serial - conectarea fizică între un calculator și un router sau un switch se face cu un cablu de consolă, care poate fi USB sau serial, nefiind necesară o adresă IP)
Cablare structurată (adăugarea de cabluri în panoul de conexiuni și în prize într-un scenariu fizic) - echipamente și componente hardware
(este necesară existența unui modul wiress în dotarea calculatorului)
- Networks & Internet > Wi-FI > Hardware Properties (aici se văd numele rețelei SSID, la care calculatorul se poate conecta dacă se cunoaște parola; se poate verifica adresa IP)
(este necesară existența unui modul bluetooth în dotarea calculatorului)
- Bluetooth & Devices > Bluetooth ON (activarea este necesară la ambele dispozitive) > Add a Device (Pair) > click pe numele dispozitivului care apare în listă
Software
PROGRAMAREA = crearea unui produs-program:
- descrierea algoritmilor
&
- codificarea algoritmilor într-un limbaj de programare
Problemă?
(click pe + sau - pentru a desfășura sau restrânge conținutul reperelor)
1. Definirea și analizarea problemei
- CITEȘTE (în matematică = ce se dă?): se comunică algoritmului informații (cu enunț clar, precis al problemei - specificarea cerințelor și datelor de intrare și ieșire)
2. Algoritm
- SCRIE (în matematică = ce se cere?): algoritmul comunică informații - un set de date
- PROIECTAREA ALGORITMULUI - Stabilirea metodei de rezolvare pas cu pas
3. Codificarea într-un limbaj de programare
- limbaj (binar) între om și mașină (calculator sau alt dispozitiv), o sintaxă specifică utilizată pentru scrierea programelor
- COD SURSĂ (text scris într-un limbaj de programare - de exemplu: C, C++, C#, Python, Java etc., folosindu-se un fișier text, cum ar fi Notepad)
(DESCOMPUNEREA CODULUI: se recomandă ca problema/ CODUL să fie împărțit în bucăți bine izolate, care să fie codificate fiecare sub forma unei funcții - astfel se poate testa fiecare funcție separat)
- COMPILATOR - analizează textul programului și îl traducere în program (cod sursă - compilator - cod executabil/ mașină) - programul poate fi executat și fără a folosi un compilator, viteza de executare este mai ridicată (date de intrare - program executabil - date de ieșire)
- INTERPRETATOR - analizează și execută în același timp instrucțiunile (date de intrare & cod sursă - interpretator - date de ieșire)
- rezultă un PROGRAM = reprezentarea unui algoritm într-un limbaj - un fișier binar (cu extensia .exe în Windows), care presupune descrierea datelor și definirea unor instrucțiuni de procesare, adică se poate executa (lansa în execuție) sau rula
(timpul de rulare și dimensiunea memoriei folosite trebuie să fie cât mai mici)
- DEBUGGER/ DEPANATOR - rulându-se pas cu pas, se poate DEPANA programul creat (folosindu-se un breakpoint, se găsesc la fiecare pas rezultate intermediare) - PyCharm conține și un depanator, care permite interogarea pas cu pas a codului
4. Testarea și validarea programului
- rulează și se comportă conform așteptărilor?
- oferă rezultate conform cerințelor stabilite?
5. Întocmirea documentației
Principalele activități într-un proiect software
1. ACTIVITĂȚI DE MANAGEMENT AL PROIECTULUI
1. ce aduce nou/ interesant proiectul? 2. care ar fi alte trei proiecte similare si ce diferențe ar avea noul proiect? 3. în cazul unui site/ aplicații, ce funcționalități ar avea fiecare utilizator?
2. ACTIVITĂȚI TEHNICE
a. Definirea cerințelor utilizatorului
DIAGRAME UML (The Unified Modeling Language) = este un limbaj de modelare (unificat) obiect si nu o metodă-obiect - o modalitate de a dezvolta modele bogate, care descriu funcționalitățile unui sistem software sau hardware, rezultând documentația necesară unui proiect de dezvoltare (Care sunt entitățile? - Care sunt relațiile dintre ele?).
Diagrama cazurilor de utilizare (Use Case Diagram) - modelează serviciile, sarcinile, funcția pe care un sistem trebuie să le îndeplinească:
- elemente: Actor (o entitate care interacționează cu sistemul - un utilizator, de exemplu), Use Case (caz de utilizare reprezintă o funcționalitate distinctă a unui sistem, a unei componente, a unui pachet sau a unei clase - după analiza întregului sistem, se stabilește o funcționalitate de bază, apoi se organizează cazurile de utilizare, se stabilesc diverși actori sau lucruri care vor interacționa cu sistemul) și Asociere
- relații între use case-uri (relația fiecărui autor cu cazul de utilizare sau cu un sistem): trebuie identificat numărul total de moduri în care un actor ar putea interacționa cu sistemul (este posibil să interacționeze cu mai multe cazuri de utilizare simultan, dar dacă un caz de utilizare sau un actor are mai multe relații, trebuie afișate doar interacțiunile semnificative).
ZONA ONG (actori: ONG-SPECIALIST)
1. funcționalitate: problemă de rezolvat (ex. depunere declarație)
-
2. funcționalitate: rezolvare problemă (ex. depunere declarație)
3. funcționalitate: status/ stadiu rezolvare (use case de includere)
4. funcționalitate: recenzie pentru specialist (use case de extensie - opțional)
-
Pe baza specificațiilor definite, se poate crea macheta (mockup) proiectului (aplicație/ website etc.), folosindu-se instrumente precum FIGMA, BALSAMIQ etc.).
b. Definirea cerințelor software-ului (programului/ aplicației) > Document de cerințe software (Specificația de sistem)
c. Proiectare arhitecturală
d. Proiectare detaliată
e. Implementarea unităților programului (modulele)
f. Integrarea
g. Testarea de sistem
h. Testarea de acceptare
i. Întreținerea și operare
3. ACTIVITĂȚI DE ASIGURARE A CALITĂȚII
Medii vizuale de programare
(click pe + sau - pentru a desfășura sau restrânge conținutul reperelor)
(în colțul din dreapta-jos al ecranului) CLICK PE CAPUL PISICII > se alege personajul (pisica este personaj implicit)
(se trag piesele din coloana stângă în partea centrală) - acțiunea începe dacă se face click pe steagul verde - se adaugă în block din secțiunea EVENIMENTE (EVENTS - cu bulină galbenă) CÂND SE FACE CLICK PE STEAGUL VERDE (WHEN FLAG CLICKED)
- schimbarea poziției pisicii: din secțiunea MOTION (cu bulina albastră) > se trage CHANGE/ MODIFICĂ x CU 10 (apăsând tasta săgeata dreapta)
(în colțul din stanga-sus al ecranului) CREATE APPS (necesită crearea unui cont) > în meniul de sus: PROJECTS > START NEW PROJECTS > CREATE NEW APP INVENTOR PROJECT
- (setarea ecranului fără derulare - pentru ca ecranul interfeței să fie corect poziționat) > în meniul din stânga: DRAWING AND ANIMATION > CANVAS (se trage în coloana din mijloc a ecranului) > în dreapta ecranului, prima coloană - click pe SCREEN1 > în dreapta ecranului, a doua coloană - în DESIGNER - Scrollable trebuie să fie debifat
- (setarea dimensiunilor ecranului interfeței) > în meniul din stânga: DRAWING AND ANIMATION > CANVAS (se trage în coloana din mijloc a ecranului) > în dreapta ecranului, prima coloană - click pe CANVAS1 > în dreapta ecranului, a doua coloană - în DESIGNER - la HEIGHT și la WEIGHT, de bifat FILL PARENT
- în meniul din stânga: DRAWING AND ANIMATION > BALL (se trage în coloana din mijloc a ecranului) > în dreapta ecranului, prima coloană - click pe BALL1 > în dreapta ecranului, a doua coloană - în DESIGNER - se poate schimba dimensiunea mingii la RADIUS
- în dreapta ecranului, a doua coloană - click BLOCKS > în stânga ecranului: SCREEN1 > CANVAS1 > BALL (se adaugă blocuri) > se trage în centrul ecranului blocul ”when - Ball 1 -.Flung ... x y speed heading xvel yvel... do” - marcat cu maro (Flung declanșează la o glisare rapidă cu degetul pe ecran acțiunea de aruncare a mingii - aruncare = flinging)
- SETAREA DIRECȚIEI ȘI A VITEZEI MINGII: în stânga ecranului: SCREEN1 > CANVAS1 > BALL (se adaugă blocuri) > se trag în centrul ecranului blocurile ”sett - Ball 1 - Speed - to” (se setează viteza mingii la aceeași valoare cu a gestului de glisare a degetului pe ecran) și ”sett - Ball 1 - Heading - to” (se setează direcția mingii, care să fie aceeași cu a gestului de glisare a degetului pe ecran) - marcate cu verde > cele două blocuri pentru viteză (speed) și direcție (heading) trebuie să fie (conectate) în interiorul blocului .Flung > cu click pe parametrii SPEED și HEADING se adaugă blocurile GET SPEED și GET HEADING (cu portocaliu)
- SETAREA ACȚIUNII MINGII DE A LOVI MARGINILE ECRANULUI (se folosește argumentul EDGE): în stânga ecranului: SCREEN1 > CANVAS1 > BALL (se adaugă blocul) > se trag în centrul ecranului blocurile ”when - Ball 1 -.EdgeReached”
- se instalează pe device aplicația (din App Store/ Magazin Play...) MIT APP INVENTOR > din mediul de programare de pe desktop, în meniul de sus - CONNECT AI COMPANION > se generează un QR CODE care se poate scana cu aplicația instalată pe device sau un cod care se poate introduce în aplicație.
(înainte de a începe, se deschide din Start > Node.js Command Prompt (în folder Node.js) > se tastează comanda node-red
(în browser) http://localhost:1880 - se va deschide o fereastră Flow1
- (din secțiunea stângă a ecranului) se trag nodurile: http in (method: GET, url: /hello) click Done - function (msg.payload = { message: "Hello, World!" }; return msg; ) click Done - json (Property: msg.payload) click Done - http request (poate rămâne necompletat) - se creează legături între ele
- (tot din secțiunea stângă a ecranului) se trag nodurile: http in (method: POST, url: /echo) click Done - json (Property: msg.payload) click Done - function (return msg; ) click Done - json (Property: msg.payload) click Done - http request (poate rămâne necompletat) - se creează legături între ele
- (în dreapta sus a ecranului) click DEPLOY
(în browser) http://localhost:1880/hello - se va deschide o fereastră cu conținutul Hello, World
Limbaje de programare
HTML - limbaj de marcare (a textului astfel încât să poată fi afișat) pentru publicarea documentelor pe internet
- se folosește un set fix de marcaje (tag-uri = un șir de caractere delimitat de caracterele ”<" și ”>") prestabilite pentru a se defini modul în care este afișat conținutul pe internet (nu se referă la tipul informației conținută în document)
<!DOCTYPE html>
<html>
<head>
<title>Heading Example</title>
</head>
<body>
<h1>Hello, World!</h1>
</body>
</html>
XML - limbaj de marcare extensibil (generic) - marcare a datelor pentru a fi înțelese/ procesate automat de calculator, destinat structurării (de date ierarhice folosind etichete personalizte) și schimbului de date (transportului/ transferului) între sisteme și aplicații diferite
- se folosesc (tag-uri = un șir de caractere delimitat de caracterele ”<" și ”>") care conțin date caracter - marcajele și datele caracter formează un DOCUMENT XML.
- un FIȘIER XML este format din: PROLOG (instrucțiune de procesare, care indică versiunea - 1.0, encodarea setului de caractere - UTF-8), DEFINIȚIA TIPULUI DE DOCUMENT (opțională) și ELEMENTUL RĂDĂCINĂ, care este unic (în exemplul ”Hello, World!” ceea ce este cuprins între tag-urile <message> și </message>).
- formatul XSD arată că este un fișier XML, în care s-a folosit o schemă pentru definirea structurii, conținutului și regulilor de validare ale unui document xml.
Descărcarea (gratuit) editorului XML COPY EDITOR: http://xml-copy-editor.sourceforge.io:
<?xml version="1.0" encoding="UTF-8"?>
<message>
<greeting>Hello, World!</greeting>
</message>
<?xml version="1.0"?>
<BIBLIOTECA>
<CARTE>
<TITLU>Poezii</TITLU>
<AUTOR>Mihai Eminescu</AUTOR>
</CARTE>
</BIBLIOTECA>
TITLU
Poezii
AUTOR
Mihai Eminescu
În File > Options > Customize Ribbon > se bifează (în partea dreaptă) Developer
Folosind un editor (XML COPY EDITOR sau altul), se scrie o structură XML pentru mapare (salvare ca format .xml). Sunt necesare cel puțin două înregistrări (blocuri de date) în structură pentru a se genera fișierul XML.
<?xml version="1.0"?>
<BIBLIOTECA>
<CARTE>
<TITLU>Poezii</TITLU>
<AUTOR>Mihai Eminescu</AUTOR>
</CARTE>
<CARTE>
<TITLU>Jurnalul fericirii</TITLU>
<AUTOR>N. Steinhardt</AUTOR>
</CARTE>
</BIBLIOTECA>
În meniul Excel: Developer > butonul Source > (în partea dreapta a ecranului se va deschide XML Source > XML Maps > Add > (se adaugă fișierul XML creat cu editorul) > se trage cu cursorul câmpurile din structura XML încărcate în dreapta spre titlurile coloanelor > se exportă fișierul Excel cu format XML Data (.xml).
* Dacă se adaugă noi titluri și autori în lista Excel, aceste date vor apărea în noul fișier exportat în format XML, care poate fi deschis cu editorul XML.
* pentru a lucra cu baze de date, se pot folosi XAMPP și DBeaver
1. TIPURI DE DATE NUMERICE (ÎNTREGI)
- TINYINT
- SMALLINT
- MEDIUMINT
- INT
- BIGINT
- Clauza ZEROFILL - se completează la stânga până se ajunge la numărul de cifre specificat (de exemplu, pentru INT(7) ZEROFILL: valoarea 10 va fi afișată 0000010
- DATE
- TIME
- DATETIME
- TIMESTAMP
- YEAR
- CHAR
- VARCHAR
- BLOB
- TEXT
- CHAR
- VARCHAR
- BLOB
- TEXT
(ATENȚIE! pentru a se vedea modificările în baza de date, este necesar click dreapta - REFRESH)
MySQL -
1. CONECTARE LA SERVERUL SQL (în DBEAVER): Database - New Database Connection - click MySQL - Next - Main - Host: Localhost - Port: 3306 - Test Connection - Download
1. CREAREA BAZĂ DE DATE: (în noua conexiune) click dreapta Databases - Create New Database - Database Name: Exemplu (crearea unei baze de date, dar și a obiectelor se poate face și făcând un script nou (click dreapta pe conexiune - SQL Editor - New SQL Script: CREATE DATABASE Exemplu) sau folosind un script SQL existent (File - Open - se deschide scriptul SQL). Import bază de date deja existentă (un fișier Dump): click dreapta pe baza de date creată - Tools - Restore Database - selectare fișier - Start
2. CREARE TABELE - click dreapta pe Tables - Create New Table - Table Name...
MODIFICARE TABELE cu SQL script - (dacă este cazul, înainte se va adăuga USE nume_baza_de_date;) ALTER TABLE carte
DESIGN-ul TABELULUI: 3. ADĂUGAREA DE COLOANE (câmpuri) ÎN TABEL (nume, dată etc.): click dreapta pe Columns - Create New Column - Save - Refresh (necesită selectarea coloanei)
CONSTRÂNGERI/ CONSTRAINTS (reguli/ restricții în cadrul unui tabel/ între tabele - asupra valorilor dintr-un tabel/ dintr-o coloană pentru a nu exista date invalide sau greșite - exemplu: vârsta negativă):
4. PRIMARY KEY (cheia primară) dă unicitate fiecărui rând (de exemplu, nu pot exista două persoane cu același nume) și nu permite să fie Null, adică să lipsească - ALTER TABLE carte ADD CONSTRAINT pk_carte PRIMARY KEY (id); AUTO_INCREMENT se folosește pentru a se genera automat valori consecutive, de obicei pentru chei primare - ALTER TABLE carte
MODIFY id INT
AUTO_INCREMENT;
5. FOREIGN KEY - cheia străină creează o relație/ legătura între două tabele, asigurând existența valorii în tabelul părinte, adică o înregistrare dintr-un tabel trebuie să se regăsească în al doilea tabel (Exemple: coloana mea trebuie să existe în alt tabel, deci FOREIGN KEY (coloana_mea) REFERENCES alt_tabel (coloana_lui) sau în tabelul editura există coloana id_localitate, care are legătură cu tabelul localitate: ALTER TABLE editura ADD FOREIGN KEY (id_localitate) REFERENCES localitate(id); )
(pe diagrama creată, se poate selecta cheia primară dintr-un tabel, se trage cu mouse-ul de la rândul selectat spre columna echivalentă din tabelul vizat pentru relație);
* în relația many-to-many este necesară o tabelă intermedială, care conectează tabele independente prin chei străine, iar într-o astfel de relație găsim chei străine doar în tabela intermediară, nu și în tabelele independente (exemplu: o carte are mai multe categorii, o categorie are mai multe cărți): ALTER TABLE carte_categorie
ADD CONSTRAINT fk_carte
FOREIGN KEY (id_carte) REFERENCES carte(id);
și
ALTER TABLE carte_categorie
ADD CONSTRAINT fk_categorie
FOREIGN KEY (id_categorie) REFERENCES categorie(id);
6. CONSTRÂNGERI DE COLOANĂ SAU DE INTEGRITATE/ REGULI PENTRU VALIDAREA DATELOR: UNIQUE - pentru a nu permite duplicate într-o coloană (exemple: pentru logarea într-un cont se permite o adresă email unică, dar data nașterii unui autor poate fi aceeași pentru mai mulți - (dacă este cazul, înainte se va adăuga
USE nume_baza_de_date;) ALTER TABLE carte
ADD CONSTRAINT uq_carte_isbn UNIQUE (isbn);
- ceea ce înseamnă că se modifică tabelul carte adăugându-se constrângerea pentru unicitate ISBN); NOT NULL - nu permite să lipsească valori, iar ID-ul, care este Primary Key, este NOT NULL (exemple de folosire NOT NULL: orice persoană are nume; nume obligatoriu pentru autor - ALTER TABLE autor MODIFY nume VARCHAR(100) NOT NULL; - se poate adăuga în aceeași instrucțiune MODIFY id INT(11) NOT NULL; (NULL = lipsă de informație - de exemplu, cei care locuiesc la casă nu completează numărul apartamentului); DEFAULT - valoare implicită; 7. CONSTRÂNGERI DE VERIFICARE: CHECK - impune o condiție): click dreapta pe Column Name - Check Constraint, de exemplu - se completează în General - Expressions - de adăugat și coloana referentă cu condiția Gen = 'M' sau 'F'
(Acțiuni referențiale - proiecții la ștergere: CASCADE, SET NULL, RESTRICT/ NO ACTION)
(* modificările referitoare la constrângeri apar în Constraints - este necesar click dreapta - REFRESH)
AFIȘARE ÎN DIAGRAMĂ A DETALIILOR UNUI TABEL cu MySQL - click dreapta pe baza de date - View Diagram (diagrama se poate salva ca imagine cu click dreapta - Sava diagram as...
MICROSOFT SQL SERVER -
1. CONECTARE LA SERVERUL SQL (în DBEAVER): Database - New Database Connection - click Microsoft SQL SERVER - Next - Main - a) Authentication: Windows Authentication - la Setting se bifează Trust Server Certificate (de la Test Connection - Download Driver files); b) Authentication: SQL SERVER AUTHENTICATION (se completează user și parola) - la Setting se bifează Trust Server Certificate (de la Test Connection - Download Driver files)
2. CONECTARE LA SERVERUL SQL (în SQL SERVER MANAGEMENT STUDIO - https://learn.microsoft.com/en-us/ssms/install/install): File - Connect Object Explorer... - Server Name: .\SQLEXPRESS - Authentication: a) Windows Authentication/ b) SQL Server Authentication (cont administrativ - Username: sa, Password: ... - Connect;)
COMENTARE în SQL SERVER: /* comentare */
1. CREAREA BAZEI DE DATE: Database - New Database - General - Database Name: Exemplu - proprietarul bazei de date poate fi schimbat de la owner (Setări - de la Options: Collation: Romania CI_AS; Compatibility level recomandat - SQL Server 2014) - crearea unei baze de date, dar și a obiectelor se poate face și folosind un script SQL (File - Open - se deschide scriptul SQL)
2. CREARE TABELE - click dreapta pe Tables - New - Table... (cheile primare nu trebuie să aibă bifat Allow Nulls, dar pot fi setate cu autoincrementare - în partea de jos a paginii, la Column Properties - Identity Specification - Is Identity - Yes - cheia primară poate să nu fie autoincrementabilă când are valoare definită prin litere; activarea cheiței din meniu - este necesară selectarea întregului rând ID_Angajat) - Salvarea noului tabel - click Refresh în Object Explorer - se poate genera script SQL cu click dreapta pe tabelul creat - Script Table as... - Create to... - New Query Editor Window - Save (* dacă apare mesajul Saving changes is not permitted, în meniu - Tools - Options - Designers - Table Options - bifare Prevent saving changes that require table re-creation)/ Crearea tabelelor folosind script SQL: se selecteaza baza de date - File - Open - selectare script - click Execute
DESIGN-ul TABELULUI: 3. ADĂUGAREA DE COLOANE (câmpuri) ÎN TABEL (nume, dată etc.): click dreapta pe Columns - New Column - Save - Refresh (necesită selectarea coloanei)
CONSTRÂNGERI/ CONSTRAINTS (reguli/ restricții asupra valorilor dintr-un tabel/ dintr-o coloană pentru a nu exista date invalide sau greșite - exemplu: vârsta negativă):
4. PRIMARY KEY (cheia primară) dă unicitate fiecărui rând și nu permite să fie Null, adică să lipsească; 5. FOREIGN KEY - cheia străină creează o relație/ legătura între două tabele, asigurând existența valorii în tabelul părinte (pe diagrama creată, se poate selecta cheia primară dintr-un tabel, se trage cu mouse-ul de la rândul selectat spre columna echivalentă din tabelul vizat pentru relație); 6. REGULI PENTRU VALIDAREA DATELOR: UNIQUE - pentru a nu permite duplicate într-o coloană; NOT NULL - nu permite să lipsească valori (NULL = lipsă de informație); DEFAULT - valoare implicită; CHECK - impune o condiție): click dreapta pe Column Name - Check Constraint, de exemplu - se completează în General - Expressions - de adăugat și coloana referentă cu condiția Gen = 'M' sau 'F'
RELAȚIILE ÎNTRE TABELE (1:1, 1:N, N.M)
AFIȘARE ÎN DIAGRAMĂ A DETALIILOR UNUI TABEL cu SQL SERVER - în SSMS (dacă se cere Install Diagram Support, click pentru instalare): după crearea diagramei, click dreapta pe titlul tabelului - Table View - alegerea modului de afișare: Standard... (se poate face export diagramă cu click dreapta pe diagramă - Copy Diagram to Clipboard; în DBEAVER: click dreapta pe Tables - View Diagram
GENERARE SCRIPT SQL EXPORT (doar structura sau structura și date) - în fișier .sql - click dreapta pe baza de date - Tasks - Generate Script - Set Script Options - Advanced - Types of data to script
EDIT TOP 200 ROWS: click dreapta pe tabel - select Edit Top 200 Rows - permite vizualizarea/ verificarea rapidă a datelor, editare/ modificare rapidă a datelor, adăugare sau ștergere de rânduri
SELECT TOP 200 ROWS: click dreapta pe tabel - select Select Top 1000 Rows - permite doar vizualizarea/ verificarea rapidă a datelor, nu și editare/ modificare
DESIGN (comandă utilă pentru a analiza structura unui tabel: denumiri ale coloanelor și ordinea acestora, tipuri de date, acceptarea valorilor NULL): click dreapta pe tabel - Design
- prin aducere la forma normală a datelor (descompunerea valorilor complexe/ compuse în valori atomice), se va obține o bază de date relațională (mai multe tabele, cu chei primare și operații logice între ele)
- rezultatele afișate în urma unei interogări în DataGridView se pot copia, după selectare - click dreapta pe selecție - copiere sau salvare cu Save Results As... (datele pot fi copiate sau inserate într-un foaie Excel)
Afișarea tuturor datelor din tabel - fără filtrare, fără ordonare:
SELECT *
FROM Customers
Afișarea anumitor date din tabel - fără filtrare, fără ordonare (coloanele pot fi scrise una sub alta, dar cu spațiu înainte de virgulă sau se pot pune virgulele înaintea coloanelor):
SELECT CustomerID, Address, City, Phone
FROM Customers
Afișarea rezultatelor ordonate crescător după City:
SELECT CustomerID, Address, City, Phone
FROM Customers
ORDER BY City ASC
Afișarea rezultatelor folosind comanda SELECT împreună cu clauza DISTINCT pentru a evita duplicate/ repetarea rezultatelor:
SELECT DISTINCT City
FROM Customers
ORDER BY City
Afișarea rezultatelor folosind comanda SELECT împreună cu clauza AS (alias) pentru a afișa alt nume pentru o coloană
SELECT City AS Oras
FROM Customers
ORDER BY City
Afișarea rezultatelor folosind comanda SELECT împreună cu clauza WHERE pentru a filtra datele - a afișa doar acele înregistrări care îndeplinesc o anumită condiție
SELECT CustomerID, Address, City, Phone
FROM Customers
WHERE City = 'Cluj'
ORDER BY City
Adăugarea de date cu comandă rapidă: click dreapta pe tabel - Script table as - Insert to - New Query Editor Window (se modifică datele care urmează după VALUES, puse între '...')
Actualizare de date cu comandă rapidă: click dreapta pe tabel - Script table as - Update to - New Query Editor Window (se modifică datele care urmează după VALUES, puse între '...')
Ștergerea de date cu comandă rapidă: click dreapta pe tabel - Script table as - Delete to - New Query Editor Window (se modifică datele care urmează după VALUES, puse între '...')
PREGĂTIREA CHESTIONĂRII: Crearea unei vederi folosind Query Builder (înseamnă construirea unei comenzi SELECT): click dreapta pe baza de date - New Query sau pe View - New View - Add Table (alegerea tabelelor) - pentru a vedea Lista tuturor clienților, se bifează All columns sau doar coloanele necesare în funcție de situație - la Output, apare bifare True sau False (panourile 1 și 2 sunt sincronizate, iar modificările se transmit automat în comanda SELECT din panoul 3; de asemenea, modificările la comanda SELECT se transmit în panourile 1 și 2).
/* Lista tuturor clientilor */
SELECT *
FROM Customers
* pentru a obține ordinea alfabetică, se selectează în coloana Sort Type - pe același rând cu CustomerID
/* Lista tuturor clientilor */
SELECT *
FROM Customers
PREGĂTIREA CHESTIONĂRII: Configurarea sortării/ ordonării datelor: - în panoul 2 - pe coloana Sort Type (echivalentul clauzei ORDER BY - modul de sortare a datelor)/ pe coloana Sort order (se poate face sortare multiplă, după număr de ordine); - în coloana Filter se notează condiția de filtrare: = 'Germany' pe randul aferent valorii Country - se folosește clauza WHERE; - în panoul 3, click dreapta pe script - Execute (pentru a afișa rezultatele sortării în panoul 4)
/* Lista tuturor clientilor */
SELECT *
FROM Customers
* pentru a obține lista clienților din țări cu U, se modifică WHERE (Country LIKE 'U%')
* pentru a obține lista clienților din țări cu nume diferite, se modifică WHERE (Country IN (N'France', N'Germany'))
* pentru a obține lista clienților din alte țări decât Canada:
WHERE (dbo.Customers.Country NOT LIKE ('Canada')) sau WHERE dbo.Customers.Country <> 'Germany'
* pentru a obține lista clienților cu nume care încep cu litere A, D, se adaugă WHERE (Country IN (N'France', N'Germany')) AND (CustomerName LIKE N'A%' OR
CustomerName LIKE N'D%')
/* Lista tuturor clientilor */
SELECT *
FROM Customers
* pentru a obține lista filtrată după an și lună WHERE (YEAR(dbo.Orders.OrderDate) = 2022) AND (MONTH(dbo.Orders.OrderDate) = 5)
* pentru a obține lista filtrată pentru o perioadă între doi ani: WHERE (YEAR(HireDate) BETWEEN 2016 AND 2017)
VIZIBILITATEA DATELOR UNEI VEDERI CREATE: Deschiderea unei vederi: View (Refresh) - dbo.View - Design
* interogările se fac în fereastra Designer
C - limbaj de programare de nivel mediu (programare procedurală)
Tipuri de date
DATA TYPES (succesiuni de biți - 0 sau 1, măsurate în octeți - BYTE, adică 8 biți) = zone/ bucăți din memoria RAM dedicate unei instrucțiuni)
VARIABILELE (pot fi imaginate ca niște cutii cu conținut variat) = zone/ bucăți din memoria RAM dedicate unei instrucțiuni) - șiruri alfanumerice, având un NUME și o VALOARE (sunt senzitive la litere mari sau mici, care, în acest limbaj, nu pot începe cu cifră, nu pot conține caractere speciale, nu pot fi separate prin spații (spațiul este înlocuit cu _)
VARIABILE NUMERICE (int = număr fără virgulă și float = număr cu virgulă)
- funcțiile int () și float () se folosesc pentru a converti un șir într-un număr
VARIABILE DE TIP CARACTER (string)
(string înseamnă șir)
- funcția str () se poate folosi pentru a converti un număr într-un șir - str(number)
(nu se pot amesteca variabile numerice cu variabile de tip string, dar cele numerice se pot converti în string)
OPERATORI sunt folosiți pentru a da valori variabilelor
Structuri de date liniare
ȘIRURI (un tip de dată de bază format din caractere numerice)
(pentru editare de coduri, se pot folosi Code Blocks sau CLion)
C++ este un limbaj de nivel înalt, adică programare orientată pe obiecte)
Structuri de date neliniare
GRAF = elementele unei mulțimi sau grup de obiecte/ set de puncte, adică NODURI, unite sau conectate, două câte două, prin MUCHII sau CURBE(pe baza unei relații).
GRAF NEORIENTAT (G) = o pereche ordonată de mulțimi de noduri (notate X - nodes) și de muchii (notate U - edges). LANȚ AL UNUI GRAF = o succesiune de vârfuri, unde oricare două vârfuri consecutive sunt adiacente. GRAF PARȚIAL AL UNUI GRAF INIȚIAL = un graf obținut prin eliminarea uneia sau mai multor muchii. SUBGRAF AL GRAFULUI INIȚIAL - un graf obținut prin eliminarea unor noduri șia muchiilor incidente lor. GRAF COMPLET = oricare două noduri sunt adiacente. CICLU ELEMENTAR = toate nodurile sunt diferite, cu excepția primului și ultimului. NODUL IZOLAT = are gradul 0. MATRICE DE ADIACENȚĂ a[i][j], unde 1 se notează dacă există muchie între i și j, (i,j aparține mulțimii de muchii U), iar 0 se notează daca nu există muchie între i și j (i, j nu aparține mulțimii de muchii U). LISTE DE VECINI = se notează nodurile vecine fiecărui nod
ARBORE = colecție de noduri, unde fiecare nod are asociată o anumită informație și o colecție de descendenți (fii - nodul care urmează imediat sub nodul-părinte). Rădăcina unui arbore = un nod unic, care nu are părinte.
ARBORI BINARI = fiecare nod are maxim doi descendenți, știindu-se exact care este fiul stâng și fiul drept (nodurile fără fii sunt frontieră a arborelui).
PYTHON - este un limbaj de nivel înalt, adică programare orientată pe obiecte
(pentru editarea liniilor de cod se poate folosi mediul de dezvoltare PyCharm - acesta permite navigarea prin proiect și cod, vizualăzări de specialitate ale codurilor, structurii fișierelor și salturi între fișiere, clase, metode)
- este obligatorie identarea codului (tab)
- comentariile în Python se notează cu #
Tipuri de date
VARIABILELE (pot fi imaginate ca niște cutii cu conținut variat) = DATE/ DATA TYPES (succesiuni de biți - 0 sau 1, măsurate în octeți - BYTE, adică 8 biți) = zone/ bucăți din memoria RAM dedicate unei instrucțiuni) - șiruri alfanumerice, având un NUME și o VALOARE (sunt senzitive la litere mari sau mici, care, în acest limbaj, nu pot începe cu cifră, nu pot conține caractere speciale, nu pot fi separate prin spații (spațiul este înlocuit cu _)
VARIABILE NUMERICE (int = număr fără virgulă și float = număr cu virgulă)
- funcțiile int () și float () se folosesc pentru a converti un șir într-un număr
VARIABILE DE TIP CARACTER (string)
(string înseamnă șir)
- funcția str () se poate folosi pentru a converti un număr într-un șir - str(number)
(nu se pot amesteca variabile numerice cu variabile de tip string, dar cele numerice se pot converti în string)
OPERATORI sunt folosiți pentru a da valori variabilelor
(în ordine de prioritate - operațiile în paranteze au prioritate)
ARITMETICI
(2**3)**2=64
LOGICI
DE ATRIBUIRE
DE COMPARARE
PRECEDENȚA OPERATORILOR
(majoritatea operatorilor sunt considerați ca nivel de importanță de la stânga la dreapta, cu excepția operatorului exponent)
OPERAȚII (adunare, scădere etc.)
(în ordine de prioritate - operațiile în paranteze au prioritate)
Structuri de date liniare
ȘIRURI (un tip de dată de bază format din caractere numerice încapsulate în formate ASCII, UNICODE -UTF 8 etc., încadrate printr-o pereche de apostrof sau ghilimele)
INDEXARE
- este asociat caracterelor din șir
SEGMENTARE
- este asociat caracterelor din șir
LISTE - se pun între paranteze drepte, iar intre valori trebuie să fie virgule = este o colecție de elemente scalare
- tipurile de date cuprinse în liste pot fi diferite
INDEXARE
SEGMENTARE
IF
(execută o singură dată)
STRUCTURI REPETITIVE
BUCLĂ CU WHILE (repetă execuția atâta timp cât condiția evaluează cu TRUE)
BUCLĂ CU FOR (utilă pentru seturi mai de date)
JAVA - este un limbaj de nivel înalt, de programare orientată pe obiecte
(ATENȚIE! pentru tehnologia JAVA EE se folosește server Tomcat 9, altfel apar erori, iar pentru Jakarta EE - Tomcat 10)
ETAPA 1: CONFIGURAREA PROIECTULUI - MAVEN
(în IntelliJ) CREATE NEW PROJECT - (în partea stânga, la Generators, se alege:) MAVEN ARCHETYPE - org.apache.maven.archetypes:maven-archetype-webapp - (JDK - versiunea 17) - click CREATE
(în pom.xml, dependețele trebuie să fie descrise astfel:)
<dependencies>
<!-- JSF -->
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>javax.faces</artifactId>
<version>2.3.9</version>
</dependency>
<!-- BootsFaces -->
<dependency>
<groupId>net.bootsfaces</groupId>
<artifactId>bootsfaces</artifactId>
<version>1.5.0</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-core</artifactId>
<version>3.1.9.Final</version>
</dependency>
</dependencies>
ETAPA 2: CREAREA LOGICII (MANAGED BEAN)
CREARE PACHET JAVA (în folderul proiectului din src-main - click dreapta pe folderul java - echivalentul Sources Packages) - New - Package - nume: com.example.bean
CREARE CLASA JAVA (click dreapta pe pachetul com.example.bean) - New - Java Class - HelloBean - tasta Enter
package com.example;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
@ManagedBean
@RequestScoped
public class HelloBean {
private String name;
private String message;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMessage() {
return message;
}
public void sayHello() {
message = "Hello " + name;
}
}
ETAPA 3: DEFINIREA INTERFEȚEI (.xhtml)
(click dreapta pe directorul src) NEW - DIRECTORY - Name (webapp)
(click dreapta pe directorul src) NEW - DIRECTORY - Name (webapp)
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:b="http://bootsfaces.net/ui">
<h:head>
<title>Hello JSF BootsFaces</title>
</h:head>
<h:body>
<b:container>
<b:jumbotron>
<h1>Hello World</h1>
</b:jumbotron>
<h:form>
<b:inputText value="#{helloBean.name}" placeholder="Enter name"/>
<b:commandButton value="Say Hello"
action="#{helloBean.sayHello}"
update="@form"/>
<br/><br/>
<h:outputText value="#{helloBean.message}"/>
</h:form>
</b:container>
</h:body>
</html>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<display-name>HelloWorld</display-name>
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
</web-app>
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee"
bean-discovery-mode="all">
</beans>
STRUCTURA PROIECTULUI (cele cu roșu necesită modificări)
Hello
- pom.xml
- src -
- main -
- java
- com
- example
- HelloBean.java
- resources -
- webapp -
- index.xhtml
- WEB-INF
- beans.xml
- web.xml
Configurarea serverului: RUN - EDIT CONFIGURATION - (se adaugă) TOMCAT SERVER - LOCAL - (Deploy) ARTIFACT -HelloWorld:war exploded
După modificări: BUILD - REBUILD PROJECT și (din bara dreapta) MAVEN - Reload All Maven Projects
(ATENȚIE! pentru ca datele să fie păstrate la restart server este nevoie de integrare a unei baze de date - datele din memoria BEAN nu persistă)
* interacțiunea cu datele se face prin JPA și printr-un server de aplicații
* este nevoie de un driver JDBC pentru baza de date, cum este MySQL
- în XAMPP (se descarcă gratuit și se instalează MySQL, Apache - se instalează și phpMyAdmin) - la Action: START Apache și MySQL, apoi click ADMIN MySQL
- Local Host - numele serverului pe calculator: - adresa Local Host (afișată sus: Server 127.0.0.1
- pe serverul MySQL (Server 127.0.0.1 - în meniu BAZĂ DE DATE / DATABASES se CREEAZĂ baza de date: în căsuța Database name se notează exercitiu
- pe serverul MySQL (Server 127.0.0.1 - în meniu CONTURI UTILIZATOR/ USER ACCOUNTS se CREEAZĂ utilizator: utilizator și parola: parolaTa (la Nume gazdă se poate selecta Orice gazdă și se completează alăturat %) - administratorul trebuie să acorde toate privilegii Userului) are activat protocolul TCP/IP și lucrează pe portul TCP 3306;
- o bază de date nou creată nu conține tabele sau date, acestea trebuie create - de exemplu: username și password (se poate folosi un script SQL pentru importul tuturor tabelelor cu date) - în baza de date exercitiu - Import - se alege fișierul din calculator; în meniu - la Structură se va vedea conținutul bazei de date, al tabelelor;
- vizualizarea DIAGRAMEI - din meniu - More - Designer;
- INTEROGARE - din meniu - SQL
<!-- Exemplu pentru MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
<!-- JPA -->
<dependency>
<groupId>java.persistence</groupId>
<artifactId>java.persistence-api</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.6.15.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.6.15.Final</version>
</dependency>
* arată cum se face conectarea la baza de date
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_2.xsd"
version="2.2">
<persistence-unit name="myPU" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<class>com.exercitiu.model.User</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/exercitiu"/>
<property name="javax.persistence.jdbc.user" value="utilizator"/>
<property name="javax.persistence.jdbc.password" value="parolaTa"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL8Dialect"/>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>
* dacă se folosește XAMPP, spațiul pentru parola root poate fi necompletat, dar fără a lăsa spații libere între ghilimele (
value="")* dacă MySQL este instalat separat, este necesară parola aleasă la instalare
* se poate folosi Hibernate cu MySQL pentru a se evita erorile (de exemplu, hibernate.hbm2ddl.auto=update va crea automat tabela users în MySQL)
* adnotarea entității pentru a marca în această clasă ca fiind un tabel în baza de date
package com.exercitiu.model;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name = "utilizatori")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(unique = true, nullable = false)
private String username;
@Column(nullable = false)
private String password;
// ======================
// Getters / Setters
// ======================
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
package com.exercitiu.bean;
import com.exercitiu.model.User;
//import com.exercitiu.service.UserService;
import javax.inject.Named; // Folosim CDI
import javax.enterprise.context.SessionScoped; // Folosim CDI
import javax.persistence.*;
import java.io.Serializable;
import java.util.List;
@Named(value = "userBean")
@SessionScoped
public class UserBean implements Serializable {
private String username;
private String password;
private User loggedUser;
// Factory-ul poate fi static
private static final EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPU");
public UserBean() {}
public String login() {
// Creăm EntityManager-ul doar când avem nevoie de el
EntityManager em = emf.createEntityManager();
try {
TypedQuery<User> query = em.createQuery(
"SELECT u FROM User u WHERE u.username=:username AND u.password=:password", User.class);
query.setParameter("username", username);
query.setParameter("password", password);
List<User> result = query.getResultList();
if (result.isEmpty()) return "login?faces-redirect=true&error=true";
loggedUser = result.get(0);
return "dashboard?faces-redirect=true";
} catch (Exception e) {
e.printStackTrace();
return "login?faces-redirect=true&error=exception";
} finally {
em.close(); // Foarte important să îl închizi!
}
}
public String register() {
EntityManager em = emf.createEntityManager();
try {
em.getTransaction().begin();
User newUser = new User();
newUser.setUsername(this.username);
newUser.setPassword(this.password);
em.persist(newUser);
em.getTransaction().commit();
return "login?faces-redirect=true";
} catch (Exception e) {
if (em.getTransaction().isActive()) {
em.getTransaction().rollback();
}
e.printStackTrace();
return "register?faces-redirect=true&error=exception";
} finally {
em.close();
}
}
public String logout() {
loggedUser = null;
username = null;
password = null;
return "login?faces-redirect=true";
}
// Getters / Setters (Rămân la fel)
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
public User getLoggedUser() { return loggedUser; }
}
package com.exercitiu.bean;
import com.exercitiu.model.User;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.persistence.*;
import java.io.Serializable;
@ManagedBean(name="loginBean")
@SessionScoped
public class LoginBean implements Serializable {
@PersistenceContext(unitName = "MyPU")
private EntityManager em;
private String username;
private String password;
private User loggedUser;
public String login() {
try {
loggedUser = em.createQuery(
"SELECT u FROM User u WHERE u.username=:u AND u.password=:p", User.class)
.setParameter("u", username)
.setParameter("p", password)
.getSingleResult();
return "projects.xhtml?faces-redirect=true";
} catch (NoResultException e) {
loggedUser = null;
return "login.xhtml?faces-redirect=true";
}
}
public String logout() {
loggedUser = null;
return "login.xhtml?faces-redirect=true";
}
public boolean isLoggedIn() { return loggedUser != null; }
public User getLoggedUser() { return loggedUser; }
public String getUsername() { return username; }
public void setUsername(String username) { this.username = username; }
public String getPassword() { return password; }
public void setPassword(String password) { this.password = password; }
}
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:b="http://bootsfaces.net/ui">
<h:head>
<title>Exercitiu - Home</title>
</h:head>
<h:body style="padding-top: 60px; background-color: #f5f5f5;">
<b:container>
<b:jumbotron>
<h1>Bun venit!</h1>
<p>Pentru a accesa platforma, te rugăm să te autentifici sau să îți creezi un cont nou.</p>
<br/>
<b:button value="Login" look="primary" size="lg" outcome="login.xhtml" style="margin-right: 10px;"/>
<b:button value="Înregistrare Cont" look="success" size="lg" outcome="register.xhtml"/>
</b:jumbotron>
</b:container>
</h:body>
</html>
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:b="http://bootsfaces.net/ui">
<h:head>
<title>Înregistrare User</title>
</h:head>
<h:body style="padding-top: 60px; background-color: #f5f5f5;">
<b:container>
<h:form id="registerForm">
<b:panel title="Creare cont nou" style="max-width: 400px; margin: auto;" look="success">
<b:inputText value="#{userBean.username}" label="Utilizator" required="true">
<f:facet name="prepend"><b:icon name="user" /></f:facet>
</b:inputText>
<b:inputSecret value="#{userBean.password}" label="Parolă" required="true">
<f:facet name="prepend"><b:icon name="lock" /></f:facet>
</b:inputSecret>
<b:commandButton value="Înregistrare" action="#{userBean.register}" look="success" style="width:100%" />
<hr/>
<b:navLink value="Ai deja cont? Login" outcome="login.xhtml" />
<b:messages />
</b:panel>
</h:form>
</b:container>
</h:body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:b="http://bootsfaces.net/ui">
<h:head>
<title>Login</title>
</h:head>
<h:body>
<h:form id="loginForm">
<b:container>
<b:panel title="Login" style="max-width: 400px; margin: auto; margin-top: 50px;">
<b:inputText label="Username" value="#{userBean.username}" required="true" />
<b:inputSecret label="Password" value="#{userBean.password}" required="true" />
<b:commandButton value="Login" action="#{userBean.login}" look="primary" style="width:100%" />
<b:messages />
</b:panel>
</b:container>
</h:form>
</h:body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<faces-config xmlns="http://xmlns.jcp.org/xml/ns/javaee"
version="2.3">
</faces-config>
* în directorul WEB-INF să existe beans.xml și web.xml
* BootsFaces folosește Bootstrap (este un html în JSF), dar se poate realiza și CSS clasic
NAVIGAȚIE:
Navigație simplă: b:button
Navigație cu logică (ex. Logout): b:commandButton
Navigație JSF: h:link
CENTRAREA UNUI TEXT:
<h:panelGroup layout="block" style="text-align:center;">
<h2>Servus, #{userBean.loggedUser.username}</h2>
</h:panelGroup>
ADĂUGARE FEREASTRĂ POPUP
- în fișierul .xhtml
<h:form>
<!-- Buton care deschide popup-ul -->
<b:commandButton value="Deschide descriere"
onclick="$('.modalPseudoClass').modal('show'); return false;" />
<!-- Modal (popup) -->
<b:modal styleClass="modalPseudoClass" title="Descriere" closable="true">
<h:outputText value="Se afișează o descriere needitabilă." />
<f:facet name="footer">
<b:button value="Închide" dismiss="modal" />
</f:facet>
</b:modal>
</h:form>
- și
<h:outputText value="#{descriereBean.descriere}" />
- în backend - Java
public class DescriereBean {
public String getDescriere() {
return "Descriere (needitabilă)";
}
}
ADĂUGARE FEREASTRĂ POPUP ÎN CARE SĂ SE EDITEZE TEXT (cu salvare)
- în fișierul .xhtml
<h:form id="formProiect">
<!-- Buton pentru adăugare/modificare descriere -->
<h:panelGroup style="display:flex; align-items:center; gap:10px;">
<h3 style="margin:0;">Descriere proiect</h3>
<b:commandButton value="#{empty projectBean.selectedProject.description ? 'Adaugă descriere' : 'Editează descriere'}"
look="primary"
onclick="$('.modalDescriere').modal('show'); return false;" />
</h:panelGroup>
<br/>
<!-- Afișare descriere existentă -->
<h:outputText id="descriereOutput"
value="#{empty projectBean.selectedProject.description ? 'Nu există descriere' : projectBean.selectedProject.description}"
escape="false"/>
<!-- Popup unic -->
<b:modal styleClass="modalDescriere"
title="#{empty projectBean.selectedProject.description ? 'Adaugă descriere' : 'Modifică descriere'}"
closable="true"
modal="true">
<h:panelGrid columns="1" cellpadding="5">
<h:outputLabel value="Descriere proiect:" for="descriereInput"/>
<!-- Text editabil -->
<b:inputTextarea id="descriereInput"
value="#{projectBean.selectedProject.description}"
rows="6"
style="width:100%;" />
<br/>
<!-- Salvează modificările -->
<b:commandButton value="Salvează"
action="#{projectBean.saveDescription}"
update=":formProiect:descriereOutput"
look="success"
oncomplete="$('.modalDescriere').modal('hide');" />
</h:panelGrid>
</b:modal>
</h:form>
- în backend - Java
public Project getSelectedProject() {
return selectedProject;
}
public void setSelectedProject(Project selectedProject) {
this.selectedProject = selectedProject;
}
// Metodă pentru salvarea descrierii în DB
public void saveDescription() {
if (selectedProject == null) return;
try {
em.getTransaction().begin();
em.merge(selectedProject);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
if (em.getTransaction().isActive()) em.getTransaction().rollback();
}
}
ADĂUGARE IMAGINE (exemplu: banner)
- în fișier .xhtml
- în fișier css
(ATENȚIE! * rulează numai cu Windows)
(ATENȚIE! * rulează numai cu Windows)
Fiecare PROIECT în Visual Studio generează un ANSAMBLU privat sau partajat (o unitate logică, având cod executabil - fișier cu extensia .exe și bibliotecă de clase - fișier cu extensia .dll), iar la crearea acestuia, numele devine și spațiul de nume/ NAMESPACE pentru toate clasele conținute (regiunile din codul clasei se pot extinde sau restrânge - o astfel de metodă a organizării codului are ca scop evitarea suprapunerii de nume folosite pentru clase și obiecte). METADATELE sunt informații care descriu tipurile și metodele existente în codul unui ansamblu).
C# (C sharp este un limbaj de nivel înalt, adică programare orientată pe obiecte - limbaj puternic tipizat, deci clasele sunt tipuri referință)
* comentarea în C# cu combinația de taste CTRL+K+C, iar decomentarea cu CTRL+K+U
TERMENI FRECVENȚI:
(* Este hașurată cu galben structura minimă a unui program)
CREATE A NEW PROJECT > se alege CONSOLE APP (.NET FRAMEWORK) > (în fereastra Configure your new project - Project Name: HELLO WORLD, - Solution Name: HELLO WORLD_CS)
În panoul SOLUTION EXPLORER (se află de obicei în dreapta ecranului) se afișează structura proiectului.
În fereastra Program.cs, în cod s-a generat namespace HELLO WORLD.
SCRIEREA CODULUI: pentru instrucțiuni se folosesc: cuvinte-cheie ale limbajului de programare (class, static, string etc.), denumiri de clase (ex. Program, Console... - editorul oferă posibilitatea completării automate după scrierea primelor litere din cuvintele-cheie, datorită suportului IntelliSense), metode apelate (ex. WriteLine, ReadLine), variabile (ex. args = argumentele funcției Main), valori (șirul de caractere Hello World), alte elemente (//comentariu - este un element care nu este luat ]n considerare la rularea programului).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HELLO_WORLD
{
internal class Program
{
private static object console;
static void Main(string[] args)
{
Console.WriteLine("Hello, World!"); //comentariu
Console.WriteLine("Press ENTER to exit...");
Console.ReadLine();
}
}
}
Dacă se fac modificări în cod, este necesară o nouă compilare a proiectului sau a soluției din MENIU > BUILD (tasta F6)
În MENIU se alege DEBUG > START DEBUGGING (se va deschide o fereastră în care se afișează: Hello, World! Press ENTER to exit...
Pentru oprirea forțată se alege butonul STOP DEBUGGING.
Depanarea pas cu pas se face folosind comenzile STEP INTO sau STEP OVER
INTEROGĂRI ALE COLECȚIILOR DE DATE (LINQ)
- folosește CUVINTE-CHEIE (inspirate din SQL): var (variabile care vor conține reultate ale interogărilor LINQ), from, where, select etc.
(PAȘI: 1. crearea unei liste generice: List<Angajat> angajati = new List<Angajat>(); 2. adăugarea de elemente în lista angajaților; 3. pregătirea interogării: var query = from a in angajari where a.AnNastere >= 1970 orderby a.Nume, a.Prenume select a;CREATE NEW PROJECT (de ex. - de tip CLASS LIBRAY .NET Framework) - se definește numele proiectului (de ex. Clase).
Codul programului conține instrucțiuni - cuprinzând cuvinte-cheie, denumiri de clase, de metode apelate, de variabile, valori introduse în cod, comentarii, alte elemente.
SOLUȚIE Visual Studio = un container cu unul sau mai multe proiecte (un folder care conține fișierul *.sln și câte un subfolder pentru fiecare proiect, bin și obj cu cod compilat - unul dintre proiecte de tip aplicație .exe este START UP - apare cu bold în panoul Solution Explorer). Folderul soluției apare în C:\Users\UserName\source\repos
COMANDA BUILD SOLUTION în Visual Studio = determină crearea ansamblului EXE și a celui DLL (în folderul bin\Debug)
La pasul descris anterior (CREATE NEW PROJECT), în aceeași fereastră se completează și noua soluție - se definește numele soluției: Clase_CS.
În Solution Explorer se șterge Class1.cs.
În panoul SOLUTION EXPLORER (click dreapta) sau în meniu - FILE - ADD - NEW PROJECT, se pot adăuga alte proiecte la o soluție (de ex. - de tip CONSOLE APP .NET Framework, numit Obiecte, care se va seta ca Startup Project cu click dreapta, click Set as Startup Project - va fi evidențiat cu caractere îngroșate).
(Într-o soluție Visual Studio cu mai multe proiecte, unul dintre proiectele de tip aplicație EXE este PROIECT PRINCIPAL - STARTUP PROJECT - apare cu caractere îngroșate în panoul Solution Explorer.)
Într-un proiect de tip Windows Forms Application, o fereastră este o clasă.
(Codul conține apeluri către anumite metode)
În panoul SOLUTION EXPLORER (dublu click pe numele Program.cs din proiectul Obiecte pentru a deschide codul acesteia - este programul principal).
using System;
using Clase;
using System.Text;
namespace Obiecte
{
class Program
{
static void Main(string[] args)
// PAS 1
CreeazaObiecteDinClasaPersoana();
// PAS 2
CreeazaObiecteDinClasaStudent();
// PAS 3
TransmiteObiecteInApelulFunctiilor();
Console.WriteLine(" \n\n Apasă ENTER pentru a termina programul." );
Console.ReadLine();
// aici se termina programul principal
// urmează codul metodelor apelate
}
private static void CreeazaObiecteDinClasaPersoana() // metodă
{
string mesaj = "1. Rulează metoda CreeazaObiecteDinClasaPersoana()";
Console.WriteLine("\n" +mesaj + "\n");
// creare obiect pentru clasa Persoana si particularizare (varianta1)
Persoana p1 = new Persoana();
p1.Nume = "Pop";
p1.Prenume = "Ion";
p1.AnNastere = 1990;
// afisarea descrierii obiectului
Console.WriteLine(p1.Descriere() + "\n");
}
private static void CreeazaObiecteDinClasaStudent() // metodă
{
string mesaj = "2. Rulează metoda CreeazaObiecteDinClasaStudent()";
Console.WriteLine("\n" + mesaj + "\n");
// creare obiect pentru clasa Student si particularizare (varianta1)
Student s1 = new Student();
s1.Nume = "Pop";
s1.Prenume = "Ion";
s1.AnNastere = 1990;
// afisarea descrierii obiectului
Console.WriteLine(s1.Descriere() + "\n");
}
private static void TransmiteObiecteInApelulFunctiilor()
{
}
private static void AfiseazaDetaliiDespreObiect(object param)
{
}
}
}
Dacă se fac modificări în cod, este necesară o nouă compilare a proiectului sau a soluției din MENIU > BUILD (tasta F6)
CREAREA UNUI OBIECT se face în codul Program.cs (folosindu-se operatorul NEW și indicându-se constructorul clasei)
Proprietățile arată atributele obiectelor (aspectul). Metodele arată operațiile pe care le poate face un obiect (comportamentul). Constructorii sunt apelați pentru a crea noi obiecte. Câmpurile private sunt variabile care indică vizibilitatea.
În panoul SOLUTION EXPLORER, click dreapta pe proiectul OBIECTE - ADD - REFERENCE - PROJECTS - se bifează CLASE
În panoul SOLUTION EXPLORER (click dreapta) sau în meniu - PROJECT - ADD - NEW ITEM - CLASS (se poate redenumi cu click dreapta pe clasa nou creată - RENAME - de exemplu, PERSOANA)
(Proprietățile descriu atributele unui obiect - ASPECTUL)
În panoul SOLUTION EXPLORER (dublu click pe numele clasei pentru a deschide codul acesteia).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Clase
{ // Crearea clasei
public class Persoana
{
// Proprietățile publice ale clasei
public string Nume { get; set; }
public string Prenume { get; set; }
public int AnNastere { get; set; }
public string LocNastere { get; set; }
public string Domiciliu { get; set; }
}
}
Dacă se fac modificări în cod, este necesară o nouă compilare a proiectului sau a soluției din MENIU > BUILD (tasta F6)
(Câmpurile private sunt variabile vizibile în cadrul obiectului - VIZIBILITATE)
// Campurile private ale clasei
private int anCurent;
(Constructorul poartă numele clasei și este apelat pentru crearea unui nou obiect - CREARE)
// Constructorul clasei
public Persoana(string nume, int anNastere)
{
}
(Metodele descriu operațiile specifice pe care le poate efectua un obiect - COMPORTAMENT)
//Metodele publice ale clasei
public string NumeComplet()
{
string numeComplet;
numeComplet = $"{Nume} {Prenume}";
return numeComplet;
}
public int Varsta()
{
anCurent = DateTime.Now.Year;
return anCurent - AnNastere;}
}
public string Descriere()
{
string descriere;
descriere = $"PERSOANA {Nume} {Prenume}, " + $"anul nasterii {AnNastere}";
return descriere;
}
(Studentul este o Persoană, deci preia toate proprietățile și metodele clasei Persoana)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Clase
{
public class Student : Persoana
{
// Proprietatile publice ale clasei:
public int AnAdmitere { get; set; }
// Constructorul clasei
public Student()
{
Console.WriteLine(”a fost apelat constructorul clasei...”);
}
// Metodele publice ale clasei
public string Descriere()
{
string descriere;
descriere = $"STUDENT {Nume} {Prenume}, " + $"anul nasterii: {AnNastere}, anul admiterii {AnAdmitere}";
return descriere;
}
}
- necesită instalarea instrumentului CLASS DESIGNER
În panoul SOLUTION EXPLORER (click dreapta pe proiect - CLASE) sau în meniu - PROJECT - ADD - NEW ITEM - CLASS DIAGRAM
(Datele furnizate de ansamblul DataLayer.dll, stocate în colecții generice, sunt prelucrate cu interogări LINQ - filtrare, sortare, grupare)
CREATE NEW PROJECT (de ex. - de tip CLASS LIBRAY .NET Framework) - se definește numele proiectului (DataLayer).
ADĂUGAREA LA UN PROIECT A UNUI ANSAMBLU .DLL: în File Explorer - copy pentru fișierul .dll > în Solution Explorer - click dreapta pe numele proiectului - Paste - setări în Properties: Build action > None, Copy to Output Directory > Copy if newer.
În panoul SOLUTION EXPLORER, click dreapta pe proiectul principal - ADD - REFERENCE - PROJECTS - se bifează DataLayer (în proiectul principal va apărea - la References - Data Layer)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DataLayer
{
public class Partener
{
public int ID { get; set; }
public string Nume { get; set; }
public int CodFiscal { get; set; }
public string Localitate { get; set; }
public string Descriere
{
get { return $"{Nume}, {Localitate}"; }
}
// constructor Implicit
public Partener()
{
}
// constructor Specialist
public Partener(int id, string nume, int codFiscal,
string localitate)
{
this.ID = id;
this.Nume = nume;
this.CodFiscal = codFiscal;
this.Localitate = localitate;
}
}
}
În panoul SOLUTION EXPLORER (click dreapta) sau în meniu - PROJECT - ADD - NEW ITEM - CLASS (se poate redenumi cu click dreapta pe clasa nou creată - RENAME)
using System.Collections.Generic;
namespace DataLayer
{
public static class DataRepository
{
public static List<Partener> GetTotiPartenerii()
{
return new List<Partener>
{
new Partener(1, "Partener A", 123, "Bucuresti"),
new Partener(2, "Partener B", 456, "Cluj"),
new Partener(3, "Partener C", 789, "Bucuresti")
};
}
}
}
ADĂUGAREA UNEI PAGINI NOI LA PROIECT: În panoul SOLUTION EXPLORER (din dreapta ecranului), click dreapta pe numele proiectului > Add > Page (WPF) > redenumirea acesteia PAGEDATA
Codul pentru PAGEDATA.xaml
<Page x:Class="HelloWorldWPF.PageData"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HelloWorldWPF"
mc:Ignorable="d"
d:DesignHeight="550" d:DesignWidth="900"
Title="PageData">
<Grid Style="{DynamicResource GridStyleHello}" Background="Ivory">
<StackPanel Margin="10">
<Button Content="Afiseaza toti partenerii"
Click="BtnToti_Click"
Margin="0,0,0,5"/>
<StackPanel Orientation="Horizontal">
<TextBox x:Name="txtLocalitate" Width="150" Margin="0,0,5,0"/>
<Button Content="Cauta dupa localitate"
Click="BtnLocalitate_Click"/>
</StackPanel>
<ListBox x:Name="lstParteneri"
Margin="0,10,0,0"/>
</StackPanel>
</Grid>
</Page>
Codul pentru PAGEDATA.xaml.cs
using DataLayer;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace HelloWorldWPF
{
/// <summary>
/// Interaction logic for PageData.xaml
/// </summary>
public partial class PageData : Page
{
public PageData()
{
InitializeComponent();
}
private void BtnToti_Click(object sender, RoutedEventArgs e)
{
lstParteneri.Items.Clear();
foreach (var p in DataRepository.GetTotiPartenerii())
{
lstParteneri.Items.Add(p.Descriere);
}
}
private void BtnLocalitate_Click(object sender, RoutedEventArgs e)
{
lstParteneri.Items.Clear();
// LINQ aplicat pe colecția de date, NU pe ListBox
var parteneriDinLocalitate = DataRepository
.GetTotiPartenerii();
foreach (var p in parteneriDinLocalitate)
{
lstParteneri.Items.Add(p.Descriere);
}
}
}
}
În codul .xaml se adaugă - text box cu text link
<TextBlock
Grid.Row="2"
Foreground="Blue"
Cursor="Hand"
TextWrapping="Wrap"
MouseLeftButtonUp="buttonLink_Click">
Exemplu date organizate în colecții generice obținute din ansamblul DataLayer.dll
</TextBlock>
În codul .xaml.cs se adaugă
private void buttonLink_Click(object sender, RoutedEventArgs e)
{
this.Content = new PageData();
}
(obținerea unui context de date care conține o colecție de obiecte Produse)
CREATE NEW PROJECT (de ex. - de tip CLASS LIBRAY .NET Framework) - se definește numele proiectului (DataLayer).
În panoul SOLUTION EXPLORER, click dreapta pe proiectul principal - ADD - REFERENCE - PROJECTS - se bifează DataLayer (în proiectul principal va apărea - la References - Data Layer)
În panoul SOLUTION EXPLORER (click dreapta) sau în meniu - PROJECT - ADD - NEW ITEM - CLASS (se poate redenumi cu click dreapta pe clasa nou creată - RENAME - DATACONTEXT) - clasa cu rol de DataContext poate fi Program.cs - se adaugă în codul clasei:
class Program
{
static DataContext context; //denumirea contextului in date
static void Main(string[] args)
{
// se creează contextul de date
context = new DataContext();
// se încarcă datele
context.LoadData();
//folosire date
foreach (var produs in context.Produse)
{
Console.WriteLine($"{produs.Denumire} - {produs.Pret} lei");
}
}
În panoul SOLUTION EXPLORER (click dreapta pe proiect - CLASE) sau în meniu - PROJECT - ADD - NEW ITEM - CLASS DIAGRAM
WPF (Windows Presentation Foundation - aplicații n-tier sau multi-layer, care sunt client desktop, cu un cadru UI - interfață utilizator) - această platformă/ mediu de dezvoltare se bazează pe un set larg de caracteristici:
APLICAȚII N-TIER (MULTYLAYER)
Presentation Layer (ferestre, pagini, controale): - afișarea datelor; - afișarea comenzilor; - ferestre/ casete de dialog; - introducerea/ modificarea datelor; - notificări etc.
- după ce se încarcă toate elementele apare Window Loaded (eveniment)
Business Logic Layer (prelucrarea datelor): - selectarea datelor necesare; - operații specifice aplicației.
Data Layer: - definire tipuri de date (Data Models); - colecții de date (Context, Repository); - acces la date externe (fișiere locale, fișiere la distanță, servere de baze de date cu SQL, servicii web prin http)
- o FEREASTRĂ WPF sau o PAGINĂ este descrisă (definită) prin 2 fișiere - unul cu cod XAML (care descrie interfața - conținutul și aspectul - prin toate elementele, cu atribute și prin stiluri) și unul cu cod C# (în spate - Code Behind) - care descrie ce se face în fereastră (comportamentul ferestrei/ al componentelor vizuale) prin gestionarea metodelor (funcțiilor) și evenimentelor.
XAML - (eXtensible Application Markup Language) limbaj de marcare specializat, creat de Microsoft ca variantă la XML, pentru descrierea (și editarea facilă) unei interfețe grafice (UI).
WINDOW - fereastra principală sau secundară a aplicației
- container de nivel superior, fereastra principală găzduind aplicația, iar o fereastră secundară poate conține informații despre aplicație, de exemplu;
- are bară de titlu, butoane Minimize/ Maximize;
- conține orice control - dialoguri (Login etc.);
- când se închide fereastra, se închide aplicația.
Înainte de a defini Grid (sau alt panou), se va scrie elementul XAML <Window.Resources> pentru stabilirea proprietăților unui stil.
<!-- Definirea stilului -->
<Window.Resources>
<Style TargetType="Border" x:Key="RoundedBorderStyle">
<Setter Property="CornerRadius" Value="10 10 10 10" />
</Style>
<Style TargetType="Button" x:Key="RoundedButtonStyle">
<Setter Property="Background" Value="DarkBlue"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Height" Value="30"/>
<Style.Resources>
<Style TargetType="Border" BasedOn="{StaticResource RoundedBorderStyle}"/>
</Style.Resources>
</Style>
</Window.Resources>
myButton.Height = 50;
myButton.Width = 100;
myButton.FontSize = 20;
myButton.Content = "WPF !";
myButton.Foreground = new
SolidColorBrush(Colors.Yellow);
myButton.Background = new
SolidColorBrush(Colors.Green);
Foreground="Yellow" Background="Green" />
Controale WPF (componente vizuale)
FRAME (cadru/ container de navigare) - conținut navigabil în fereastră
- container folosit pentru a conține pagini, permițând navigarea între ele (înainte de Frame, în fereastră sau pagină se poate adăuga un meniu fix (MainFrame = fereastră principal.
PAGINA 1
- control LABEL (etichetă pentru alt control - folosită pentru a afișa într-un TextBox text static, care nu poate fi modificat de utilizator)
- control TEXTBLOCK - cadru unde se afișează text care nu poate fi modificat de utilizator
- control TEXTBOX - chenar unde utilizatorul poate completa cu text
- control BUTTON - buton cu care se poate realiza o acțiune
PAGINA 2
Folosirea stilurilor în WPF
- definirea unui stil pentru un buton cu colțuri rotunjite, de exemplu, va fi utilă pentru a nu repeta scrierea proprietăților pentru alte butoane de același tip (pentru colțuri rotunjite este necesar un ControlTemplate, nu este suficient cu stil simplu)
- Control.Resources - stilul se folosește doar pentru un singur control;
- Window.Resources - stilul se folosește doar pentru o fereastră (de exemplu, pentru toate butoanele din fereastră);
- App.xaml - stilul se folosește în întreaga aplicație (de exemplu, pentru toate butoanele din aplicație)
Înainte de a defini Grid (sau alt panou), se va scrie elementul XAML <Page.Resources> pentru stabilirea proprietăților unui stil.
<Page.Resources>
<Style x:Key="PageTitleStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="24"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="Foreground" Value="DarkBlue"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Margin" Value="0,10"/>
</Style>
<Style x:Key="MenuButtonStyle" TargetType="Button">
<Setter Property="Background" Value="DarkSlateBlue"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Margin" Value="5"/>
<Setter Property="Padding" Value="10,5"/>
<Setter Property="Width" Value="150"/>
</Style>
</Page.Resources>
În interiorul panoului Grid (sau alt panou), în descrierea butonului deja existent se va adăuga:
Style="{StaticResource RoundedButtonStyle}"/>
Sau click dreapta pe buton existent sau nou adăugat, Edit Template > Apply Resource > RoundedButtonStyle
CREATE A NEW PROJECT > se alege WPF APP (.NET FRAMEWORK) > (în fereastra Configure your new project - Project Name: HelloWorldWPF, - Solution Name: HelloWorldWPF_CS)
În panoul SOLUTION EXPLORER (se află de obicei în dreapta ecranului) se afișează structura proiectului.
În fereastra principală, care se editează, cu aspect grafic de pagină/ tablă albă (Designer - Main Window) se pot adăuga componente/ controale fie prin scrierea directă a codului XAML, fie prin tragerea din panoul Tool Box (care va apărea în partea stângă a ecranului prin activare din Meniu > View > Toolbox) - sub fereastră se văd opțiunile (secțiunile) Design sau XAML (pentru editarea codului/ personalizarea controalelor) - numele controalelor se pot modifica din Proprietăți
- textBlockHello
- textBoxUsername
- buttonSayHello
În vizualizarea (marcajul) XAML va apărea (MainWindow.xaml):
<Window x:Class="HelloWorldWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWorldWPF"
mc:Ignorable="d"
WindowStartupLocation="CenterScreen"
MinHeight="260" MinWidth="380"
Height="320" Width="520"
Title="Hello, World!" >
<Grid Background="Ivory">
<TextBlock x:Name="textBlockHello"
Background="Khaki"
Margin="140,90,0,0"
VerticalAlignment="Top" HorizontalAlignment="Left"
TextWrapping="Wrap"
Text="Hello, World!" FontSize="36" TextAlignment="Center" />
<TextBox x:Name="textBoxUsername"
Margin="140,154,0,0"
VerticalAlignment="Top" HorizontalAlignment="Left"
Width="210" Height="30"
IsTabStop="True" TabIndex="1"
TextWrapping="Wrap"
Text="" FontSize="10" Foreground="Gray" TextChanged="textBoxUsername_TextChanged" />
<Button x:Name="buttonSayHello"
Background="WhiteSmoke"
Margin="140,194,0,0"
VerticalAlignment="Top" HorizontalAlignment="Left"
Width="210" Height="40"
IsTabStop="True" TabIndex="2"
Click="buttonSayHello_Click"
Content="Scrie numele pentru a primi salut"
FontSize="14" />
</Grid>
</Window>
SELECTAREA IMPLICITĂ A UNUI BUTON (un buton dintre mai multe este activat implicit) - în secțiunea XAML de sub (Designer), pentru HelloButton, de exemplu, se adaugă atributul IsCheked, setat cu True (adică: IsChecked="True").
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace HelloWorldWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
// constructorul implicit al clasei
{
public MainWindow()
{
InitializeComponent();
// se setează primul control selectat
textBoxUsername.Focus();
}
// METODE PRIVATE AJUTĂTOARE
private void SayHello()
{
string username = textBoxUsername.Text.Trim();
if (string.IsNullOrEmpty(username))
{
username = "World";
}
string message = $"Hello, {username}!";
string caption = "Hello...";
MessageBox.Show(message, caption,
MessageBoxButton.OK,
MessageBoxImage.Information);
textBlockHello.Text = message;
}
// EVENIMENTE
private void buttonSayHello_Click(object sender, RoutedEventArgs e)
{
SayHello();
}
private void textBoxUsername_TextChanged(object sender, TextChangedEventArgs e)
{
}
}
}
În MENIU se alege DEBUG > START DEBUGGING (se va deschide o fereastră în care se afișează: Hello, World! Press ENTER to exit...
Pentru oprirea forțată se alege butonul STOP DEBUGGING.
Depanarea pas cu pas se face folosind comenzile STEP INTO sau STEP OVER
-* cu proprietatea TextWrapping="Wrap" un control text trece textul pe rândul următor când nu încape pe un rând (nu este valabil la controlul Label!)
ADĂUGAREA UNEI FERESTRE NOI LA PROIECT: În panoul SOLUTION EXPLORER (din dreapta ecranului), click dreapta pe numele proiectului > Add > Window (WPF) > redenumirea acesteia Window_Informatii
În fereastra principală, se adaugă - din Tool Box - un panou StackPanel pentru un meniu destinat butonului pentru NAVIGARE către noua fereastră și un cadru Frame., care să asigure navigarea spre fereastra secundară.
În vizualizarea (marcajul) XAML (MainWindow.xaml) va apărea - pe lângă codul anterior al proiectului HELLO, WORLD (se va adăuga după <Grid Background="Ivory">:
<StackPanel x:Name="buttonsPanel" Orientation="Horizontal"
VerticalAlignment="Top" Height="50" Background="Ivory">
<Button x:Name="buttonInformatii" Content="INFORMAȚII UTILE"
HorizontalAlignment="Left"
Margin="15,5,0,5"
FontSize="11"
Background="DarkSlateGray"
Foreground="White"
Height="30" Width="102"
Click="buttonInformatii_Click" />
</StackPanel>
<Frame x:Name="MainFrame" Margin="15 75 15 15"
NavigationUIVisibility="Hidden"/>
În codul C# (MainWindow.xaml.cs) se va adăuga la codul anterior al proiectului HELLO, WORLD, după metoda buttonSayHello_Click, pentru a se realiza acțiunea de navigare la noua fereastră cu INFORMAȚII:
private void buttonInformatii_Click(object sender, RoutedEventArgs e)
{
Window_Informatii win = new Window_Informatii
{
WindowStartupLocation = WindowStartupLocation.CenterScreen
};
win.Show();
}
În vizualizarea (marcajul) XAML al noii ferestre (Window_Informatii.xaml) va apărea:
<Window x:Class="HelloWorldWPF.Window_Informatii"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Informatii"
Height="300"
Width="500">
<Grid>
<Label x:Name="labelTitle" Background="AliceBlue"
Margin="0" Height="40"
Content="Fereastra INFORMATII UTILE" Foreground="Navy"
VerticalAlignment="Top"
FontSize="20"
HorizontalContentAlignment="Center" />
<Label Content="*Aceasta este o etichetă (Label) - text care nu poate fi modificat de utilizator."
HorizontalAlignment="Center"
Margin="0,45,0,0"
FontSize="10"
VerticalAlignment="Top" VerticalContentAlignment="Center"/>
</Grid>
</Window>
În codul C# (Window_Informatii.xaml.cs):
using System.Windows;
namespace HelloWorldWPF
{
public partial class Window_Informatii : Window
{
public Window_Informatii()
{
InitializeComponent();
}
}
}
ADĂUGAREA UNEI PAGINI NOI LA PROIECT: În panoul SOLUTION EXPLORER (din dreapta ecranului), click dreapta pe numele proiectului > Add > Page (WPF) > redenumirea acesteia LoginPage
În vizualizarea (marcajul) XAML (MainWindow.xaml) va apărea - pe lângă codul anterior al proiectului HELLO, WORLD (se va adăuga după <Grid Background="Ivory">, în StackPanel de la Window_Informatii)::
<Button x:Name="buttonLogin" Content="LOGIN"
Margin="270,5,0,5"
FontSize="15"
Background="DarkBlue"
Foreground="White"
Height="30" Width="105"
Click="buttonLogin_Click" />
În codul C# (MainWindow.xaml.cs) se va adăuga la codul anterior al proiectului HELLO, WORLD, după metoda buttonInformatii_Click:
private void buttonLogin_Click(object sender, RoutedEventArgs e)
{
this.Content = new LoginPage();
}
În vizualizarea (marcajul) XAML al noii ferestre (LoginPage.xaml) va apărea:
<Page x:Class="HelloWorldWPF.LoginPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:HelloWorldWPF"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="Login">
<Grid Background="Ivory">
<StackPanel Grid.Row="0">
<Label x:Name="labelTitle"
Background="AliceBlue"
Height="40"
Content="LOGIN"
Foreground="Navy"
FontSize="20"
HorizontalContentAlignment="Center"/>
<Grid Height="100" Margin="0,20,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="10"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="Username"
VerticalAlignment="Center" HorizontalAlignment="Right"
FontSize="16" TextAlignment="Center"
Grid.Row="0" Grid.Column="0" />
<TextBlock Text="Password"
VerticalAlignment="Center" HorizontalAlignment="Right"
Grid.Row="2" Grid.Column="0"
FontSize="16" TextAlignment="Center" />
<TextBox x:Name="textBoxUsername"
Margin="0,5,20,5"
VerticalContentAlignment="Center"
Grid.Row="0" Grid.Column="2"
FontSize="16" />
<PasswordBox x:Name="passwordBox"
FontSize="16"
Margin="0,5,20,5"
VerticalContentAlignment="Center"
Grid.Row="2" Grid.Column="2" />
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"
Margin="0,20,0,0" Height="auto">
<Button x:Name="buttonOK" Content="OK"
FontSize="16" IsDefault="True"
Background="WhiteSmoke"
Margin="10,0" Height="40" Width="120"
Click="buttonOK_Click" />
<Button x:Name="buttonCancel" Content="Cancel"
FontSize="16" IsCancel="True"
Margin="10,0" Height="40" Width="120"
Click="buttonCancel_Click" />
</StackPanel>
</StackPanel>
</Grid>
</Page>
În vizualizarea (marcajul) XAML al noii ferestre (LoginPage.xaml.cs) va apărea:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace HelloWorldWPF
{
public partial class LoginPage : Page
{
public string Username { get; private set; }
public string Password { get; private set; }
public LoginPage()
{
InitializeComponent();
textBoxUsername.Focus();
}
private void buttonOK_Click(object sender, RoutedEventArgs e)
{
string username = textBoxUsername.Text;
string password = passwordBox.Password;
MessageBox.Show($"Username = {username} \n Password = {password}",
"Login",
MessageBoxButton.OK,
MessageBoxImage.Information);
}
private void buttonCancel_Click(object sender, RoutedEventArgs e)
{
NavigationService?.GoBack();
}
}
}
(mod de lucru: Database First - pe platforma .NET 8).
* cu EF se creează automat tabele
- în XAMPP (se descarcă gratuit și se instalează MySQL, Apache și phpMyAdmin - se instalează și phpMyAdmin) - la Action: START Apache și MySQL, apoi click ADMIN MySQL
- Local Host - numele serverului pe calculator: - adresa Local Host (afișată sus: Server 127.0.0.1
- pe serverul MySQL (Server 127.0.0.1 - în meniu BAZĂ DE DATE / DATABASES se CREEAZĂ baza de date: în căsuța Database name se notează Exercitiu
- pe serverul MySQL (Server 127.0.0.1 - în meniu CONTURI UTILIZATOR/ USER ACCOUNTS se CREEAZĂ utilizator: user și parola: parolaTa (la Nume gazdă se poate selecta Orice gazdă și se completează alăturat %) - administratorul trebuie să acorde toate privilegii Userului) are activat protocolul TCP/IP și lucrează pe portul TCP 3306;
- o bază de date nou creată nu conține tabele sau date, acestea trebuie create (se poate folosi un script SQL pentru importul tuturor tabelelor cu date) - în baza de date Exercitiu - Import - se alege fișierul din calculator; în meniu - la Structură se va vedea conținutul bazei de date, al tabelelor;
- vizualizarea DIAGRAMEI - din meniu - More - Designer;
- INTEROGARE - din meniu - SQL
CREATE A NEW PROJECT > FILE - NEW PROJECT - Project Name: HelloWorldWPF, - Solution Name: HelloWorldWPF_CS - se alege WPF APP (. NET8.0)
(în codul XAML al ferestrei principale - MainWindow.xaml)
<Window x:Class="HelloWorldWPF"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:HelloWorldWPF"
mc:Ignorable="d"
Title="HelloWorldWPF - MainWindow"
Height="550" Width="800"
ResizeMode="CanResizeWithGrip"
WindowStartupLocation="CenterScreen">
<Grid>
</Grid>
</Window>
(în SOLUTION EXPLORER se creează un folder DATA - click dreapta pe proiect) ADD > NEW FOLDER > Rename... ;
(adăugarea la proiect a pachetelor NuGet - click dreapta pe proiect) MANAGE NUGET PACKAGES > Microsoft.EntityFrameworkCore (v.8.0.22), Microsoft.EntityFrameworkCore.Design (v.8.0.22), Microsoft.EntityFrameworkCore.Proxies (v.8.0.22), Microsoft.EntityFrameworkCore.Tools (v.8.0.22), Pomelo.EntityFrameworkCore.MySQL (v.8.0.3 - dacă se folosește MySQL), Microsoft.EntityFrameworkCore.SqlServer (v.8.0.22 - dacă se folosește MS SQL Server), System.Text.JSON (v.8.0.6) > BUILD
Prima modalitate: TOOLS > NuGet Package Manager > Package Manager Console > Scaffold-DbContext "Server=localhost;Port=3306;Database=Exercitiu;Uid=user;Pwd=ParolaTa" Pomelo.EntityFrameworkCore.MySql -OutputDir Models -ContextDir Data -Context ExempluContext
A doua modalitate (fără Scaffold-DbContext): se creează manual - în folderul Data - clasa DbContext
Susțineți-ne (www.rosfera.ro/sustine) să putem susține acest proiect si celelalte activități de la RoSfera
* distribuind postările noastre, iar dacă aveți posibilitatea
* fie să redirecționați din impozitul pe venit personal sau afacerii,
* fie să sponsorizați (*cheltuielile unei persoane juridice cu sponsorizările se scad din impozitul pe profit datorat, fără a depăși 20% din acesta și nici 0,75% din cifra de afaceri -sunt cheltuieli nedeductibile integral). sau
* să donați, fiind ONG, depindem de implicarea celor care ne apreciază activitatea pe care o desfășurăm împreună cu colaboratorii.
- VOLUNTARII (creativi și nu numai) sunt promovați pe căile noastre și pot beneficia de diverse oportunități din activitățile noastre sau din partea partenerilor
- PARTENERII (companii, organizații, instituții) sunt piloni de bază ai activității noastre și dorim să le susținem activitatea, la rândul nostru, prin metode și căi agreate reciproc.
- SPONSORII ȘI CEI CARE NE SUSȚIN CU DONAȚII vor avea de câștigat accesul la valorile pe care le promovăm și la activitățile pe care le derulăm, precum și beneficii anunțate în cadrul fiecărei activități în parte.
- Donații putem primi și în contul ASOCIAȚIEI ROSFERA (înregistrată la Registrul Comerțului/ Asociațiilor și Fundațiilor nr. 341/ 25.05.2021, C.I.F. 44439483):
RO27 CARP 0250 0160 0650 RO01, deschis la PATRIA BANK, iar pentru sponsorizări vă rugăm să ne contactați pentru contract.
- În PUNCTELE DE CULTURĂ sau în atelierele noastre ne-ar fi de folos implicarea prin servicii sau donații, astfel ne susțineți activitățile și proiectele și putem, la rândul nostru, să susținem creativii.
Apreciem și pe această cale implicarea celor care ni s-au alăturat în proiecte sau activități: