├── .gitignore
├── README.md
├── Recursos
└── cheat_sheet_java8.png
├── Soluciones
├── 01-Optional
│ ├── .idea
│ │ ├── .gitignore
│ │ ├── description.html
│ │ ├── encodings.xml
│ │ ├── misc.xml
│ │ ├── modules.xml
│ │ └── project-template.xml
│ ├── Optional.iml
│ └── src
│ │ └── es
│ │ └── joseluisgs
│ │ └── dam
│ │ └── Main.java
├── 02-Formateadores
│ ├── .idea
│ │ ├── .gitignore
│ │ ├── description.html
│ │ ├── encodings.xml
│ │ ├── misc.xml
│ │ ├── modules.xml
│ │ └── project-template.xml
│ ├── KakaJava.iml
│ └── src
│ │ └── es
│ │ └── joseluisgs
│ │ └── dam
│ │ └── Main.java
├── 03-BD-Relacional
│ ├── .gitignore
│ ├── .idea
│ │ ├── .gitignore
│ │ ├── compiler.xml
│ │ ├── encodings.xml
│ │ ├── jarRepositories.xml
│ │ ├── misc.xml
│ │ ├── uiDesigner.xml
│ │ └── vcs.xml
│ ├── docker
│ │ ├── docker-compose.yml
│ │ └── mariadb
│ │ │ ├── Dockerfile
│ │ │ └── sql
│ │ │ └── init-db.sql
│ ├── pom.xml
│ ├── sql
│ │ └── mapas.sql
│ └── src
│ │ └── main
│ │ └── java
│ │ └── es
│ │ └── joseluisgs
│ │ └── dam
│ │ ├── App.java
│ │ ├── database
│ │ └── DataBaseManager.java
│ │ └── model
│ │ └── User.java
├── 04-MVC-Paises-BBDD-DI
│ ├── .gitignore
│ ├── SecuenciaPaises.iml
│ ├── data
│ │ └── backup.json
│ ├── docker
│ │ ├── docker-compose.yml
│ │ └── mariadb
│ │ │ ├── Dockerfile
│ │ │ └── sql
│ │ │ └── init-db.sql
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── es
│ │ │ │ └── joseluisgs
│ │ │ │ └── dam
│ │ │ │ ├── Main.java
│ │ │ │ ├── comparators
│ │ │ │ ├── PaisCodigoComparator.java
│ │ │ │ └── PaisNombreComparator.java
│ │ │ │ ├── controllers
│ │ │ │ ├── AcuerdoController.java
│ │ │ │ ├── BackupManager.java
│ │ │ │ ├── DataBaseManager.java
│ │ │ │ └── PaisController.java
│ │ │ │ ├── exceptions
│ │ │ │ ├── AcuerdoException.java
│ │ │ │ └── PaisException.java
│ │ │ │ ├── models
│ │ │ │ ├── Acuerdo.java
│ │ │ │ ├── Backup.java
│ │ │ │ ├── LineaAcuerdo.java
│ │ │ │ └── Pais.java
│ │ │ │ ├── repositories
│ │ │ │ ├── CRUDRepository.java
│ │ │ │ ├── acuerdos
│ │ │ │ │ ├── AcuerdoRepository.java
│ │ │ │ │ └── IAcuerdoRepository.java
│ │ │ │ └── paises
│ │ │ │ │ ├── IPaisRepository.java
│ │ │ │ │ └── PaisRepository.java
│ │ │ │ ├── services
│ │ │ │ └── Storage
│ │ │ │ │ ├── IStorage.java
│ │ │ │ │ ├── IStorageBackup.java
│ │ │ │ │ └── StorageBackupJsonFile.java
│ │ │ │ ├── utils
│ │ │ │ ├── ApplicationProperties.java
│ │ │ │ ├── Console.java
│ │ │ │ └── Formatter.java
│ │ │ │ └── views
│ │ │ │ └── PaisView.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── sql
│ │ │ └── init-db.sql
│ │ └── test
│ │ ├── java
│ │ └── es
│ │ │ └── joseluisgs
│ │ │ └── dam
│ │ │ ├── MainTest.java
│ │ │ ├── controllers
│ │ │ ├── AcuerdoControllerMockTest.java
│ │ │ ├── AcuerdoControllerTest.java
│ │ │ ├── PaisControllerMockTest.java
│ │ │ └── PaisControllerTest.java
│ │ │ ├── repositories
│ │ │ ├── acuerdos
│ │ │ │ └── AcuerdoRepositoryTest.java
│ │ │ └── paises
│ │ │ │ └── PaisRepositoryTest.java
│ │ │ └── utilities
│ │ │ ├── DataBase.java
│ │ │ └── DataDB.java
│ │ └── resources
│ │ ├── application.properties
│ │ └── sql
│ │ └── init-db.sql
├── 05-JavaLambdaFuncional
│ ├── .idea
│ │ ├── .gitignore
│ │ ├── description.html
│ │ ├── encodings.xml
│ │ ├── misc.xml
│ │ ├── modules.xml
│ │ ├── project-template.xml
│ │ └── uiDesigner.xml
│ ├── JavaLambdaFuncional.iml
│ └── src
│ │ └── es
│ │ └── joseluisgs
│ │ └── dam
│ │ ├── CalcImperativeA.java
│ │ ├── CalcImperativeB.java
│ │ ├── CalcImperativeC.java
│ │ ├── ICalcFunctional.java
│ │ ├── ICalcImperativeA.java
│ │ ├── ICalcImperativeB.java
│ │ ├── ICalcImperativeC.java
│ │ └── Main.java
├── 06-JavaStreamAPI
│ ├── .idea
│ │ ├── .gitignore
│ │ ├── description.html
│ │ ├── encodings.xml
│ │ ├── misc.xml
│ │ ├── modules.xml
│ │ └── project-template.xml
│ ├── JavaStreamAPI.iml
│ └── src
│ │ └── es
│ │ └── joseluisgs
│ │ └── dam
│ │ ├── Main.java
│ │ └── Persona.java
├── 07-StreamEjemplos
│ ├── .gitignore
│ ├── .idea
│ │ ├── .gitignore
│ │ ├── description.html
│ │ ├── encodings.xml
│ │ ├── misc.xml
│ │ ├── modules.xml
│ │ ├── project-template.xml
│ │ └── vcs.xml
│ ├── 02-Stream.iml
│ ├── data
│ │ └── products.csv
│ └── src
│ │ └── es
│ │ └── joseluisgs
│ │ └── dam
│ │ ├── ConsultasAlumnos.java
│ │ ├── ConsultasCanciones.java
│ │ ├── ConsultasProductos.java
│ │ ├── Main.java
│ │ ├── model
│ │ ├── Alumno.java
│ │ ├── Cancion.java
│ │ └── Product.java
│ │ └── utils
│ │ └── Util.java
├── 08-MVC-Paises-BBDD-Optional-Functional
│ ├── .gitignore
│ ├── SecuenciaPaises.iml
│ ├── data
│ │ └── backup.json
│ ├── docker
│ │ ├── docker-compose.yml
│ │ └── mariadb
│ │ │ ├── Dockerfile
│ │ │ └── sql
│ │ │ └── init-db.sql
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── es
│ │ │ │ └── joseluisgs
│ │ │ │ └── dam
│ │ │ │ ├── Main.java
│ │ │ │ ├── controllers
│ │ │ │ ├── AcuerdoController.java
│ │ │ │ ├── BackupManager.java
│ │ │ │ ├── DataBaseManager.java
│ │ │ │ └── PaisController.java
│ │ │ │ ├── exceptions
│ │ │ │ ├── AcuerdoException.java
│ │ │ │ └── PaisException.java
│ │ │ │ ├── models
│ │ │ │ ├── Acuerdo.java
│ │ │ │ ├── Backup.java
│ │ │ │ ├── LineaAcuerdo.java
│ │ │ │ └── Pais.java
│ │ │ │ ├── repositories
│ │ │ │ ├── CRUDRepository.java
│ │ │ │ ├── acuerdos
│ │ │ │ │ ├── AcuerdoRepository.java
│ │ │ │ │ └── IAcuerdoRepository.java
│ │ │ │ └── paises
│ │ │ │ │ ├── IPaisRepository.java
│ │ │ │ │ └── PaisRepository.java
│ │ │ │ ├── services
│ │ │ │ └── Storage
│ │ │ │ │ ├── IStorage.java
│ │ │ │ │ ├── IStorageBackup.java
│ │ │ │ │ └── StorageBackupJsonFile.java
│ │ │ │ ├── utils
│ │ │ │ ├── ApplicationProperties.java
│ │ │ │ ├── Console.java
│ │ │ │ └── Formatter.java
│ │ │ │ └── views
│ │ │ │ └── PaisView.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── sql
│ │ │ └── init-db.sql
│ │ └── test
│ │ ├── java
│ │ └── es
│ │ │ └── joseluisgs
│ │ │ └── dam
│ │ │ ├── MainTest.java
│ │ │ ├── controllers
│ │ │ ├── AcuerdoControllerMockTest.java
│ │ │ ├── AcuerdoControllerTest.java
│ │ │ ├── PaisControllerMockTest.java
│ │ │ └── PaisControllerTest.java
│ │ │ ├── repositories
│ │ │ ├── acuerdos
│ │ │ │ └── AcuerdoRepositoryTest.java
│ │ │ └── paises
│ │ │ │ └── PaisRepositoryTest.java
│ │ │ └── utilities
│ │ │ ├── DataBase.java
│ │ │ └── DataDB.java
│ │ └── resources
│ │ ├── application.properties
│ │ └── sql
│ │ └── init-db.sql
├── 09-AccidentesStream
│ ├── .gitignore
│ ├── .idea
│ │ ├── .gitignore
│ │ ├── compiler.xml
│ │ ├── description.html
│ │ ├── encodings.xml
│ │ ├── jarRepositories.xml
│ │ ├── libraries
│ │ │ └── Maven__org_projectlombok_lombok_1_18_22.xml
│ │ ├── misc.xml
│ │ ├── modules.xml
│ │ └── project-template.xml
│ ├── AccidentesStream.iml
│ ├── data
│ │ └── accidentes.csv
│ ├── pom.xml
│ └── src
│ │ └── main
│ │ └── java
│ │ └── es
│ │ └── joseluisgs
│ │ └── dam
│ │ ├── Accidente.java
│ │ ├── AccidentesController.java
│ │ └── Main.java
├── 10-MVC-Paises-BBDD-Dagger-Lombok
│ ├── .gitignore
│ ├── SecuenciaPaises.iml
│ ├── data
│ │ └── backup.json
│ ├── docker
│ │ ├── docker-compose.yml
│ │ └── mariadb
│ │ │ ├── Dockerfile
│ │ │ └── sql
│ │ │ └── init-db.sql
│ ├── pom.xml
│ └── src
│ │ ├── main
│ │ ├── java
│ │ │ └── es
│ │ │ │ └── joseluisgs
│ │ │ │ └── dam
│ │ │ │ ├── DI
│ │ │ │ ├── controllers
│ │ │ │ │ └── controllers
│ │ │ │ │ │ ├── AcuerdoControllerDI.java
│ │ │ │ │ │ ├── BackupManagerDI.java
│ │ │ │ │ │ └── PaisControllerDI.java
│ │ │ │ └── modules
│ │ │ │ │ ├── AcuerdoRepositoryModule.java
│ │ │ │ │ ├── DataBaseManagerModule.java
│ │ │ │ │ ├── PaisRepositoryModule.java
│ │ │ │ │ └── StorageBackupModule.java
│ │ │ │ ├── Main.java
│ │ │ │ ├── controllers
│ │ │ │ ├── AcuerdoController.java
│ │ │ │ ├── BackupManager.java
│ │ │ │ ├── DataBaseManager.java
│ │ │ │ └── PaisController.java
│ │ │ │ ├── exceptions
│ │ │ │ ├── AcuerdoException.java
│ │ │ │ └── PaisException.java
│ │ │ │ ├── models
│ │ │ │ ├── Acuerdo.java
│ │ │ │ ├── Backup.java
│ │ │ │ ├── LineaAcuerdo.java
│ │ │ │ └── Pais.java
│ │ │ │ ├── repositories
│ │ │ │ ├── CRUDRepository.java
│ │ │ │ ├── acuerdos
│ │ │ │ │ ├── AcuerdoRepository.java
│ │ │ │ │ └── IAcuerdoRepository.java
│ │ │ │ └── paises
│ │ │ │ │ ├── IPaisRepository.java
│ │ │ │ │ └── PaisRepository.java
│ │ │ │ ├── services
│ │ │ │ └── Storage
│ │ │ │ │ ├── IStorage.java
│ │ │ │ │ ├── IStorageBackup.java
│ │ │ │ │ └── StorageBackupJsonFile.java
│ │ │ │ ├── utils
│ │ │ │ ├── ApplicationProperties.java
│ │ │ │ ├── Console.java
│ │ │ │ └── Formatter.java
│ │ │ │ └── views
│ │ │ │ └── PaisView.java
│ │ └── resources
│ │ │ ├── application.properties
│ │ │ └── sql
│ │ │ └── init-db.sql
│ │ └── test
│ │ ├── java
│ │ └── es
│ │ │ └── joseluisgs
│ │ │ └── dam
│ │ │ ├── MainTest.java
│ │ │ ├── controllers
│ │ │ ├── AcuerdoControllerMockTest.java
│ │ │ ├── AcuerdoControllerTest.java
│ │ │ ├── PaisControllerMockTest.java
│ │ │ └── PaisControllerTest.java
│ │ │ ├── repositories
│ │ │ ├── acuerdos
│ │ │ │ └── AcuerdoRepositoryTest.java
│ │ │ └── paises
│ │ │ │ └── PaisRepositoryTest.java
│ │ │ └── utilities
│ │ │ ├── DataBase.java
│ │ │ └── DataDB.java
│ │ └── resources
│ │ ├── application.properties
│ │ └── sql
│ │ └── init-db.sql
└── 11-CRUD-SQLite-GSon
│ ├── .gitignore
│ ├── .idea
│ ├── .gitignore
│ ├── dataSources.xml
│ ├── deployment.xml
│ ├── inspectionProfiles
│ │ └── Project_Default.xml
│ ├── misc.xml
│ ├── uiDesigner.xml
│ └── vcs.xml
│ ├── data
│ └── personas.json
│ ├── db
│ └── personas.db
│ ├── pom.xml
│ └── src
│ └── main
│ └── java
│ └── es
│ └── joseluisgs
│ └── dam
│ ├── Main.java
│ ├── controllers
│ └── PersonasController.java
│ ├── managers
│ └── DataBaseManager.java
│ ├── models
│ └── Persona.java
│ ├── repositories
│ ├── CRUDRepository.java
│ ├── IPersonasRepository.java
│ └── PersonasRepository.java
│ ├── services
│ ├── Backup.java
│ ├── BackupJSON.java
│ └── IBackupJSON.java
│ └── utils
│ └── LocalDateAdapter.java
└── UD09.pdf
/.gitignore:
--------------------------------------------------------------------------------
1 | *.pptx
2 | .DS_Store
3 | /Ejercicios/*.docx
4 | upload.sh
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Programación - 09 Gestión de Bases de Datos mediante código
2 |
3 | Tema 09 Gestión de Bases de Datos mediante código. 1DAM. Curso 2021/2022.
4 |
5 | 
6 |
7 | ## Contenidos
8 | 1. Bases de datos Relacionales
9 | 2. El Desfase Objeto-Relacional
10 | 3. Acceso a Base de Datos Relacionales
11 | 4. CRUD con JDBC
12 | 5. El problema de Null y el tipo Optional
13 | 6. Procesando información en colecciones. API Stream y programación funcional
14 |
15 |
16 | ## Recursos
17 | - Twitter: https://twitter.com/joseluisgonsan
18 | - GitHub: https://github.com/joseluisgs
19 | - Web: https://joseluisgs.github.io
20 | - Discord: https://discord.gg/uv7GcytM
21 | - Aula Virtual: https://aulavirtual33.educa.madrid.org/ies.luisvives.leganes/course/view.php?id=245
22 |
23 |
24 |
25 | ## Autor
26 |
27 | Codificado con :sparkling_heart: por [José Luis González Sánchez](https://twitter.com/joseluisgonsan)
28 |
29 | [](https://twitter.com/joseluisgonsan)
30 | [](https://github.com/joseluisgs)
31 |
32 | ### Contacto
33 |
34 | Cualquier cosa que necesites házmelo saber por si puedo ayudarte 💬.
35 |
36 |
37 |
38 |
40 |
41 |
42 |
44 |
45 |
46 |
48 |
49 |
50 |
52 |
53 |
54 |
--------------------------------------------------------------------------------
/Recursos/cheat_sheet_java8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joseluisgs/Programacion-09-2021-2022/188c0476c2f30e7149340dda33239a3df1488e4b/Recursos/cheat_sheet_java8.png
--------------------------------------------------------------------------------
/Soluciones/01-Optional/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/Soluciones/01-Optional/.idea/description.html:
--------------------------------------------------------------------------------
1 | Simple Java application that includes a class with main()
method
--------------------------------------------------------------------------------
/Soluciones/01-Optional/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/01-Optional/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Soluciones/01-Optional/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Soluciones/01-Optional/.idea/project-template.xml:
--------------------------------------------------------------------------------
1 |
2 | IJ_BASE_PACKAGE
3 |
--------------------------------------------------------------------------------
/Soluciones/01-Optional/Optional.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Soluciones/01-Optional/src/es/joseluisgs/dam/Main.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | import java.util.Optional;
4 |
5 | public class Main {
6 |
7 | public static void main(String[] args) {
8 | System.out.println("Hello Optional!");
9 | sinOptional();
10 | conOptional();
11 | }
12 |
13 | private static void sinOptional() {
14 | // imaginamos que nos llega un null o no sabemos que es
15 | String nombre = null;
16 | // y se nos olvida el if...
17 | // System.out.println("Nombre: " + nombre.length());
18 | // ponemos el if, o try catch por todos lados
19 | if (nombre != null) {
20 | System.out.println("Nombre: " + nombre.length());
21 | }
22 | try {
23 | System.out.println("Nombre: " + nombre.length());
24 | } catch (NullPointerException e) {
25 | System.out.println("puffff");
26 | // throw new RuntimeException("No hay nombre");
27 | }
28 | }
29 |
30 | public static void conOptional() {
31 | String nombre = null;
32 | Optional nombreOpt = Optional.ofNullable(nombre);
33 | // Podemos comrpbar si está presente o no
34 | if (nombreOpt.isPresent()) {
35 | System.out.println("Nombre: " + nombreOpt.get().length());
36 | }
37 | // o si está vacío
38 | if (!nombreOpt.isEmpty()) {
39 | System.out.println("Nombre: " + nombreOpt.get().length());
40 | }
41 | // Lo importante es que siempre que quiera usarlo necesito el get!! y si no
42 | // Puedo jugar con valores por defecto
43 | System.out.println("Nombre: " + nombreOpt.orElse("default").length());
44 | // O lanzar una excepción controlada...
45 | // System.out.println("Nombre: " + nombreOpt.orElseThrow(() -> new RuntimeException("No hay nombre")));
46 | Optional opt = Optional.of("DAM");
47 | String name = opt.get();
48 | System.out.println("Nombre: " + name);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/Soluciones/02-Formateadores/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/Soluciones/02-Formateadores/.idea/description.html:
--------------------------------------------------------------------------------
1 | Simple Java application that includes a class with main()
method
--------------------------------------------------------------------------------
/Soluciones/02-Formateadores/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/02-Formateadores/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Soluciones/02-Formateadores/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Soluciones/02-Formateadores/.idea/project-template.xml:
--------------------------------------------------------------------------------
1 |
2 | IJ_BASE_PACKAGE
3 |
--------------------------------------------------------------------------------
/Soluciones/02-Formateadores/KakaJava.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Soluciones/02-Formateadores/src/es/joseluisgs/dam/Main.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | import java.text.NumberFormat;
4 | import java.time.LocalDate;
5 | import java.time.LocalDateTime;
6 | import java.time.format.DateTimeFormatter;
7 | import java.time.format.FormatStyle;
8 | import java.util.Date;
9 | import java.util.Locale;
10 | import java.util.StringTokenizer;
11 |
12 | public class Main {
13 |
14 | public static void main(String[] args) {
15 | // write your code here
16 | double numero = 123_456.789;
17 | LocalDateTime fecha = LocalDateTime.now();
18 |
19 | System.out.println(numero);
20 | System.out.println(fecha);
21 |
22 | Locale.setDefault(Locale.getDefault());
23 | System.out.println(Locale.getDefault());
24 |
25 | // Formatear la fecha
26 | System.out.println(dateParser(fecha, Locale.getDefault()));
27 |
28 | // Formatear el numero
29 | System.out.println(doubleParser(numero, new Locale("es", "ES")));
30 |
31 | // Formatear el dinero
32 | System.out.println(moneyParser(numero, new Locale("es", "ES")));
33 |
34 | // Formatear el porcentaje
35 | System.out.println(doublePercentParser(numero, new Locale("es", "ES")));
36 |
37 | String fechaString = "01/01/2020";
38 | String horaString = "11:13:14";
39 |
40 | DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
41 | LocalDateTime fechaHora = LocalDateTime.parse(fechaString + " " + horaString, formatter);
42 | System.out.println(fechaHora);
43 |
44 | formatter = DateTimeFormatter.ofPattern("HH:mm:ss");
45 | System.out.println(fechaHora.format(formatter));
46 |
47 | String token = ",";
48 | String cadena = "casa , pepe ,, , luis, jose ";
49 | String[] palabras = cadena.split(token);
50 | for (String palabra : palabras) {
51 | if (!palabra.isBlank()) {
52 | System.out.println(palabra.trim());
53 | }
54 | }
55 |
56 | StringTokenizer st = new StringTokenizer(cadena, token);
57 | while (st.hasMoreTokens()) {
58 | System.out.println(st.nextToken().trim());
59 | }
60 |
61 | }
62 |
63 | public static String dateParser(LocalDateTime date, Locale locale) {
64 | // private String pattern = "dd/MM/yyyy";
65 | return date.format(DateTimeFormatter
66 | .ofLocalizedDate(FormatStyle.FULL).withLocale(locale));
67 | }
68 |
69 | public static String moneyParser(Double money, Locale locale) {
70 | return NumberFormat.getCurrencyInstance(locale).format(money);
71 | }
72 |
73 | public static String doubleParser(Double number, Locale locale) {
74 | return NumberFormat.getNumberInstance(locale).format(number);
75 | }
76 |
77 | public static String doublePercentParser(Double number, Locale locale) {
78 | return NumberFormat.getPercentInstance(locale).format(number);
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/.gitignore:
--------------------------------------------------------------------------------
1 | /out
2 | /target
3 |
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # Indicamos la versión
2 | # Para iniciar docker-compose up -d
3 | version: '3.7'
4 |
5 | # Mis servicios
6 | # Iniciamos los servicios
7 | services:
8 | # MARIA DB
9 | mariadb:
10 | build: ./mariadb
11 | image: mariadb
12 | container_name: mariadb
13 | ports:
14 | - 3306:3306
15 | expose:
16 | - 3306
17 | volumes:
18 | - mariadb-volume:/var/lib/mysql
19 | networks:
20 | - mariadb-network
21 | # restart: always
22 |
23 | # ADMIN MARIADB
24 | adminer:
25 | image: adminer
26 | container_name: adminer
27 | # restart: always
28 | ports:
29 | - 8080:8080
30 | networks:
31 | - mariadb-network
32 | depends_on:
33 | - mariadb
34 |
35 | # Mi volumenes de datos compartidos
36 | volumes:
37 | mariadb-volume:
38 |
39 | # Si queremos que tengan una red propia a otros contenedores
40 | networks:
41 | mariadb-network:
42 | driver: bridge
43 |
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/docker/mariadb/Dockerfile:
--------------------------------------------------------------------------------
1 | # MariaDB
2 | FROM yobasystems/alpine-mariadb:10
3 | # FROM mariadb:10.5
4 |
5 | # Configuramos BBDD
6 | ENV MYSQL_ROOT_PASSWORD 123
7 | ENV MYSQL_USER blog
8 | ENV MYSQL_PASSWORD blog1234
9 | ENV MYSQL_DATABASE blog
10 |
11 | # Copiamos los ficheros sql para que se ejecuten
12 | COPY ./sql /docker-entrypoint-initdb.d/
--------------------------------------------------------------------------------
/Soluciones/03-BD-Relacional/src/main/java/es/joseluisgs/dam/model/User.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.model;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDate;
7 |
8 | @Data
9 | @Builder
10 | public class User {
11 | private Long id;
12 | private String nombre;
13 | private String email;
14 | private String password;
15 | private LocalDate fechaRegistro;
16 |
17 |
18 | public User(Long id, String nombre, String email, String password, LocalDate fechaRegistro) {
19 | this.id = id;
20 | this.nombre = nombre;
21 | this.email = email;
22 | this.fechaRegistro = fechaRegistro;
23 | this.password = password;
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/maven,java,intellij+all
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=maven,java,intellij+all
4 |
5 | ### Intellij+all ###
6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
8 |
9 | # User-specific stuff
10 | .idea/**/workspace.xml
11 | .idea/**/tasks.xml
12 | .idea/**/usage.statistics.xml
13 | .idea/**/dictionaries
14 | .idea/**/shelf
15 |
16 | # AWS User-specific
17 | .idea/**/aws.xml
18 |
19 | # Generated files
20 | .idea/**/contentModel.xml
21 |
22 | # Sensitive or high-churn files
23 | .idea/**/dataSources/
24 | .idea/**/dataSources.ids
25 | .idea/**/dataSources.local.xml
26 | .idea/**/sqlDataSources.xml
27 | .idea/**/dynamic.xml
28 | .idea/**/uiDesigner.xml
29 | .idea/**/dbnavigator.xml
30 |
31 | # Gradle
32 | .idea/**/gradle.xml
33 | .idea/**/libraries
34 |
35 | # Gradle and Maven with auto-import
36 | # When using Gradle or Maven with auto-import, you should exclude module files,
37 | # since they will be recreated, and may cause churn. Uncomment if using
38 | # auto-import.
39 | # .idea/artifacts
40 | # .idea/compiler.xml
41 | # .idea/jarRepositories.xml
42 | # .idea/modules.xml
43 | # .idea/*.iml
44 | # .idea/modules
45 | # *.iml
46 | # *.ipr
47 |
48 | # CMake
49 | cmake-build-*/
50 |
51 | # Mongo Explorer plugin
52 | .idea/**/mongoSettings.xml
53 |
54 | # File-based project format
55 | *.iws
56 |
57 | # IntelliJ
58 | out/
59 |
60 | # mpeltonen/sbt-idea plugin
61 | .idea_modules/
62 |
63 | # JIRA plugin
64 | atlassian-ide-plugin.xml
65 |
66 | # Cursive Clojure plugin
67 | .idea/replstate.xml
68 |
69 | # SonarLint plugin
70 | .idea/sonarlint/
71 |
72 | # Crashlytics plugin (for Android Studio and IntelliJ)
73 | com_crashlytics_export_strings.xml
74 | crashlytics.properties
75 | crashlytics-build.properties
76 | fabric.properties
77 |
78 | # Editor-based Rest Client
79 | .idea/httpRequests
80 |
81 | # Android studio 3.1+ serialized cache file
82 | .idea/caches/build_file_checksums.ser
83 |
84 | ### Intellij+all Patch ###
85 | # Ignore everything but code style settings and run configurations
86 | # that are supposed to be shared within teams.
87 |
88 | .idea/*
89 |
90 | !.idea/codeStyles
91 | !.idea/runConfigurations
92 |
93 | ### Java ###
94 | # Compiled class file
95 | *.class
96 |
97 | # Log file
98 | *.log
99 |
100 | # BlueJ files
101 | *.ctxt
102 |
103 | # Mobile Tools for Java (J2ME)
104 | .mtj.tmp/
105 |
106 | # Package Files #
107 | *.jar
108 | *.war
109 | *.nar
110 | *.ear
111 | *.zip
112 | *.tar.gz
113 | *.rar
114 |
115 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
116 | hs_err_pid*
117 | replay_pid*
118 |
119 | ### Maven ###
120 | target/
121 | pom.xml.tag
122 | pom.xml.releaseBackup
123 | pom.xml.versionsBackup
124 | pom.xml.next
125 | release.properties
126 | dependency-reduced-pom.xml
127 | buildNumber.properties
128 | .mvn/timing.properties
129 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar
130 | .mvn/wrapper/maven-wrapper.jar
131 |
132 | # Eclipse m2e generated files
133 | # Eclipse Core
134 | .project
135 | # JDT-specific (Eclipse Java Development Tools)
136 | .classpath
137 |
138 | # End of https://www.toptal.com/developers/gitignore/api/maven,java,intellij+all
139 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/SecuenciaPaises.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # Indicamos la versión
2 | # Para iniciar docker-compose up -d
3 | version: '3.7'
4 |
5 | # Mis servicios
6 | # Iniciamos los servicios
7 | services:
8 | # MARIA DB
9 | mariadb:
10 | build: ./mariadb
11 | image: mariadb
12 | container_name: mariadb
13 | ports:
14 | - 3306:3306
15 | expose:
16 | - 3306
17 | volumes:
18 | - mariadb-volume:/var/lib/mysql
19 | networks:
20 | - mariadb-network
21 | # restart: always
22 |
23 | # ADMIN MARIADB
24 | adminer:
25 | image: adminer
26 | container_name: adminer
27 | # restart: always
28 | ports:
29 | - 8080:8080
30 | networks:
31 | - mariadb-network
32 | depends_on:
33 | - mariadb
34 |
35 | # Mi volumenes de datos compartidos
36 | volumes:
37 | mariadb-volume:
38 |
39 | # Si queremos que tengan una red propia a otros contenedores
40 | networks:
41 | mariadb-network:
42 | driver: bridge
43 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/docker/mariadb/Dockerfile:
--------------------------------------------------------------------------------
1 | # MariaDB
2 | FROM yobasystems/alpine-mariadb:10
3 | # FROM mariadb:10.5
4 |
5 | # Configuramos BBDD
6 | ENV MYSQL_ROOT_PASSWORD 123
7 | ENV MYSQL_USER dam
8 | ENV MYSQL_PASSWORD dam1234
9 | ENV MYSQL_DATABASE dam
10 |
11 | # Copiamos los ficheros sql para que se ejecuten
12 | COPY ./sql /docker-entrypoint-initdb.d/
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | groupId
8 | SecuenciaPaises
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 11
13 | 11
14 |
15 |
16 |
17 |
18 |
19 | com.google.code.gson
20 | gson
21 | 2.9.0
22 |
23 |
24 |
25 | org.projectlombok
26 | lombok
27 | RELEASE
28 | compile
29 |
30 |
31 |
32 | org.mariadb.jdbc
33 | mariadb-java-client
34 | 3.0.3
35 |
36 |
37 |
38 | org.mybatis
39 | mybatis
40 | 3.5.9
41 |
42 |
43 |
44 | org.junit.jupiter
45 | junit-jupiter
46 | RELEASE
47 | test
48 |
49 |
50 |
51 | org.mockito
52 | mockito-core
53 | 4.4.0
54 | test
55 |
56 |
57 | org.mockito
58 | mockito-junit-jupiter
59 | 4.4.0
60 | test
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/Main.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | import es.joseluisgs.dam.controllers.DataBaseManager;
4 | import es.joseluisgs.dam.utils.ApplicationProperties;
5 | import es.joseluisgs.dam.views.PaisView;
6 |
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 | import java.util.Optional;
12 |
13 | /**
14 | * Ejemplo de Patrón MVC para CRUD de países.
15 | * Siguiendo los diagramas de Secuencias en Clase
16 | * Modelo: Pais, gestionador por PaisRepository
17 | * Vista: La propia consola: comunicacion con el usuario
18 | * Controlador: PaisController, controla, cómo y de qué manera el modelo, repositorio y la vista interactúan
19 | * Como vista que soy, soy lo último y gestiono las excepciones con Try/Catch
20 | */
21 | public class Main {
22 | public static void main(String[] args) {
23 | checkServer();
24 | initData();
25 | PaisView view = PaisView.getInstance();
26 | view.menu();
27 |
28 | }
29 |
30 | private static void checkServer() {
31 | System.out.println("Comprobamos la conexión al Servidor BD");
32 | DataBaseManager controller = DataBaseManager.getInstance();
33 | try {
34 | controller.open();
35 | Optional rs = controller.select("SELECT 'Hello world'");
36 | if (rs.isPresent()) {
37 | rs.get().first();
38 | controller.close();
39 | System.out.println("Conexión con la Base de Datos realizada con éxito");
40 | }
41 | } catch (SQLException e) {
42 | System.err.println("Error al conectar al servidor de Base de Datos: " + e.getMessage());
43 | System.exit(1);
44 | }
45 | }
46 |
47 | private static void initData() {
48 | ApplicationProperties properties = new ApplicationProperties();
49 | boolean init = Boolean.parseBoolean(properties.readProperty("database.initdata"));
50 | if (init) {
51 | System.out.println("Iniciamos los datos de ejemplo de la Base de Datos");
52 | DataBaseManager controller = DataBaseManager.getInstance();
53 | String dataPath = "sql" + File.separator + "init-db.sql";
54 | try {
55 | var sqlFile = Main.class.getClassLoader().getResource(dataPath).getPath();
56 | System.out.println(dataPath);
57 | controller.open();
58 | controller.initData(sqlFile, false);
59 | controller.close();
60 | System.out.println("Datos inicializados con éxito");
61 | } catch (SQLException e) {
62 | System.err.println("Error al conectar al servidor de Base de Datos: " + e.getMessage());
63 | System.exit(1);
64 | } catch (FileNotFoundException e) {
65 | System.err.println("Error al leer el fichero de datos iniciales: " + e.getMessage());
66 | System.exit(1);
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/comparators/PaisCodigoComparator.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.comparators;
2 |
3 | import es.joseluisgs.dam.models.Pais;
4 |
5 | import java.util.Comparator;
6 |
7 | /**
8 | * Comparador de países por código.
9 | */
10 | public class PaisCodigoComparator implements Comparator {
11 | @Override
12 | public int compare(Pais p1, Pais p2) {
13 | return p1.getCodigo().compareTo(p2.getCodigo());
14 | }
15 |
16 | @Override
17 | public Comparator reversed() {
18 | return Comparator.super.reversed();
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/comparators/PaisNombreComparator.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.comparators;
2 |
3 | import es.joseluisgs.dam.models.Pais;
4 |
5 | import java.util.Comparator;
6 |
7 | /**
8 | * Comparador de países por nombre.
9 | */
10 | public class PaisNombreComparator implements Comparator {
11 | @Override
12 | public int compare(Pais p1, Pais p2) {
13 | return p1.getNombre().compareTo(p2.getNombre());
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/controllers/AcuerdoController.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.controllers;
2 |
3 | import es.joseluisgs.dam.exceptions.AcuerdoException;
4 | import es.joseluisgs.dam.models.Acuerdo;
5 | import es.joseluisgs.dam.models.LineaAcuerdo;
6 | import es.joseluisgs.dam.models.Pais;
7 | import es.joseluisgs.dam.repositories.acuerdos.IAcuerdoRepository;
8 |
9 | import java.sql.SQLException;
10 | import java.time.LocalDate;
11 | import java.time.LocalDateTime;
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | public class AcuerdoController {
16 | private final IAcuerdoRepository acuerdosRepository;
17 |
18 | public AcuerdoController(IAcuerdoRepository acuerdosRepository) {
19 | this.acuerdosRepository = acuerdosRepository;
20 | }
21 |
22 | /**
23 | * Crea un acuerdo con los datos pasados por parámetro.
24 | *
25 | * @param nombre Nombre del acuerdo.
26 | * @param paises Paises que participan en el acuerdo.
27 | * @return El acuerdo creado.
28 | * @throws SQLException Si hay un error en la base de datos.
29 | */
30 | public Acuerdo createAcuerdo(String nombre, List paises) throws SQLException {
31 | List lineas = new ArrayList<>();
32 | for (Pais pais : paises) {
33 | lineas.add(new LineaAcuerdo(pais, LocalDate.now().getYear()));
34 | }
35 | Acuerdo acuerdo = new Acuerdo(0, nombre, LocalDateTime.now(), lineas);
36 | return acuerdosRepository.save(acuerdo);
37 | }
38 |
39 | /**
40 | * Obtiene un acuerdo por su id.
41 | *
42 | * @param id Id del acuerdo.
43 | * @return El acuerdo.
44 | * @throws AcuerdoException Si no existe el acuerdo.
45 | * @throws SQLException Si hay un error en la base de datos.
46 | */
47 | public Acuerdo getAcuerdoById(int id) throws AcuerdoException, SQLException {
48 | return acuerdosRepository.findById(id).orElseThrow(() -> new AcuerdoException("No existe el acuerdo con id " + id));
49 | }
50 |
51 | /**
52 | * Obtiene todos los acuerdos.
53 | *
54 | * @return Lista de acuerdos.
55 | * @throws SQLException Si hay un error en la base de datos.
56 | */
57 | public List getAllAcuerdos() throws SQLException {
58 | return acuerdosRepository.findAll();
59 | }
60 |
61 | /**
62 | * Elimina un acuerdo por su id.
63 | *
64 | * @param id Id del acuerdo.
65 | * @return El acuerdo eliminado.
66 | * @throws SQLException Si hay un error en la base de datos.
67 | */
68 | public Acuerdo deleteAcuerdo(int id) throws SQLException {
69 | return acuerdosRepository.delete(id);
70 | }
71 |
72 | /**
73 | * Actualiza un acuerdo.
74 | *
75 | * @param id Id del acuerdo.
76 | * @param acuerdo Acuerdo con los nuevos datos.
77 | * @return El acuerdo actualizado.
78 | * @throws SQLException Si hay un error en la base de datos.
79 | */
80 | public Acuerdo updateAcuerdo(int id, Acuerdo acuerdo) throws SQLException {
81 | return acuerdosRepository.update(id, acuerdo);
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/controllers/BackupManager.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.controllers;
2 |
3 | import es.joseluisgs.dam.models.Acuerdo;
4 | import es.joseluisgs.dam.models.Backup;
5 | import es.joseluisgs.dam.models.Pais;
6 | import es.joseluisgs.dam.repositories.acuerdos.IAcuerdoRepository;
7 | import es.joseluisgs.dam.repositories.paises.IPaisRepository;
8 | import es.joseluisgs.dam.services.Storage.IStorageBackup;
9 |
10 | import java.sql.SQLException;
11 |
12 | public class BackupManager {
13 | private final IPaisRepository paisRepository;
14 | private final IAcuerdoRepository acuerdoRepository;
15 | private final IStorageBackup storageBackup;
16 |
17 | public BackupManager(IPaisRepository paisRepository, IAcuerdoRepository acuerdoRepository, IStorageBackup storageBackup) {
18 | this.paisRepository = paisRepository;
19 | this.acuerdoRepository = acuerdoRepository;
20 | this.storageBackup = storageBackup;
21 | }
22 |
23 |
24 | /**
25 | * Importa los datos desde un fichero de backup
26 | */
27 | public void importarDatos() throws SQLException {
28 | System.out.println("Importando datos de Backup: " + storageBackup.getStoragePath());
29 | var backup = storageBackup.load();
30 | System.out.println("Importando Paises...");
31 | if (backup.getPaises().size() > 0) {
32 | paisRepository.clearAll();
33 | for (Pais pais : backup.getPaises()) {
34 | paisRepository.save(pais);
35 | }
36 | System.out.println("Paises importados con éxito al repositorio: " + backup.getPaises().size() + " paises");
37 | } else {
38 | System.out.println("Ha existido un problema al importar los datos de Paises");
39 | }
40 | System.out.println("Importando Acuerdos...");
41 | if (backup.getAcuerdos().size() > 0) {
42 | acuerdoRepository.clearAll();
43 | for (Acuerdo acuerdo : backup.getAcuerdos()) {
44 | acuerdoRepository.save(acuerdo);
45 | }
46 | System.out.println("Acuerdos importados con éxito al repositorio: " + backup.getAcuerdos().size() + " acuerdos");
47 | } else {
48 | System.out.println("Ha existido un problema al importar los datos de Acuerdos");
49 | }
50 | }
51 |
52 |
53 | /**
54 | * Exporta los datos desde un fichero de Backup
55 | */
56 | public void exportarDatos() throws SQLException {
57 | System.out.println("Exportando datos a fichero de Backup...");
58 | var paises = paisRepository.findAll();
59 | var acuerdos = acuerdoRepository.findAll();
60 | Backup backup = Backup.builder()
61 | .paises(paises)
62 | .acuerdos(acuerdos)
63 | .build();
64 | var res = storageBackup.save(backup);
65 | if (res) {
66 | System.out.println("Exportando " + backup.getPaises().size() + " paises");
67 | System.out.println("Exportando " + backup.getAcuerdos().size() + " acuerdos");
68 | System.out.println("Datos exportados con éxito en: " + storageBackup.getStoragePath());
69 | } else {
70 | System.out.println("Ha existido un problema al exportar los datos");
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/exceptions/AcuerdoException.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.exceptions;
2 |
3 | /**
4 | * Excepción asociada al comprotamiento de gestion de Acuerdos.
5 | */
6 | public class AcuerdoException extends Exception {
7 |
8 | public AcuerdoException(String mensaje) {
9 | super(mensaje);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/exceptions/PaisException.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.exceptions;
2 |
3 | /**
4 | * Excepción asociada al comprotamiento de gestion de paises.
5 | */
6 | public class PaisException extends Exception {
7 |
8 | public PaisException(String mensaje) {
9 | super(mensaje);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/models/Acuerdo.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import es.joseluisgs.dam.utils.Formatter;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 | import java.util.List;
8 |
9 | @Data
10 | public class Acuerdo {
11 | private final LocalDateTime fecha;
12 | private String nombre;
13 | private double aportacion;
14 | private List lineas;
15 | private int id;
16 |
17 |
18 | public Acuerdo(int id, String nombre, LocalDateTime fecha, List lineas) {
19 | this.id = id;
20 | this.nombre = nombre;
21 | this.fecha = fecha;
22 | this.lineas = lineas;
23 | this.aportacion = calcularAportacion();
24 | }
25 |
26 | public Acuerdo(int id, String nombre, LocalDateTime fecha, double aportacion, List lineas) {
27 | this.id = id;
28 | this.nombre = nombre;
29 | this.fecha = fecha;
30 | this.lineas = lineas;
31 | this.aportacion = aportacion;
32 | }
33 |
34 | private double calcularAportacion() {
35 | double total = 0;
36 | for (LineaAcuerdo linea : lineas) {
37 | total += linea.getSubvencion();
38 | }
39 | return total;
40 | }
41 |
42 | public Integer getId() {
43 | return id;
44 | }
45 |
46 | @Override
47 | public String toString() {
48 | // Puedes imprimir listas como Arrays.toString(lista))
49 | return "Acuerdo{" + "id=" + id + ", nombre=" + nombre + ", fecha="
50 | + Formatter.dateParser(fecha) + ", lineas=" + lineas + ", aportacion=" + Formatter.moneyParser(aportacion) + '}';
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/models/Backup.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import lombok.Builder;
4 |
5 | import java.time.LocalDateTime;
6 | import java.util.List;
7 |
8 | @Builder
9 | public class Backup {
10 | private final String createdAt = LocalDateTime.now().toString();
11 | private List paises;
12 | private List acuerdos;
13 |
14 | public List getPaises() {
15 | return paises;
16 | }
17 |
18 | public List getAcuerdos() {
19 | return acuerdos;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/models/LineaAcuerdo.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import es.joseluisgs.dam.utils.Formatter;
4 | import lombok.Data;
5 |
6 | @Data
7 | public class LineaAcuerdo {
8 | private final Pais pais;
9 | private final int año;
10 | private final double subvencion;
11 |
12 | public LineaAcuerdo(Pais pais, int año) {
13 | this.pais = pais;
14 | this.año = año;
15 | this.subvencion = pais.getPresupuesto() * 0.25;
16 | }
17 |
18 | public LineaAcuerdo(Pais pais, int año, double subvencion) {
19 | this.pais = pais;
20 | this.año = año;
21 | this.subvencion = subvencion;
22 | }
23 |
24 | @Override
25 | public String toString() {
26 | return "LineaAcuerdo{" + "pais=" + pais.getNombre() + ", año=" + año + ", subvencion=" + Formatter.moneyParser(subvencion) + '}';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/repositories/CRUDRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories;
2 |
3 | import java.sql.SQLException;
4 | import java.util.List;
5 | import java.util.Optional;
6 |
7 | public interface CRUDRepository {
8 | /**
9 | * Devuelve una lista de todos los elementos del repositorio
10 | *
11 | * @return Lista de elementos
12 | * @throws SQLException Si hay algún error en la base de datos
13 | */
14 | List findAll() throws SQLException;
15 |
16 | /**
17 | * Devuelve un Optional del elemento dada una id
18 | *
19 | * @param id Id del elemento
20 | * @return Optional del elemento
21 | * @throws SQLException Si hay algún error en la base de datos
22 | */
23 | Optional findById(ID id) throws SQLException;
24 |
25 | /**
26 | * Inserta un elemento en el repositorio
27 | *
28 | * @param entity Elemento a insertar
29 | * @return Elemento insertado
30 | * @throws SQLException Si hay algún error en la base de datos
31 | */
32 | T save(T entity) throws SQLException;
33 |
34 | /**
35 | * Actualiza un elemento en el repositorio
36 | *
37 | * @param id Id del elemento a actualizar
38 | * @param entity Elemento a actualizar
39 | * @return Elemento actualizado
40 | * @throws SQLException Si hay algún error en la base de datos
41 | */
42 | T update(ID id, T entity) throws SQLException;
43 |
44 | /**
45 | * Elimina un elemento del repositorio
46 | *
47 | * @param id Id del elemento a eliminar
48 | * @return Elemento eliminado
49 | * @throws SQLException Si hay algún error en la base de datos
50 | */
51 | T delete(ID id) throws SQLException;
52 | }
53 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/repositories/acuerdos/IAcuerdoRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories.acuerdos;
2 |
3 | import es.joseluisgs.dam.models.Acuerdo;
4 | import es.joseluisgs.dam.repositories.CRUDRepository;
5 |
6 | import java.sql.SQLException;
7 |
8 | public interface IAcuerdoRepository extends CRUDRepository {
9 |
10 | void clearAll() throws SQLException;
11 | }
12 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/repositories/paises/IPaisRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories.paises;
2 |
3 | import es.joseluisgs.dam.models.Pais;
4 | import es.joseluisgs.dam.repositories.CRUDRepository;
5 |
6 | import java.sql.SQLException;
7 | import java.util.Optional;
8 |
9 | // Toda nueva funcionalidad se extiende de la interfaz SOLID
10 | public interface IPaisRepository extends CRUDRepository {
11 |
12 | Optional findByNombre(String nombre) throws SQLException;
13 |
14 | void clearAll() throws SQLException;
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/services/Storage/IStorage.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services.Storage;
2 |
3 | public interface IStorage {
4 |
5 | /**
6 | * Salva los elementos almacenados en item.
7 | *
8 | * @param item Elementos a almacenar.
9 | * @return true si se ha almacenado correctamente, false en caso contrario.
10 | */
11 | boolean save(T item);
12 |
13 | /**
14 | * Le el almacenado y lo devuelve en un item T.
15 | *
16 | * @return Elementos almacenados.
17 | */
18 | T load();
19 |
20 | /**
21 | * Devuelve el path de la ubicación del almacenado.
22 | *
23 | * @return Path de la ubicación del almacenado.
24 | */
25 | String getStoragePath();
26 | }
27 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/services/Storage/IStorageBackup.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services.Storage;
2 |
3 | import es.joseluisgs.dam.models.Backup;
4 |
5 | public interface IStorageBackup extends IStorage {
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/services/Storage/StorageBackupJsonFile.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services.Storage;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.GsonBuilder;
5 | import com.google.gson.reflect.TypeToken;
6 | import es.joseluisgs.dam.models.Backup;
7 |
8 | import java.io.*;
9 | import java.nio.file.Files;
10 | import java.nio.file.Path;
11 | import java.nio.file.Paths;
12 |
13 | public class StorageBackupJsonFile implements IStorageBackup {
14 | private static StorageBackupJsonFile instance;
15 |
16 | private final Path currentRelativePath = Paths.get("");
17 | private final String ruta = currentRelativePath.toAbsolutePath().toString();
18 | private final String dir = ruta + File.separator + "data";
19 | private final String backupFile = dir + File.separator + "backup.json";
20 |
21 |
22 | private StorageBackupJsonFile() {
23 | init();
24 | }
25 |
26 | public static StorageBackupJsonFile getInstance() {
27 | if (instance == null) {
28 | instance = new StorageBackupJsonFile();
29 | }
30 | return instance;
31 | }
32 |
33 | private void init() {
34 | Path path = Paths.get(dir);
35 | if (!Files.exists(path)) {
36 | try {
37 | Files.createDirectories(path);
38 | } catch (IOException e) {
39 | System.out.println("Error: " + e.getMessage());
40 | }
41 | }
42 | }
43 |
44 | @Override
45 | public boolean save(Backup backup) {
46 | Gson gson = new GsonBuilder().setPrettyPrinting().create();
47 | boolean result = false;
48 | PrintWriter f = null;
49 | try {
50 | f = new PrintWriter(new FileWriter(backupFile));
51 | f.println(gson.toJson(backup));
52 | result = true;
53 |
54 | } catch (Exception e) {
55 | System.out.println("Error: " + e.getMessage());
56 | result = false;
57 | } finally {
58 | if (f != null) {
59 | f.close();
60 | }
61 | }
62 | return result;
63 | }
64 |
65 | @Override
66 | public Backup load() {
67 | Gson gson = new GsonBuilder().setPrettyPrinting().create();
68 | Backup backup = null;
69 | Reader reader = null;
70 | try {
71 | reader = Files.newBufferedReader(Paths.get(backupFile));
72 | backup = gson.fromJson(reader, new TypeToken() {
73 | }.getType());
74 | } catch (Exception e) {
75 | System.out.println("Error: " + e.getMessage());
76 | } finally {
77 | if (reader != null) {
78 | try {
79 | reader.close();
80 | } catch (IOException e) {
81 | System.out.println("Error: " + e.getMessage());
82 | }
83 | }
84 | }
85 | return backup;
86 | }
87 |
88 | @Override
89 | public String getStoragePath() {
90 | return backupFile;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/utils/ApplicationProperties.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import java.io.IOException;
4 | import java.util.Properties;
5 | import java.util.logging.Level;
6 | import java.util.logging.Logger;
7 |
8 | public class ApplicationProperties {
9 | private final Properties properties;
10 |
11 | public ApplicationProperties() {
12 | properties = new Properties();
13 | try {
14 | // De esta manera leemos desde el fichero de propiedades en resources
15 | properties.load(getClass().getClassLoader().getResourceAsStream("application.properties"));
16 |
17 | } catch (IOException ex) {
18 | System.err.println("IOException Ocurrido al leer el fichero de propiedades: " + ex.getMessage());
19 | Logger.getLogger(getClass().getName()).log(Level.ALL, "IOException Ocurrido al leer el fichero de propiedades: " + ex.getMessage());
20 | }
21 | }
22 |
23 | public String readProperty(String keyName) {
24 | // Logger.getLogger(getClass().getName()).log(Level.INFO, "Leyendo propiedad " + keyName);
25 | return properties.getProperty(keyName, "No existe esa clave en el fichero de propiedades");
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/utils/Console.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * Clase que permite leer datos desde la consola.
7 | */
8 | public class Console {
9 | public static String getString(String message) {
10 | System.out.println(message);
11 | return new Scanner(System.in).nextLine().trim();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/java/es/joseluisgs/dam/utils/Formatter.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import java.text.NumberFormat;
4 | import java.time.LocalDateTime;
5 | import java.time.format.DateTimeFormatter;
6 | import java.time.format.FormatStyle;
7 | import java.util.Locale;
8 |
9 | public class Formatter {
10 |
11 | public static String dateParser(LocalDateTime date) {
12 | final Locale locale = new Locale("es", "ES");
13 | // private String pattern = "dd/MM/yyyy";
14 | return date.format(DateTimeFormatter
15 | .ofLocalizedDate(FormatStyle.MEDIUM).withLocale(locale));
16 | }
17 |
18 | public static String moneyParser(Double money) {
19 | final Locale locale = new Locale("es", "ES");
20 | return NumberFormat.getCurrencyInstance(locale).format(money);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joseluisgs/Programacion-09-2021-2022/188c0476c2f30e7149340dda33239a3df1488e4b/Soluciones/04-MVC-Paises-BBDD-DI/src/main/resources/application.properties
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/main/resources/sql/init-db.sql:
--------------------------------------------------------------------------------
1 | -- Adminer 4.8.1 MySQL 5.5.5-10.6.4-MariaDB dump
2 |
3 | SET NAMES utf8;
4 | SET
5 | time_zone = '+00:00';
6 | SET
7 | foreign_key_checks = 0;
8 | SET
9 | sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
10 |
11 | DROP
12 | DATABASE IF EXISTS `dam`;
13 | CREATE
14 | DATABASE `dam` /*!40100 DEFAULT CHARACTER SET utf8mb3 */;
15 | USE
16 | `dam`;
17 |
18 | DROP TABLE IF EXISTS `acuerdo`;
19 | CREATE TABLE `acuerdo`
20 | (
21 | `id` int(11) NOT NULL AUTO_INCREMENT,
22 | `nombre` varchar(100) NOT NULL,
23 | `fecha` datetime NOT NULL,
24 | `aportacion` double NOT NULL,
25 | PRIMARY KEY (`id`)
26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
27 |
28 | INSERT INTO `acuerdo` (`id`, `nombre`, `fecha`, `aportacion`)
29 | VALUES (1, 'Acuerdo Diplomático', '2022-03-25 20:59:57', 12345.89),
30 | (2, 'Acuerdo de Fronteras', '2022-03-25 21:01:40', 999.99);
31 |
32 | DROP TABLE IF EXISTS `linea_acuerdo`;
33 | CREATE TABLE `linea_acuerdo`
34 | (
35 | `id_acuerdo` int(11) NOT NULL,
36 | `id_pais` int(11) NOT NULL,
37 | `año` int(11) NOT NULL,
38 | `subvencion` double NOT NULL,
39 | KEY `id_acuerdo` (`id_acuerdo`),
40 | KEY `id_pais` (`id_pais`),
41 | CONSTRAINT `linea_acuerdo_ibfk_1` FOREIGN KEY (`id_acuerdo`) REFERENCES `acuerdo` (`id`) ON DELETE CASCADE
42 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
43 |
44 | INSERT INTO `linea_acuerdo` (`id_acuerdo`, `id_pais`, `año`, `subvencion`)
45 | VALUES (1, 1, 2022, 1234.56),
46 | (1, 2, 2022, 345.32),
47 | (2, 4, 2022, 450.8),
48 | (2, 7, 2022, 6666.66),
49 | (2, 2, 2022, 333.33);
50 |
51 | DROP TABLE IF EXISTS `pais`;
52 | CREATE TABLE `pais`
53 | (
54 | `id` int(11) NOT NULL AUTO_INCREMENT,
55 | `nombre` varchar(100) NOT NULL,
56 | `codigo` varchar(5) NOT NULL,
57 | `idioma` varchar(100) NOT NULL,
58 | `moneda` varchar(50) NOT NULL,
59 | `capital` varchar(100) NOT NULL,
60 | `presupuesto` double DEFAULT NULL,
61 | PRIMARY KEY (`id`)
62 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
63 |
64 | INSERT INTO `pais` (`id`, `nombre`, `codigo`, `idioma`, `moneda`, `capital`, `presupuesto`)
65 | VALUES (1, 'España', 'ES', 'Español', 'Euro', 'Madrid', 1234567.23),
66 | (2, 'Francia', 'FR', 'Francés', 'Euro', 'París', 123456.67),
67 | (3, 'Italia', 'IT', 'Italiano', 'Euro', 'Roma', 564568.34),
68 | (4, 'Alemania', 'DE', 'Alemán', 'Euro', 'Berlín', 234567.23),
69 | (5, 'Reino Unido', 'UK', 'Inglés', 'Libra', 'Londres', 232323.34),
70 | (6, 'Japón', 'JP', 'Jsaponés', 'Yen', 'Tokio', 21212.12),
71 | (7, 'China', 'CN', 'Chino', 'Yuan', 'Pekín', 121212.34),
72 | (8, 'Australia', 'AU', 'Inglés', 'Dólar', 'Canberra', 567654.23),
73 | (9, 'Argentina', 'AR', 'Español', 'Peso', 'Buenos Aires', 123456.34),
74 | (10, 'Brasil', 'BR', 'Portugués', 'Real', 'Brasilia', 251251.62),
75 | (11, 'Estados Unidos', 'US', 'Inglés', 'Dólar', 'Washington', 1212415.98);
76 |
77 | -- 2022-03-26 11:15:34
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/test/java/es/joseluisgs/dam/MainTest.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertTrue;
6 |
7 | class MainTest {
8 |
9 | @Test
10 | public void trueIsTrue() {
11 | assertTrue(true);
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/test/java/es/joseluisgs/dam/utilities/DataBase.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utilities;
2 |
3 | import es.joseluisgs.dam.Main;
4 | import es.joseluisgs.dam.controllers.DataBaseManager;
5 | import es.joseluisgs.dam.utils.ApplicationProperties;
6 |
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 | import java.sql.SQLException;
10 |
11 | public class DataBase {
12 |
13 | /**
14 | * Inicia la base de datos con los datos de prueba si los hay, o la estructura de la tabla...
15 | */
16 | public static void init() {
17 | ApplicationProperties properties = new ApplicationProperties();
18 | boolean init = Boolean.parseBoolean(properties.readProperty("database.initdata"));
19 | if (init) {
20 | DataBaseManager controller = DataBaseManager.getInstance();
21 | String dataPath = "sql" + File.separator + "init-db.sql";
22 | try {
23 | var sqlFile = Main.class.getClassLoader().getResource(dataPath).getPath();
24 | controller.open();
25 | controller.initData(sqlFile, false);
26 | controller.close();
27 | } catch (SQLException e) {
28 | System.err.println("Error al conectar al servidor de Base de Datos: " + e.getMessage());
29 | System.exit(1);
30 | } catch (FileNotFoundException e) {
31 | System.err.println("Error al leer el fichero de datos iniciales: " + e.getMessage());
32 | System.exit(1);
33 | }
34 | }
35 | }
36 |
37 | /**
38 | * Borra todas las tablas, que cuesta menos que tirar toda la base de datos y levantarla de nuevo
39 | *
40 | * @throws SQLException
41 | */
42 | public static void deleteAll() throws SQLException {
43 | DataBaseManager db = DataBaseManager.getInstance();
44 | String query = "DELETE FROM pais";
45 | db.open();
46 | db.delete(query);
47 | query = "DELETE FROM acuerdo";
48 | db.beginTransaction();
49 | db.delete(query);
50 | query = "DELETE FROM linea_acuerdo";
51 | db.delete(query);
52 | db.commit();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/test/java/es/joseluisgs/dam/utilities/DataDB.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utilities;
2 |
3 | import es.joseluisgs.dam.controllers.DataBaseManager;
4 | import es.joseluisgs.dam.models.Acuerdo;
5 | import es.joseluisgs.dam.models.LineaAcuerdo;
6 | import es.joseluisgs.dam.models.Pais;
7 |
8 | import java.sql.ResultSet;
9 | import java.sql.SQLException;
10 | import java.util.Optional;
11 |
12 | public class DataDB {
13 | // Insertamos un dato de prueba, aquí vemos un acoplamiento...
14 | // Si no quiseramos esto, podríamos usar Order de test
15 | // Lo ideal es meterlo en el script, e iniciarlo cada vez...
16 | public static void insertPaisTest(Pais paisTest) throws SQLException {
17 | String query = "INSERT INTO pais VALUES (null, ?, ?, ?, ?, ?, ?)";
18 | DataBaseManager db = DataBaseManager.getInstance();
19 | db.open();
20 | Optional res = db.insert(query, paisTest.getNombre(), paisTest.getCodigo(), paisTest.getIdioma(), paisTest.getMoneda(),
21 | paisTest.getCapital(), paisTest.getPresupuesto());
22 | if (res.get().first()) {
23 | paisTest.setId(res.get().getInt(1));
24 | }
25 | db.close();
26 | }
27 |
28 | public static void insertAcuerdoTest(Acuerdo acuerdoTest) throws SQLException {
29 | // OJO pongo null en el primer parámetro porque no inserto el ID, este se genera automático. Mira el DBMAnager
30 | String query = "INSERT INTO acuerdo VALUES (null, ?, ?, ?)";
31 | DataBaseManager db = DataBaseManager.getInstance();
32 | // Es una transacción, por lo que si falla alguna de las dos, se cancela todo
33 | db.open();
34 | db.beginTransaction();
35 | ResultSet res = db.insert(query, acuerdoTest.getNombre(), acuerdoTest.getFecha(), acuerdoTest.getAportacion())
36 | .orElseThrow(() -> new SQLException("Error al insertar acuerdo"));
37 |
38 | // Para obtener su ID que ha generado la BD
39 | if (res.first()) {
40 | acuerdoTest.setId(res.getInt(1));
41 | // Ahora salvamos toda las lineas de acuerdo...
42 | for (LineaAcuerdo linea : acuerdoTest.getLineas()) {
43 | query = "INSERT INTO linea_acuerdo VALUES (?, ?, ?, ?)";
44 | db.insert(query, acuerdoTest.getId(), linea.getPais().getId(), linea.getAño(), linea.getSubvencion())
45 | .orElseThrow(() -> new SQLException("Error al insertar linea de acuerdo"));
46 | }
47 |
48 | // Y finalmente cerramos la conexión y devolvemos el acuerdo
49 | db.commit();
50 | db.close();
51 | }
52 | db.rollback();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/test/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joseluisgs/Programacion-09-2021-2022/188c0476c2f30e7149340dda33239a3df1488e4b/Soluciones/04-MVC-Paises-BBDD-DI/src/test/resources/application.properties
--------------------------------------------------------------------------------
/Soluciones/04-MVC-Paises-BBDD-DI/src/test/resources/sql/init-db.sql:
--------------------------------------------------------------------------------
1 | -- Adminer 4.8.1 MySQL 5.5.5-10.6.4-MariaDB dump
2 |
3 | SET NAMES utf8;
4 | SET
5 | time_zone = '+00:00';
6 | SET
7 | foreign_key_checks = 0;
8 | SET
9 | sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
10 |
11 | DROP
12 | DATABASE IF EXISTS `dam`;
13 | CREATE
14 | DATABASE `dam` /*!40100 DEFAULT CHARACTER SET utf8mb3 */;
15 | USE
16 | `dam`;
17 |
18 | DROP TABLE IF EXISTS `acuerdo`;
19 | CREATE TABLE `acuerdo`
20 | (
21 | `id` int(11) NOT NULL AUTO_INCREMENT,
22 | `nombre` varchar(100) NOT NULL,
23 | `fecha` datetime NOT NULL,
24 | `aportacion` double NOT NULL,
25 | PRIMARY KEY (`id`)
26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
27 |
28 |
29 | DROP TABLE IF EXISTS `linea_acuerdo`;
30 | CREATE TABLE `linea_acuerdo`
31 | (
32 | `id_acuerdo` int(11) NOT NULL,
33 | `id_pais` int(11) NOT NULL,
34 | `año` int(11) NOT NULL,
35 | `subvencion` double NOT NULL,
36 | KEY `id_acuerdo` (`id_acuerdo`),
37 | KEY `id_pais` (`id_pais`),
38 | CONSTRAINT `linea_acuerdo_ibfk_1` FOREIGN KEY (`id_acuerdo`) REFERENCES `acuerdo` (`id`) ON DELETE CASCADE
39 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
40 |
41 | DROP TABLE IF EXISTS `pais`;
42 | CREATE TABLE `pais`
43 | (
44 | `id` int(11) NOT NULL AUTO_INCREMENT,
45 | `nombre` varchar(100) NOT NULL,
46 | `codigo` varchar(5) NOT NULL,
47 | `idioma` varchar(100) NOT NULL,
48 | `moneda` varchar(50) NOT NULL,
49 | `capital` varchar(100) NOT NULL,
50 | `presupuesto` double DEFAULT NULL,
51 | PRIMARY KEY (`id`)
52 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
53 |
54 | -- 2022-03-26 11:15:34
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/.idea/description.html:
--------------------------------------------------------------------------------
1 | Simple Java application that includes a class with main()
method
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/.idea/project-template.xml:
--------------------------------------------------------------------------------
1 |
2 | IJ_BASE_PACKAGE
3 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/JavaLambdaFuncional.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/src/es/joseluisgs/dam/CalcImperativeA.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public class CalcImperativeA implements ICalcImperativeA {
4 |
5 | @Override
6 | public int suma(int a, int b) {
7 | return a + b;
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/src/es/joseluisgs/dam/CalcImperativeB.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public class CalcImperativeB implements ICalcImperativeB {
4 |
5 | @Override
6 | public void suma(int a, int b) {
7 | System.out.println("Suma: " + (a + b));
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/src/es/joseluisgs/dam/CalcImperativeC.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public class CalcImperativeC implements ICalcImperativeC {
4 | @Override
5 | public void suma(int a, int b) {
6 | System.out.println("Suma:");
7 | System.out.println("\tResultado: " + (a + b));
8 | }
9 |
10 | @Override
11 | public void resta(int a, int b) {
12 | System.out.println("Resta:");
13 | System.out.println("\tResultado: " + (a - b));
14 | }
15 |
16 | @Override
17 | public void multiplicacion(int a, int b) {
18 | System.out.println("Multiplicacion:");
19 | System.out.println("\tResultado: " + (a * b));
20 | }
21 |
22 | @Override
23 | public void division(int a, int b) {
24 | System.out.println("Division:");
25 | if (b != 0) {
26 | System.out.println("\tResultado: " + (a / b));
27 | } else {
28 | System.err.println("\tError!");
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/src/es/joseluisgs/dam/ICalcFunctional.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public interface ICalcFunctional {
4 | default int suma(int a, int b) {
5 | return a + b;
6 | }
7 |
8 | int multiplicacion(int a, int b);
9 |
10 | default int resta(int a, int b) {
11 | return a - b;
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/src/es/joseluisgs/dam/ICalcImperativeA.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public interface ICalcImperativeA {
4 | int suma(int a, int b);
5 | }
6 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/src/es/joseluisgs/dam/ICalcImperativeB.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public interface ICalcImperativeB {
4 | void suma(int a, int b);
5 | }
6 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/src/es/joseluisgs/dam/ICalcImperativeC.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public interface ICalcImperativeC {
4 | void suma(int a, int b);
5 | void resta(int a, int b);
6 | void multiplicacion(int a, int b);
7 | void division(int a, int b);
8 | }
9 |
--------------------------------------------------------------------------------
/Soluciones/05-JavaLambdaFuncional/src/es/joseluisgs/dam/Main.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public class Main {
4 |
5 | public static void main(String[] args) {
6 | // Podemos usar funciones definidas...
7 | hola();
8 |
9 | // podemos usar funciones anonimas o lambda, según las necesitemos
10 | Runnable r = () -> System.out.println("Hola");
11 | r.run();
12 |
13 | // Es anonima, no tiene nombre, solo la implementación.
14 | // De esta manera no hace falta declararla si solo la vamos a usar una vez
15 |
16 | // Pueden aceptar parámetros
17 | // Runnable r2 = (String s) -> System.out.println(s);
18 |
19 | /**
20 | * Concepto de caja negra (entrada salida sin muchas preocupaciones).
21 | * El código se vuelve más declarativo (programación declarativa)
22 | * y menos no imperativo (programación imperativa).
23 | * El código se vuelve más compacto, más simple, más fácil de leer y también más elegante.
24 | * Aportan una sintaxis básica.
25 | * Singularidad (SOLID o Responsabilidad única).
26 | *
27 | * (Lista de argumentos) -> { Cuerpo de la expresión lambda }
28 | * Si solo tiene un argumento, puede escribirse sin paréntesis
29 | * Si solo tiene una instruccion, puede escribirse sin llaves
30 | * a -> System.out.println(a)
31 | * () -> System.out.println("Hola")
32 | * () -> { System.out.println("Hola") }
33 | */
34 |
35 | // Y si tenemos disitntas implementaciones de una misma interfaz??
36 | CalcImperativeA calcA = new CalcImperativeA();
37 | System.out.println("Suma: " + calcA.suma(1, 2));
38 | CalcImperativeB calcB = new CalcImperativeB();
39 | calcB.suma(1, 2);
40 |
41 | // Hecho con Lambda, no necesitamos la implementación, se la indicamos sobre
42 | // La marcha
43 | ICalcImperativeA calcLambdaA = (a, b) -> a + b;
44 | System.out.println("Suma: " + calcLambdaA.suma(1, 2));
45 | ICalcImperativeB calcLambdaB = (a, b) -> {
46 | System.out.println("Suma: " + a + b);
47 | };
48 | calcLambdaB.suma(1, 2);
49 | ICalcImperativeA calcLambdaA2 = (a, b) -> 2 * a + 5 + b;
50 | System.out.println("Suma: " + calcLambdaA2.suma(1, 2));
51 |
52 | /**
53 | * Si utilizamos interfaces, las lambdas están desarrolladas para solamente
54 | * trabajar con un único método en su interior.
55 | * Si tenemos varios métodos, los requisitos a cumplir son:
56 | * Todos los métodos deben de tener la misma cantidad de parámetros.
57 | * Se deben declarar métodos a utilizar como default o static.
58 | * El resto de métodos quedaran inutilizados.
59 | * En definitiva: una función lambda es como una con un único método público.
60 | * El cual implementas su comportamiento sobre la marcha.
61 | */
62 |
63 | CalcImperativeC calcC = new CalcImperativeC();
64 | calcC.suma(1, 3);
65 | calcC.resta(1, 3);
66 | calcC.division(1, 3);
67 | calcC.multiplicacion(1, 3);
68 |
69 | ICalcFunctional calcLambdaC = (a, b) -> a * b; // Este es la multiplicación
70 | System.out.println("Total suma: " + calcLambdaC.suma(2, 3));
71 | System.out.println("Total resta: " + calcLambdaC.resta(2, 3));
72 | System.out.println("Total multiplicacion: " + calcLambdaC.multiplicacion(2, 3));
73 |
74 | ICalcFunctional calcLambdaC2 = (a, b) -> 2 * a * 2 * b;
75 | System.out.println("Total multiplicacion: " + calcLambdaC2.multiplicacion(2, 3));
76 | }
77 |
78 |
79 | private static void hola() {
80 | System.out.println("Hola");
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/Soluciones/06-JavaStreamAPI/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/Soluciones/06-JavaStreamAPI/.idea/description.html:
--------------------------------------------------------------------------------
1 | Simple Java application that includes a class with main()
method
--------------------------------------------------------------------------------
/Soluciones/06-JavaStreamAPI/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/06-JavaStreamAPI/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Soluciones/06-JavaStreamAPI/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Soluciones/06-JavaStreamAPI/.idea/project-template.xml:
--------------------------------------------------------------------------------
1 |
2 | IJ_BASE_PACKAGE
3 |
--------------------------------------------------------------------------------
/Soluciones/06-JavaStreamAPI/JavaStreamAPI.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Soluciones/06-JavaStreamAPI/src/es/joseluisgs/dam/Persona.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public class Persona {
4 | private String nombre;
5 | private int edad;
6 |
7 | public Persona(String nombre, int edad) {
8 | this.nombre = nombre;
9 | this.edad = edad;
10 | }
11 |
12 | public String getNombre() {
13 | return nombre;
14 | }
15 |
16 | public void setNombre(String nombre) {
17 | this.nombre = nombre;
18 | }
19 |
20 | public int getEdad() {
21 | return edad;
22 | }
23 |
24 | public void setEdad(int edad) {
25 | this.edad = edad;
26 | }
27 |
28 | @Override
29 | public String toString() {
30 | return "Persona{" +
31 | "nombre='" + nombre + '\'' +
32 | ", edad=" + edad +
33 | '}';
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/.gitignore:
--------------------------------------------------------------------------------
1 | /out
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Datasource local storage ignored files
5 | /dataSources/
6 | /dataSources.local.xml
7 | # Editor-based HTTP Client requests
8 | /httpRequests/
9 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/.idea/description.html:
--------------------------------------------------------------------------------
1 | Simple Java application that includes a class with main()
method
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/.idea/project-template.xml:
--------------------------------------------------------------------------------
1 |
2 | IJ_BASE_PACKAGE
3 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/02-Stream.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/src/es/joseluisgs/dam/Main.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public class Main {
4 | public static void main(String[] args) {
5 | // ConsultasAlumnos alumnos = new ConsultasAlumnos();
6 | ConsultasCanciones canciones = new ConsultasCanciones();
7 | // ConsultasProductos productos = new ConsultasProductos();
8 | }
9 |
10 |
11 | }
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/src/es/joseluisgs/dam/model/Alumno.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.model;
2 |
3 | public class Alumno {
4 | private int id;
5 | private String dni;
6 | private String nombre;
7 | private String apellidos;
8 | private String nombreCurso;
9 | private double nota;
10 | private int edad;
11 |
12 | public Alumno() {
13 |
14 | }
15 |
16 | public Alumno(int id, String dni, String nombre, String apellidos, String nombreCurso, double nota, int edad) {
17 | this.id = id;
18 | this.dni = dni;
19 | this.nombre = nombre;
20 | this.apellidos = apellidos;
21 | this.nombreCurso = nombreCurso;
22 | this.nota = nota;
23 | this.edad = edad;
24 | }
25 |
26 | public int getId() {
27 | return id;
28 | }
29 |
30 | public void setId(int id) {
31 | this.id = id;
32 | }
33 |
34 | public String getDni() {
35 | return dni;
36 | }
37 |
38 | public void setDni(String dni) {
39 | this.dni = dni;
40 | }
41 |
42 | public String getNombre() {
43 | return nombre;
44 | }
45 |
46 | public void setNombre(String nombre) {
47 | this.nombre = nombre;
48 | }
49 |
50 | public String getApellidos() {
51 | return apellidos;
52 | }
53 |
54 | public void setApellidos(String apellidos) {
55 | this.apellidos = apellidos;
56 | }
57 |
58 | public String getNombreCurso() {
59 | return nombreCurso;
60 | }
61 |
62 | public void setNombreCurso(String nombreCurso) {
63 | this.nombreCurso = nombreCurso;
64 | }
65 |
66 | public double getNota() {
67 | return nota;
68 | }
69 |
70 | public void setNota(double nota) {
71 | this.nota = nota;
72 | }
73 |
74 | public int getEdad() {
75 | return edad;
76 | }
77 |
78 | public void setEdad(int edad) {
79 | this.edad = edad;
80 | }
81 |
82 | @Override
83 | public String toString() {
84 | return id+" | "+dni+" | "+ nombre +" | "+apellidos+" | Curso: "+nombreCurso+" | Nota: "+nota+" | Edad: "+edad;
85 | }
86 | }
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/src/es/joseluisgs/dam/model/Cancion.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.model;
2 |
3 | public class Cancion {
4 | String titulo;
5 | String cantante;
6 |
7 | public Cancion(String titulo, String cantante) {
8 | this.titulo = titulo;
9 | this.cantante = cantante;
10 | }
11 |
12 | public String getTitulo() {
13 | return titulo;
14 | }
15 |
16 | public void setTitulo(String titulo) {
17 | this.titulo = titulo;
18 | }
19 |
20 | public String getCantante() {
21 | return cantante;
22 | }
23 |
24 | public void setCantante(String cantante) {
25 | this.cantante = cantante;
26 | }
27 |
28 | @Override
29 | public String toString() {
30 | return "Cancion{" +
31 | "titulo='" + titulo + '\'' +
32 | ", cantante='" + cantante + '\'' +
33 | '}';
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/src/es/joseluisgs/dam/model/Product.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.model;
2 |
3 | public class Product implements Comparable {
4 | private int id;
5 | private String name;
6 | private int supplier;
7 | private int category;
8 | private double unitPrice;
9 | private int unitsInStock;
10 |
11 | public int getId() {
12 | return id;
13 | }
14 |
15 | public void setId(int id) {
16 | this.id = id;
17 | }
18 |
19 | public String getName() {
20 | return name;
21 | }
22 |
23 | public void setName(String name) {
24 | this.name = name;
25 | }
26 |
27 | public int getSupplier() {
28 | return supplier;
29 | }
30 |
31 | public void setSupplier(int supplier) {
32 | this.supplier = supplier;
33 | }
34 |
35 | public int getCategory() {
36 | return category;
37 | }
38 |
39 | public void setCategory(int category) {
40 | this.category = category;
41 | }
42 |
43 | public double getUnitPrice() {
44 | return unitPrice;
45 | }
46 |
47 | public void setUnitPrice(double unitPrice) {
48 | this.unitPrice = unitPrice;
49 | }
50 |
51 | public int getUnitsInStock() {
52 | return unitsInStock;
53 | }
54 |
55 | public void setUnitsInStock(int unitsInStock) {
56 | this.unitsInStock = unitsInStock;
57 | }
58 |
59 | @Override
60 | public String toString() {
61 | return "Product{" +
62 | "id=" + id +
63 | ", name='" + name + '\'' +
64 | ", supplier=" + supplier +
65 | ", category=" + category +
66 | ", unitPrice=" + unitPrice +
67 | ", unitsInStock=" + unitsInStock +
68 | '}';
69 | }
70 |
71 |
72 | @Override
73 | public int compareTo(Product p) {
74 | if (this.getUnitsInStock() < p.getUnitsInStock())
75 | return -1;
76 | else if (this.getUnitsInStock() > p.getUnitsInStock())
77 | return 1;
78 | else
79 | return 0;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/Soluciones/07-StreamEjemplos/src/es/joseluisgs/dam/utils/Util.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import es.joseluisgs.dam.model.Product;
4 |
5 | import java.io.File;
6 | import java.io.IOException;
7 | import java.nio.charset.StandardCharsets;
8 | import java.nio.file.Files;
9 | import java.nio.file.Path;
10 | import java.nio.file.Paths;
11 | import java.util.ArrayList;
12 | import java.util.List;
13 | import java.util.StringTokenizer;
14 | import java.util.stream.Collectors;
15 |
16 | public class Util {
17 |
18 | public static List getProducts() throws IOException {
19 | // Cargamos el archivo ubicado en la carpeta data
20 | String DATA_FILE = "products.csv";
21 | String WORKING_DIRECTORY = System.getProperty("user.dir");
22 | Path path = Paths.get(WORKING_DIRECTORY + File.separator + "data" + File.separator + DATA_FILE);
23 | // Puedo leer todo el fichero del tiron. Cuidado si no es muy grande!!
24 | final List lineas = Files.readAllLines(path, StandardCharsets.UTF_8);
25 | // lines.forEach(System.out::println);
26 | // List products = new ArrayList<>();
27 | // Me he saltado la primera línea del archivo, porque es la cabecera
28 | /*for (int i = 1; i < lineas.size(); i++) {
29 | Product product = parseProduct(lineas.get(i));
30 | products.add(product);
31 | }*/
32 | // Mapeando cada línea a un objeto Product
33 | // Usamos Skip para saltarnos la primera línea
34 | return lineas.stream().skip(1).map(Util::parseProduct).collect(Collectors.toList());
35 |
36 | }
37 |
38 | public static List getProducts2() throws IOException {
39 | // Cargamos el archivo ubicado en la carpeta data
40 | String DATA_FILE = "products.csv";
41 | String WORKING_DIRECTORY = System.getProperty("user.dir");
42 | Path path = Paths.get(WORKING_DIRECTORY + File.separator + "data" + File.separator + DATA_FILE);
43 | // Puedo leer todo el fichero liena a linea usando API Stream y Programación Funcional
44 | // Mapeando cada línea a un objeto Product
45 | // Usamos Skip para saltarnos la primera línea
46 | return Files.lines(path, StandardCharsets.UTF_8)
47 | .skip(1).map(Util::parseProduct).collect(Collectors.toList());
48 |
49 | }
50 |
51 | private static Product parseProduct(String linea) {
52 | String[] campos = linea.split(",");
53 | Product product = new Product();
54 | product.setId(Integer.parseInt(campos[0]));
55 | product.setName(campos[1]);
56 | product.setSupplier(Integer.parseInt(campos[2]));
57 | product.setCategory(Integer.parseInt(campos[3]));
58 | product.setUnitPrice(Double.parseDouble(campos[5]));
59 | product.setUnitsInStock(Integer.parseInt(campos[6]));
60 | return product;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/maven,java,intellij+all
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=maven,java,intellij+all
4 |
5 | ### Intellij+all ###
6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
8 |
9 | # User-specific stuff
10 | .idea/**/workspace.xml
11 | .idea/**/tasks.xml
12 | .idea/**/usage.statistics.xml
13 | .idea/**/dictionaries
14 | .idea/**/shelf
15 |
16 | # AWS User-specific
17 | .idea/**/aws.xml
18 |
19 | # Generated files
20 | .idea/**/contentModel.xml
21 |
22 | # Sensitive or high-churn files
23 | .idea/**/dataSources/
24 | .idea/**/dataSources.ids
25 | .idea/**/dataSources.local.xml
26 | .idea/**/sqlDataSources.xml
27 | .idea/**/dynamic.xml
28 | .idea/**/uiDesigner.xml
29 | .idea/**/dbnavigator.xml
30 |
31 | # Gradle
32 | .idea/**/gradle.xml
33 | .idea/**/libraries
34 |
35 | # Gradle and Maven with auto-import
36 | # When using Gradle or Maven with auto-import, you should exclude module files,
37 | # since they will be recreated, and may cause churn. Uncomment if using
38 | # auto-import.
39 | # .idea/artifacts
40 | # .idea/compiler.xml
41 | # .idea/jarRepositories.xml
42 | # .idea/modules.xml
43 | # .idea/*.iml
44 | # .idea/modules
45 | # *.iml
46 | # *.ipr
47 |
48 | # CMake
49 | cmake-build-*/
50 |
51 | # Mongo Explorer plugin
52 | .idea/**/mongoSettings.xml
53 |
54 | # File-based project format
55 | *.iws
56 |
57 | # IntelliJ
58 | out/
59 |
60 | # mpeltonen/sbt-idea plugin
61 | .idea_modules/
62 |
63 | # JIRA plugin
64 | atlassian-ide-plugin.xml
65 |
66 | # Cursive Clojure plugin
67 | .idea/replstate.xml
68 |
69 | # SonarLint plugin
70 | .idea/sonarlint/
71 |
72 | # Crashlytics plugin (for Android Studio and IntelliJ)
73 | com_crashlytics_export_strings.xml
74 | crashlytics.properties
75 | crashlytics-build.properties
76 | fabric.properties
77 |
78 | # Editor-based Rest Client
79 | .idea/httpRequests
80 |
81 | # Android studio 3.1+ serialized cache file
82 | .idea/caches/build_file_checksums.ser
83 |
84 | ### Intellij+all Patch ###
85 | # Ignore everything but code style settings and run configurations
86 | # that are supposed to be shared within teams.
87 |
88 | .idea/*
89 |
90 | !.idea/codeStyles
91 | !.idea/runConfigurations
92 |
93 | ### Java ###
94 | # Compiled class file
95 | *.class
96 |
97 | # Log file
98 | *.log
99 |
100 | # BlueJ files
101 | *.ctxt
102 |
103 | # Mobile Tools for Java (J2ME)
104 | .mtj.tmp/
105 |
106 | # Package Files #
107 | *.jar
108 | *.war
109 | *.nar
110 | *.ear
111 | *.zip
112 | *.tar.gz
113 | *.rar
114 |
115 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
116 | hs_err_pid*
117 | replay_pid*
118 |
119 | ### Maven ###
120 | target/
121 | pom.xml.tag
122 | pom.xml.releaseBackup
123 | pom.xml.versionsBackup
124 | pom.xml.next
125 | release.properties
126 | dependency-reduced-pom.xml
127 | buildNumber.properties
128 | .mvn/timing.properties
129 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar
130 | .mvn/wrapper/maven-wrapper.jar
131 |
132 | # Eclipse m2e generated files
133 | # Eclipse Core
134 | .project
135 | # JDT-specific (Eclipse Java Development Tools)
136 | .classpath
137 |
138 | # End of https://www.toptal.com/developers/gitignore/api/maven,java,intellij+all
139 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/SecuenciaPaises.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # Indicamos la versión
2 | # Para iniciar docker-compose up -d
3 | version: '3.7'
4 |
5 | # Mis servicios
6 | # Iniciamos los servicios
7 | services:
8 | # MARIA DB
9 | mariadb:
10 | build: ./mariadb
11 | image: mariadb
12 | container_name: mariadb
13 | ports:
14 | - 3306:3306
15 | expose:
16 | - 3306
17 | volumes:
18 | - mariadb-volume:/var/lib/mysql
19 | networks:
20 | - mariadb-network
21 | # restart: always
22 |
23 | # ADMIN MARIADB
24 | adminer:
25 | image: adminer
26 | container_name: adminer
27 | # restart: always
28 | ports:
29 | - 8080:8080
30 | networks:
31 | - mariadb-network
32 | depends_on:
33 | - mariadb
34 |
35 | # Mi volumenes de datos compartidos
36 | volumes:
37 | mariadb-volume:
38 |
39 | # Si queremos que tengan una red propia a otros contenedores
40 | networks:
41 | mariadb-network:
42 | driver: bridge
43 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/docker/mariadb/Dockerfile:
--------------------------------------------------------------------------------
1 | # MariaDB
2 | FROM yobasystems/alpine-mariadb:10
3 | # FROM mariadb:10.5
4 |
5 | # Configuramos BBDD
6 | ENV MYSQL_ROOT_PASSWORD 123
7 | ENV MYSQL_USER dam
8 | ENV MYSQL_PASSWORD dam1234
9 | ENV MYSQL_DATABASE dam
10 |
11 | # Copiamos los ficheros sql para que se ejecuten
12 | COPY ./sql /docker-entrypoint-initdb.d/
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | groupId
8 | SecuenciaPaises
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 11
13 | 11
14 |
15 |
16 |
17 |
18 |
19 | com.google.code.gson
20 | gson
21 | 2.9.0
22 |
23 |
24 |
25 | org.projectlombok
26 | lombok
27 | RELEASE
28 | compile
29 |
30 |
31 |
32 | org.mariadb.jdbc
33 | mariadb-java-client
34 | 3.0.3
35 |
36 |
37 |
38 | org.mybatis
39 | mybatis
40 | 3.5.9
41 |
42 |
43 |
44 | org.junit.jupiter
45 | junit-jupiter
46 | RELEASE
47 | test
48 |
49 |
50 |
51 | org.mockito
52 | mockito-core
53 | 4.4.0
54 | test
55 |
56 |
57 | org.mockito
58 | mockito-junit-jupiter
59 | 4.4.0
60 | test
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/Main.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | import es.joseluisgs.dam.controllers.DataBaseManager;
4 | import es.joseluisgs.dam.utils.ApplicationProperties;
5 | import es.joseluisgs.dam.views.PaisView;
6 |
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 | import java.util.Optional;
12 |
13 | /**
14 | * Ejemplo de Patrón MVC para CRUD de países.
15 | * Siguiendo los diagramas de Secuencias en Clase
16 | * Modelo: Pais, gestionador por PaisRepository
17 | * Vista: La propia consola: comunicacion con el usuario
18 | * Controlador: PaisController, controla, cómo y de qué manera el modelo, repositorio y la vista interactúan
19 | * Como vista que soy, soy lo último y gestiono las excepciones con Try/Catch
20 | */
21 | public class Main {
22 | public static void main(String[] args) {
23 | checkServer();
24 | initData();
25 | PaisView view = PaisView.getInstance();
26 | view.menu();
27 |
28 | }
29 |
30 | private static void checkServer() {
31 | System.out.println("Comprobamos la conexión al Servidor BD");
32 | DataBaseManager controller = DataBaseManager.getInstance();
33 | try {
34 | controller.open();
35 | Optional rs = controller.select("SELECT 'Hello world'");
36 | if (rs.isPresent()) {
37 | rs.get().first();
38 | controller.close();
39 | System.out.println("Conexión con la Base de Datos realizada con éxito");
40 | }
41 | } catch (SQLException e) {
42 | System.err.println("Error al conectar al servidor de Base de Datos: " + e.getMessage());
43 | System.exit(1);
44 | }
45 | }
46 |
47 | private static void initData() {
48 | ApplicationProperties properties = new ApplicationProperties();
49 | boolean init = Boolean.parseBoolean(properties.readProperty("database.initdata"));
50 | if (init) {
51 | System.out.println("Iniciamos los datos de ejemplo de la Base de Datos");
52 | DataBaseManager controller = DataBaseManager.getInstance();
53 | String dataPath = "sql" + File.separator + "init-db.sql";
54 | try {
55 | var sqlFile = Main.class.getClassLoader().getResource(dataPath).getPath();
56 | System.out.println(dataPath);
57 | controller.open();
58 | controller.initData(sqlFile, false);
59 | controller.close();
60 | System.out.println("Datos inicializados con éxito");
61 | } catch (SQLException e) {
62 | System.err.println("Error al conectar al servidor de Base de Datos: " + e.getMessage());
63 | System.exit(1);
64 | } catch (FileNotFoundException e) {
65 | System.err.println("Error al leer el fichero de datos iniciales: " + e.getMessage());
66 | System.exit(1);
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/controllers/AcuerdoController.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.controllers;
2 |
3 | import es.joseluisgs.dam.exceptions.AcuerdoException;
4 | import es.joseluisgs.dam.models.Acuerdo;
5 | import es.joseluisgs.dam.models.LineaAcuerdo;
6 | import es.joseluisgs.dam.models.Pais;
7 | import es.joseluisgs.dam.repositories.acuerdos.IAcuerdoRepository;
8 |
9 | import java.sql.SQLException;
10 | import java.time.LocalDate;
11 | import java.time.LocalDateTime;
12 | import java.util.ArrayList;
13 | import java.util.List;
14 |
15 | public class AcuerdoController {
16 | private final IAcuerdoRepository acuerdosRepository;
17 |
18 | public AcuerdoController(IAcuerdoRepository acuerdosRepository) {
19 | this.acuerdosRepository = acuerdosRepository;
20 | }
21 |
22 | /**
23 | * Crea un acuerdo con los datos pasados por parámetro.
24 | *
25 | * @param nombre Nombre del acuerdo.
26 | * @param paises Paises que participan en el acuerdo.
27 | * @return El acuerdo creado.
28 | * @throws SQLException Si hay un error en la base de datos.
29 | */
30 | public Acuerdo createAcuerdo(String nombre, List paises) throws SQLException {
31 | List lineas = new ArrayList<>();
32 | for (Pais pais : paises) {
33 | lineas.add(new LineaAcuerdo(pais, LocalDate.now().getYear()));
34 | }
35 | Acuerdo acuerdo = new Acuerdo(0, nombre, LocalDateTime.now(), lineas);
36 | return acuerdosRepository.save(acuerdo).get();
37 | }
38 |
39 | /**
40 | * Obtiene un acuerdo por su id.
41 | *
42 | * @param id Id del acuerdo.
43 | * @return El acuerdo.
44 | * @throws AcuerdoException Si no existe el acuerdo.
45 | * @throws SQLException Si hay un error en la base de datos.
46 | */
47 | public Acuerdo getAcuerdoById(int id) throws AcuerdoException, SQLException {
48 | return acuerdosRepository.findById(id).orElseThrow(() -> new AcuerdoException("No existe el acuerdo con id " + id));
49 | }
50 |
51 | /**
52 | * Obtiene todos los acuerdos.
53 | *
54 | * @return Lista de acuerdos.
55 | * @throws SQLException Si hay un error en la base de datos.
56 | */
57 | public List getAllAcuerdos() throws SQLException {
58 | return acuerdosRepository.findAll();
59 | }
60 |
61 | /**
62 | * Elimina un acuerdo por su id.
63 | *
64 | * @param id Id del acuerdo.
65 | * @return El acuerdo eliminado.
66 | * @throws SQLException Si hay un error en la base de datos.
67 | */
68 | public Acuerdo deleteAcuerdo(int id) throws SQLException {
69 | return acuerdosRepository.delete(id).get();
70 | }
71 |
72 | /**
73 | * Actualiza un acuerdo.
74 | *
75 | * @param id Id del acuerdo.
76 | * @param acuerdo Acuerdo con los nuevos datos.
77 | * @return El acuerdo actualizado.
78 | * @throws SQLException Si hay un error en la base de datos.
79 | */
80 | public Acuerdo updateAcuerdo(int id, Acuerdo acuerdo) throws SQLException {
81 | return acuerdosRepository.update(id, acuerdo).get();
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/controllers/BackupManager.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.controllers;
2 |
3 | import es.joseluisgs.dam.models.Acuerdo;
4 | import es.joseluisgs.dam.models.Backup;
5 | import es.joseluisgs.dam.models.Pais;
6 | import es.joseluisgs.dam.repositories.acuerdos.IAcuerdoRepository;
7 | import es.joseluisgs.dam.repositories.paises.IPaisRepository;
8 | import es.joseluisgs.dam.services.Storage.IStorageBackup;
9 |
10 | import java.sql.SQLException;
11 |
12 | public class BackupManager {
13 | private final IPaisRepository paisRepository;
14 | private final IAcuerdoRepository acuerdoRepository;
15 | private final IStorageBackup storageBackup;
16 |
17 | public BackupManager(IPaisRepository paisRepository, IAcuerdoRepository acuerdoRepository, IStorageBackup storageBackup) {
18 | this.paisRepository = paisRepository;
19 | this.acuerdoRepository = acuerdoRepository;
20 | this.storageBackup = storageBackup;
21 | }
22 |
23 |
24 | /**
25 | * Importa los datos desde un fichero de backup
26 | */
27 | public void importarDatos() throws SQLException {
28 | System.out.println("Importando datos de Backup: " + storageBackup.getStoragePath());
29 | var backup = storageBackup.load();
30 | System.out.println("Importando Paises...");
31 | if (backup.getPaises().size() > 0) {
32 | paisRepository.clearAll();
33 | for (Pais pais : backup.getPaises()) {
34 | paisRepository.save(pais);
35 | }
36 | System.out.println("Paises importados con éxito al repositorio: " + backup.getPaises().size() + " paises");
37 | } else {
38 | System.out.println("Ha existido un problema al importar los datos de Paises");
39 | }
40 | System.out.println("Importando Acuerdos...");
41 | if (backup.getAcuerdos().size() > 0) {
42 | acuerdoRepository.clearAll();
43 | for (Acuerdo acuerdo : backup.getAcuerdos()) {
44 | acuerdoRepository.save(acuerdo);
45 | }
46 | System.out.println("Acuerdos importados con éxito al repositorio: " + backup.getAcuerdos().size() + " acuerdos");
47 | } else {
48 | System.out.println("Ha existido un problema al importar los datos de Acuerdos");
49 | }
50 | }
51 |
52 |
53 | /**
54 | * Exporta los datos desde un fichero de Backup
55 | */
56 | public void exportarDatos() throws SQLException {
57 | System.out.println("Exportando datos a fichero de Backup...");
58 | var paises = paisRepository.findAll();
59 | var acuerdos = acuerdoRepository.findAll();
60 | Backup backup = Backup.builder()
61 | .paises(paises)
62 | .acuerdos(acuerdos)
63 | .build();
64 | var res = storageBackup.save(backup);
65 | if (res) {
66 | System.out.println("Exportando " + backup.getPaises().size() + " paises");
67 | System.out.println("Exportando " + backup.getAcuerdos().size() + " acuerdos");
68 | System.out.println("Datos exportados con éxito en: " + storageBackup.getStoragePath());
69 | } else {
70 | System.out.println("Ha existido un problema al exportar los datos");
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/exceptions/AcuerdoException.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.exceptions;
2 |
3 | /**
4 | * Excepción asociada al comprotamiento de gestion de Acuerdos.
5 | */
6 | public class AcuerdoException extends Exception {
7 |
8 | public AcuerdoException(String mensaje) {
9 | super(mensaje);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/exceptions/PaisException.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.exceptions;
2 |
3 | /**
4 | * Excepción asociada al comprotamiento de gestion de paises.
5 | */
6 | public class PaisException extends Exception {
7 |
8 | public PaisException(String mensaje) {
9 | super(mensaje);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/models/Acuerdo.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import es.joseluisgs.dam.utils.Formatter;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 | import java.util.List;
8 |
9 | @Data
10 | public class Acuerdo {
11 | private final LocalDateTime fecha;
12 | private String nombre;
13 | private double aportacion;
14 | private List lineas;
15 | private int id;
16 |
17 |
18 | public Acuerdo(int id, String nombre, LocalDateTime fecha, List lineas) {
19 | this.id = id;
20 | this.nombre = nombre;
21 | this.fecha = fecha;
22 | this.lineas = lineas;
23 | this.aportacion = calcularAportacion();
24 | }
25 |
26 | public Acuerdo(int id, String nombre, LocalDateTime fecha, double aportacion, List lineas) {
27 | this.id = id;
28 | this.nombre = nombre;
29 | this.fecha = fecha;
30 | this.lineas = lineas;
31 | this.aportacion = aportacion;
32 | }
33 |
34 | private double calcularAportacion() {
35 | double total = 0;
36 | for (LineaAcuerdo linea : lineas) {
37 | total += linea.getSubvencion();
38 | }
39 | return total;
40 | }
41 |
42 | public Integer getId() {
43 | return id;
44 | }
45 |
46 | @Override
47 | public String toString() {
48 | // Puedes imprimir listas como Arrays.toString(lista))
49 | return "Acuerdo{" + "id=" + id + ", nombre=" + nombre + ", fecha="
50 | + Formatter.dateParser(fecha) + ", lineas=" + lineas + ", aportacion=" + Formatter.moneyParser(aportacion) + '}';
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/models/Backup.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import lombok.Builder;
4 |
5 | import java.time.LocalDateTime;
6 | import java.util.List;
7 |
8 | @Builder
9 | public class Backup {
10 | private final String createdAt = LocalDateTime.now().toString();
11 | private List paises;
12 | private List acuerdos;
13 |
14 | public List getPaises() {
15 | return paises;
16 | }
17 |
18 | public List getAcuerdos() {
19 | return acuerdos;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/models/LineaAcuerdo.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import es.joseluisgs.dam.utils.Formatter;
4 | import lombok.Data;
5 |
6 | @Data
7 | public class LineaAcuerdo {
8 | private final Pais pais;
9 | private final int año;
10 | private final double subvencion;
11 |
12 | public LineaAcuerdo(Pais pais, int año) {
13 | this.pais = pais;
14 | this.año = año;
15 | this.subvencion = pais.getPresupuesto() * 0.25;
16 | }
17 |
18 | public LineaAcuerdo(Pais pais, int año, double subvencion) {
19 | this.pais = pais;
20 | this.año = año;
21 | this.subvencion = subvencion;
22 | }
23 |
24 | @Override
25 | public String toString() {
26 | return "LineaAcuerdo{" + "pais=" + pais.getNombre() + ", año=" + año + ", subvencion=" + Formatter.moneyParser(subvencion) + '}';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/repositories/CRUDRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories;
2 |
3 | import java.sql.SQLException;
4 | import java.util.List;
5 | import java.util.Optional;
6 |
7 | public interface CRUDRepository {
8 | /**
9 | * Devuelve una lista de todos los elementos del repositorio
10 | *
11 | * @return Lista de elementos
12 | * @throws SQLException Si hay algún error en la base de datos
13 | */
14 | List findAll() throws SQLException;
15 |
16 | /**
17 | * Devuelve un Optional del elemento dada una id
18 | *
19 | * @param id Id del elemento
20 | * @return Optional del elemento
21 | * @throws SQLException Si hay algún error en la base de datos
22 | */
23 | Optional findById(ID id) throws SQLException;
24 |
25 | /**
26 | * Inserta un elemento en el repositorio
27 | *
28 | * @param entity Elemento a insertar
29 | * @return Elemento insertado
30 | * @throws SQLException Si hay algún error en la base de datos
31 | */
32 | Optional save(T entity) throws SQLException;
33 |
34 | /**
35 | * Actualiza un elemento en el repositorio
36 | *
37 | * @param id Id del elemento a actualizar
38 | * @param entity Elemento a actualizar
39 | * @return Elemento actualizado
40 | * @throws SQLException Si hay algún error en la base de datos
41 | */
42 | Optional update(ID id, T entity) throws SQLException;
43 |
44 | /**
45 | * Elimina un elemento del repositorio
46 | *
47 | * @param id Id del elemento a eliminar
48 | * @return Elemento eliminado
49 | * @throws SQLException Si hay algún error en la base de datos
50 | */
51 | Optional delete(ID id) throws SQLException;
52 | }
53 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/repositories/acuerdos/IAcuerdoRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories.acuerdos;
2 |
3 | import es.joseluisgs.dam.models.Acuerdo;
4 | import es.joseluisgs.dam.repositories.CRUDRepository;
5 |
6 | import java.sql.SQLException;
7 |
8 | public interface IAcuerdoRepository extends CRUDRepository {
9 |
10 | void clearAll() throws SQLException;
11 | }
12 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/repositories/paises/IPaisRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories.paises;
2 |
3 | import es.joseluisgs.dam.models.Pais;
4 | import es.joseluisgs.dam.repositories.CRUDRepository;
5 |
6 | import java.sql.SQLException;
7 | import java.util.Optional;
8 |
9 | // Toda nueva funcionalidad se extiende de la interfaz SOLID
10 | public interface IPaisRepository extends CRUDRepository {
11 |
12 | Optional findByNombre(String nombre) throws SQLException;
13 |
14 | void clearAll() throws SQLException;
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/services/Storage/IStorage.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services.Storage;
2 |
3 | public interface IStorage {
4 |
5 | /**
6 | * Salva los elementos almacenados en item.
7 | *
8 | * @param item Elementos a almacenar.
9 | * @return true si se ha almacenado correctamente, false en caso contrario.
10 | */
11 | boolean save(T item);
12 |
13 | /**
14 | * Le el almacenado y lo devuelve en un item T.
15 | *
16 | * @return Elementos almacenados.
17 | */
18 | T load();
19 |
20 | /**
21 | * Devuelve el path de la ubicación del almacenado.
22 | *
23 | * @return Path de la ubicación del almacenado.
24 | */
25 | String getStoragePath();
26 | }
27 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/services/Storage/IStorageBackup.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services.Storage;
2 |
3 | import es.joseluisgs.dam.models.Backup;
4 |
5 | public interface IStorageBackup extends IStorage {
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/services/Storage/StorageBackupJsonFile.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services.Storage;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.GsonBuilder;
5 | import com.google.gson.reflect.TypeToken;
6 | import es.joseluisgs.dam.models.Backup;
7 |
8 | import java.io.*;
9 | import java.nio.file.Files;
10 | import java.nio.file.Path;
11 | import java.nio.file.Paths;
12 |
13 | public class StorageBackupJsonFile implements IStorageBackup {
14 | private static StorageBackupJsonFile instance;
15 |
16 | private final Path currentRelativePath = Paths.get("");
17 | private final String ruta = currentRelativePath.toAbsolutePath().toString();
18 | private final String dir = ruta + File.separator + "data";
19 | private final String backupFile = dir + File.separator + "backup.json";
20 |
21 |
22 | private StorageBackupJsonFile() {
23 | init();
24 | }
25 |
26 | public static StorageBackupJsonFile getInstance() {
27 | if (instance == null) {
28 | instance = new StorageBackupJsonFile();
29 | }
30 | return instance;
31 | }
32 |
33 | private void init() {
34 | Path path = Paths.get(dir);
35 | if (!Files.exists(path)) {
36 | try {
37 | Files.createDirectories(path);
38 | } catch (IOException e) {
39 | System.out.println("Error: " + e.getMessage());
40 | }
41 | }
42 | }
43 |
44 | @Override
45 | public boolean save(Backup backup) {
46 | Gson gson = new GsonBuilder().setPrettyPrinting().create();
47 | boolean result = false;
48 | PrintWriter f = null;
49 | try {
50 | f = new PrintWriter(new FileWriter(backupFile));
51 | f.println(gson.toJson(backup));
52 | result = true;
53 |
54 | } catch (Exception e) {
55 | System.out.println("Error: " + e.getMessage());
56 | result = false;
57 | } finally {
58 | if (f != null) {
59 | f.close();
60 | }
61 | }
62 | return result;
63 | }
64 |
65 | @Override
66 | public Backup load() {
67 | Gson gson = new GsonBuilder().setPrettyPrinting().create();
68 | Backup backup = null;
69 | Reader reader = null;
70 | try {
71 | reader = Files.newBufferedReader(Paths.get(backupFile));
72 | backup = gson.fromJson(reader, new TypeToken() {
73 | }.getType());
74 | } catch (Exception e) {
75 | System.out.println("Error: " + e.getMessage());
76 | } finally {
77 | if (reader != null) {
78 | try {
79 | reader.close();
80 | } catch (IOException e) {
81 | System.out.println("Error: " + e.getMessage());
82 | }
83 | }
84 | }
85 | return backup;
86 | }
87 |
88 | @Override
89 | public String getStoragePath() {
90 | return backupFile;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/utils/ApplicationProperties.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import java.io.IOException;
4 | import java.util.Properties;
5 | import java.util.logging.Level;
6 | import java.util.logging.Logger;
7 |
8 | public class ApplicationProperties {
9 | private final Properties properties;
10 |
11 | public ApplicationProperties() {
12 | properties = new Properties();
13 | try {
14 | // De esta manera leemos desde el fichero de propiedades en resources
15 | properties.load(getClass().getClassLoader().getResourceAsStream("application.properties"));
16 |
17 | } catch (IOException ex) {
18 | System.err.println("IOException Ocurrido al leer el fichero de propiedades: " + ex.getMessage());
19 | Logger.getLogger(getClass().getName()).log(Level.ALL, "IOException Ocurrido al leer el fichero de propiedades: " + ex.getMessage());
20 | }
21 | }
22 |
23 | public String readProperty(String keyName) {
24 | // Logger.getLogger(getClass().getName()).log(Level.INFO, "Leyendo propiedad " + keyName);
25 | return properties.getProperty(keyName, "No existe esa clave en el fichero de propiedades");
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/utils/Console.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * Clase que permite leer datos desde la consola.
7 | */
8 | public class Console {
9 | public static String getString(String message) {
10 | System.out.println(message);
11 | return new Scanner(System.in).nextLine().trim();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/java/es/joseluisgs/dam/utils/Formatter.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import java.text.NumberFormat;
4 | import java.time.LocalDateTime;
5 | import java.time.format.DateTimeFormatter;
6 | import java.time.format.FormatStyle;
7 | import java.util.Locale;
8 |
9 | public class Formatter {
10 |
11 | public static String dateParser(LocalDateTime date) {
12 | final Locale locale = new Locale("es", "ES");
13 | // private String pattern = "dd/MM/yyyy";
14 | return date.format(DateTimeFormatter
15 | .ofLocalizedDate(FormatStyle.MEDIUM).withLocale(locale));
16 | }
17 |
18 | public static String moneyParser(Double money) {
19 | final Locale locale = new Locale("es", "ES");
20 | return NumberFormat.getCurrencyInstance(locale).format(money);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joseluisgs/Programacion-09-2021-2022/188c0476c2f30e7149340dda33239a3df1488e4b/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/resources/application.properties
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/main/resources/sql/init-db.sql:
--------------------------------------------------------------------------------
1 | -- Adminer 4.8.1 MySQL 5.5.5-10.6.4-MariaDB dump
2 |
3 | SET NAMES utf8;
4 | SET
5 | time_zone = '+00:00';
6 | SET
7 | foreign_key_checks = 0;
8 | SET
9 | sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
10 |
11 | DROP
12 | DATABASE IF EXISTS `dam`;
13 | CREATE
14 | DATABASE `dam` /*!40100 DEFAULT CHARACTER SET utf8mb3 */;
15 | USE
16 | `dam`;
17 |
18 | DROP TABLE IF EXISTS `acuerdo`;
19 | CREATE TABLE `acuerdo`
20 | (
21 | `id` int(11) NOT NULL AUTO_INCREMENT,
22 | `nombre` varchar(100) NOT NULL,
23 | `fecha` datetime NOT NULL,
24 | `aportacion` double NOT NULL,
25 | PRIMARY KEY (`id`)
26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
27 |
28 | INSERT INTO `acuerdo` (`id`, `nombre`, `fecha`, `aportacion`)
29 | VALUES (1, 'Acuerdo Diplomático', '2022-03-25 20:59:57', 12345.89),
30 | (2, 'Acuerdo de Fronteras', '2022-03-25 21:01:40', 999.99);
31 |
32 | DROP TABLE IF EXISTS `linea_acuerdo`;
33 | CREATE TABLE `linea_acuerdo`
34 | (
35 | `id_acuerdo` int(11) NOT NULL,
36 | `id_pais` int(11) NOT NULL,
37 | `año` int(11) NOT NULL,
38 | `subvencion` double NOT NULL,
39 | KEY `id_acuerdo` (`id_acuerdo`),
40 | KEY `id_pais` (`id_pais`),
41 | CONSTRAINT `linea_acuerdo_ibfk_1` FOREIGN KEY (`id_acuerdo`) REFERENCES `acuerdo` (`id`) ON DELETE CASCADE
42 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
43 |
44 | INSERT INTO `linea_acuerdo` (`id_acuerdo`, `id_pais`, `año`, `subvencion`)
45 | VALUES (1, 1, 2022, 1234.56),
46 | (1, 2, 2022, 345.32),
47 | (2, 4, 2022, 450.8),
48 | (2, 7, 2022, 6666.66),
49 | (2, 2, 2022, 333.33);
50 |
51 | DROP TABLE IF EXISTS `pais`;
52 | CREATE TABLE `pais`
53 | (
54 | `id` int(11) NOT NULL AUTO_INCREMENT,
55 | `nombre` varchar(100) NOT NULL,
56 | `codigo` varchar(5) NOT NULL,
57 | `idioma` varchar(100) NOT NULL,
58 | `moneda` varchar(50) NOT NULL,
59 | `capital` varchar(100) NOT NULL,
60 | `presupuesto` double DEFAULT NULL,
61 | PRIMARY KEY (`id`)
62 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
63 |
64 | INSERT INTO `pais` (`id`, `nombre`, `codigo`, `idioma`, `moneda`, `capital`, `presupuesto`)
65 | VALUES (1, 'España', 'ES', 'Español', 'Euro', 'Madrid', 1234567.23),
66 | (2, 'Francia', 'FR', 'Francés', 'Euro', 'París', 123456.67),
67 | (3, 'Italia', 'IT', 'Italiano', 'Euro', 'Roma', 564568.34),
68 | (4, 'Alemania', 'DE', 'Alemán', 'Euro', 'Berlín', 234567.23),
69 | (5, 'Reino Unido', 'UK', 'Inglés', 'Libra', 'Londres', 232323.34),
70 | (6, 'Japón', 'JP', 'Jsaponés', 'Yen', 'Tokio', 21212.12),
71 | (7, 'China', 'CN', 'Chino', 'Yuan', 'Pekín', 121212.34),
72 | (8, 'Australia', 'AU', 'Inglés', 'Dólar', 'Canberra', 567654.23),
73 | (9, 'Argentina', 'AR', 'Español', 'Peso', 'Buenos Aires', 123456.34),
74 | (10, 'Brasil', 'BR', 'Portugués', 'Real', 'Brasilia', 251251.62),
75 | (11, 'Estados Unidos', 'US', 'Inglés', 'Dólar', 'Washington', 1212415.98);
76 |
77 | -- 2022-03-26 11:15:34
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/test/java/es/joseluisgs/dam/MainTest.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertTrue;
6 |
7 | class MainTest {
8 |
9 | @Test
10 | public void trueIsTrue() {
11 | assertTrue(true);
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/test/java/es/joseluisgs/dam/utilities/DataBase.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utilities;
2 |
3 | import es.joseluisgs.dam.Main;
4 | import es.joseluisgs.dam.controllers.DataBaseManager;
5 | import es.joseluisgs.dam.utils.ApplicationProperties;
6 |
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 | import java.sql.SQLException;
10 |
11 | public class DataBase {
12 |
13 | /**
14 | * Inicia la base de datos con los datos de prueba si los hay, o la estructura de la tabla...
15 | */
16 | public static void init() {
17 | ApplicationProperties properties = new ApplicationProperties();
18 | boolean init = Boolean.parseBoolean(properties.readProperty("database.initdata"));
19 | if (init) {
20 | DataBaseManager controller = DataBaseManager.getInstance();
21 | String dataPath = "sql" + File.separator + "init-db.sql";
22 | try {
23 | var sqlFile = Main.class.getClassLoader().getResource(dataPath).getPath();
24 | controller.open();
25 | controller.initData(sqlFile, false);
26 | controller.close();
27 | } catch (SQLException e) {
28 | System.err.println("Error al conectar al servidor de Base de Datos: " + e.getMessage());
29 | System.exit(1);
30 | } catch (FileNotFoundException e) {
31 | System.err.println("Error al leer el fichero de datos iniciales: " + e.getMessage());
32 | System.exit(1);
33 | }
34 | }
35 | }
36 |
37 | /**
38 | * Borra todas las tablas, que cuesta menos que tirar toda la base de datos y levantarla de nuevo
39 | *
40 | * @throws SQLException
41 | */
42 | public static void deleteAll() throws SQLException {
43 | DataBaseManager db = DataBaseManager.getInstance();
44 | String query = "DELETE FROM pais";
45 | db.open();
46 | db.delete(query);
47 | query = "DELETE FROM acuerdo";
48 | db.beginTransaction();
49 | db.delete(query);
50 | query = "DELETE FROM linea_acuerdo";
51 | db.delete(query);
52 | db.commit();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/test/java/es/joseluisgs/dam/utilities/DataDB.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utilities;
2 |
3 | import es.joseluisgs.dam.controllers.DataBaseManager;
4 | import es.joseluisgs.dam.models.Acuerdo;
5 | import es.joseluisgs.dam.models.LineaAcuerdo;
6 | import es.joseluisgs.dam.models.Pais;
7 |
8 | import java.sql.ResultSet;
9 | import java.sql.SQLException;
10 | import java.util.Optional;
11 |
12 | public class DataDB {
13 | // Insertamos un dato de prueba, aquí vemos un acoplamiento...
14 | // Si no quiseramos esto, podríamos usar Order de test
15 | // Lo ideal es meterlo en el script, e iniciarlo cada vez...
16 | public static void insertPaisTest(Pais paisTest) throws SQLException {
17 | String query = "INSERT INTO pais VALUES (null, ?, ?, ?, ?, ?, ?)";
18 | DataBaseManager db = DataBaseManager.getInstance();
19 | db.open();
20 | Optional res = db.insert(query, paisTest.getNombre(), paisTest.getCodigo(), paisTest.getIdioma(), paisTest.getMoneda(),
21 | paisTest.getCapital(), paisTest.getPresupuesto());
22 | if (res.get().first()) {
23 | paisTest.setId(res.get().getInt(1));
24 | }
25 | db.close();
26 | }
27 |
28 | public static void insertAcuerdoTest(Acuerdo acuerdoTest) throws SQLException {
29 | // OJO pongo null en el primer parámetro porque no inserto el ID, este se genera automático. Mira el DBMAnager
30 | String query = "INSERT INTO acuerdo VALUES (null, ?, ?, ?)";
31 | DataBaseManager db = DataBaseManager.getInstance();
32 | // Es una transacción, por lo que si falla alguna de las dos, se cancela todo
33 | db.open();
34 | db.beginTransaction();
35 | ResultSet res = db.insert(query, acuerdoTest.getNombre(), acuerdoTest.getFecha(), acuerdoTest.getAportacion())
36 | .orElseThrow(() -> new SQLException("Error al insertar acuerdo"));
37 |
38 | // Para obtener su ID que ha generado la BD
39 | if (res.first()) {
40 | acuerdoTest.setId(res.getInt(1));
41 | // Ahora salvamos toda las lineas de acuerdo...
42 | for (LineaAcuerdo linea : acuerdoTest.getLineas()) {
43 | query = "INSERT INTO linea_acuerdo VALUES (?, ?, ?, ?)";
44 | db.insert(query, acuerdoTest.getId(), linea.getPais().getId(), linea.getAño(), linea.getSubvencion())
45 | .orElseThrow(() -> new SQLException("Error al insertar linea de acuerdo"));
46 | }
47 |
48 | // Y finalmente cerramos la conexión y devolvemos el acuerdo
49 | db.commit();
50 | db.close();
51 | }
52 | db.rollback();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/test/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joseluisgs/Programacion-09-2021-2022/188c0476c2f30e7149340dda33239a3df1488e4b/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/test/resources/application.properties
--------------------------------------------------------------------------------
/Soluciones/08-MVC-Paises-BBDD-Optional-Functional/src/test/resources/sql/init-db.sql:
--------------------------------------------------------------------------------
1 | -- Adminer 4.8.1 MySQL 5.5.5-10.6.4-MariaDB dump
2 |
3 | SET NAMES utf8;
4 | SET
5 | time_zone = '+00:00';
6 | SET
7 | foreign_key_checks = 0;
8 | SET
9 | sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
10 |
11 | DROP
12 | DATABASE IF EXISTS `dam`;
13 | CREATE
14 | DATABASE `dam` /*!40100 DEFAULT CHARACTER SET utf8mb3 */;
15 | USE
16 | `dam`;
17 |
18 | DROP TABLE IF EXISTS `acuerdo`;
19 | CREATE TABLE `acuerdo`
20 | (
21 | `id` int(11) NOT NULL AUTO_INCREMENT,
22 | `nombre` varchar(100) NOT NULL,
23 | `fecha` datetime NOT NULL,
24 | `aportacion` double NOT NULL,
25 | PRIMARY KEY (`id`)
26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
27 |
28 |
29 | DROP TABLE IF EXISTS `linea_acuerdo`;
30 | CREATE TABLE `linea_acuerdo`
31 | (
32 | `id_acuerdo` int(11) NOT NULL,
33 | `id_pais` int(11) NOT NULL,
34 | `año` int(11) NOT NULL,
35 | `subvencion` double NOT NULL,
36 | KEY `id_acuerdo` (`id_acuerdo`),
37 | KEY `id_pais` (`id_pais`),
38 | CONSTRAINT `linea_acuerdo_ibfk_1` FOREIGN KEY (`id_acuerdo`) REFERENCES `acuerdo` (`id`) ON DELETE CASCADE
39 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
40 |
41 | DROP TABLE IF EXISTS `pais`;
42 | CREATE TABLE `pais`
43 | (
44 | `id` int(11) NOT NULL AUTO_INCREMENT,
45 | `nombre` varchar(100) NOT NULL,
46 | `codigo` varchar(5) NOT NULL,
47 | `idioma` varchar(100) NOT NULL,
48 | `moneda` varchar(50) NOT NULL,
49 | `capital` varchar(100) NOT NULL,
50 | `presupuesto` double DEFAULT NULL,
51 | PRIMARY KEY (`id`)
52 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
53 |
54 | -- 2022-03-26 11:15:34
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.idea/description.html:
--------------------------------------------------------------------------------
1 | Simple Java application that includes a class with main()
method
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.idea/libraries/Maven__org_projectlombok_lombok_1_18_22.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/.idea/project-template.xml:
--------------------------------------------------------------------------------
1 |
2 | IJ_BASE_PACKAGE
3 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/AccidentesStream.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | groupId
8 | AccidentesStream
9 | 1.0-SNAPSHOT
10 |
11 |
12 | org.projectlombok
13 | lombok
14 | RELEASE
15 | compile
16 |
17 |
18 |
19 |
20 | 11
21 | 11
22 |
23 |
24 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/src/main/java/es/joseluisgs/dam/Accidente.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | import lombok.Data;
4 |
5 | import java.time.LocalDate;
6 | import java.time.LocalTime;
7 |
8 | @Data
9 | public class Accidente {
10 | private final String numExpediente;
11 | private final LocalDate fecha;
12 | private final LocalTime hora;
13 | private final String localizacion;
14 | private final String distrito;
15 | private final String tipoAccidente;
16 | private final String meteorologia;
17 | private final String tipoVehiculo;
18 | private final String tipoPersona;
19 | private final String sexo;
20 | private final boolean positivoAlcohol;
21 | private final boolean positivoDrogas;
22 | }
23 |
--------------------------------------------------------------------------------
/Soluciones/09-AccidentesStream/src/main/java/es/joseluisgs/dam/Main.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | public class Main {
4 |
5 | public static void main(String[] args) {
6 | System.out.println("Accidentes Madrid");
7 | System.out.println("==================");
8 | AccidentesController controller = new AccidentesController();
9 | controller.run();
10 |
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.toptal.com/developers/gitignore/api/maven,java,intellij+all
3 | # Edit at https://www.toptal.com/developers/gitignore?templates=maven,java,intellij+all
4 |
5 | ### Intellij+all ###
6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
8 |
9 | # User-specific stuff
10 | .idea/**/workspace.xml
11 | .idea/**/tasks.xml
12 | .idea/**/usage.statistics.xml
13 | .idea/**/dictionaries
14 | .idea/**/shelf
15 |
16 | # AWS User-specific
17 | .idea/**/aws.xml
18 |
19 | # Generated files
20 | .idea/**/contentModel.xml
21 |
22 | # Sensitive or high-churn files
23 | .idea/**/dataSources/
24 | .idea/**/dataSources.ids
25 | .idea/**/dataSources.local.xml
26 | .idea/**/sqlDataSources.xml
27 | .idea/**/dynamic.xml
28 | .idea/**/uiDesigner.xml
29 | .idea/**/dbnavigator.xml
30 |
31 | # Gradle
32 | .idea/**/gradle.xml
33 | .idea/**/libraries
34 |
35 | # Gradle and Maven with auto-import
36 | # When using Gradle or Maven with auto-import, you should exclude module files,
37 | # since they will be recreated, and may cause churn. Uncomment if using
38 | # auto-import.
39 | # .idea/artifacts
40 | # .idea/compiler.xml
41 | # .idea/jarRepositories.xml
42 | # .idea/modules.xml
43 | # .idea/*.iml
44 | # .idea/modules
45 | # *.iml
46 | # *.ipr
47 |
48 | # CMake
49 | cmake-build-*/
50 |
51 | # Mongo Explorer plugin
52 | .idea/**/mongoSettings.xml
53 |
54 | # File-based project format
55 | *.iws
56 |
57 | # IntelliJ
58 | out/
59 |
60 | # mpeltonen/sbt-idea plugin
61 | .idea_modules/
62 |
63 | # JIRA plugin
64 | atlassian-ide-plugin.xml
65 |
66 | # Cursive Clojure plugin
67 | .idea/replstate.xml
68 |
69 | # SonarLint plugin
70 | .idea/sonarlint/
71 |
72 | # Crashlytics plugin (for Android Studio and IntelliJ)
73 | com_crashlytics_export_strings.xml
74 | crashlytics.properties
75 | crashlytics-build.properties
76 | fabric.properties
77 |
78 | # Editor-based Rest Client
79 | .idea/httpRequests
80 |
81 | # Android studio 3.1+ serialized cache file
82 | .idea/caches/build_file_checksums.ser
83 |
84 | ### Intellij+all Patch ###
85 | # Ignore everything but code style settings and run configurations
86 | # that are supposed to be shared within teams.
87 |
88 | .idea/*
89 |
90 | !.idea/codeStyles
91 | !.idea/runConfigurations
92 |
93 | ### Java ###
94 | # Compiled class file
95 | *.class
96 |
97 | # Log file
98 | *.log
99 |
100 | # BlueJ files
101 | *.ctxt
102 |
103 | # Mobile Tools for Java (J2ME)
104 | .mtj.tmp/
105 |
106 | # Package Files #
107 | *.jar
108 | *.war
109 | *.nar
110 | *.ear
111 | *.zip
112 | *.tar.gz
113 | *.rar
114 |
115 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
116 | hs_err_pid*
117 | replay_pid*
118 |
119 | ### Maven ###
120 | target/
121 | pom.xml.tag
122 | pom.xml.releaseBackup
123 | pom.xml.versionsBackup
124 | pom.xml.next
125 | release.properties
126 | dependency-reduced-pom.xml
127 | buildNumber.properties
128 | .mvn/timing.properties
129 | # https://github.com/takari/maven-wrapper#usage-without-binary-jar
130 | .mvn/wrapper/maven-wrapper.jar
131 |
132 | # Eclipse m2e generated files
133 | # Eclipse Core
134 | .project
135 | # JDT-specific (Eclipse Java Development Tools)
136 | .classpath
137 |
138 | # End of https://www.toptal.com/developers/gitignore/api/maven,java,intellij+all
139 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/SecuenciaPaises.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/docker/docker-compose.yml:
--------------------------------------------------------------------------------
1 | # Indicamos la versión
2 | # Para iniciar docker-compose up -d
3 | version: '3.7'
4 |
5 | # Mis servicios
6 | # Iniciamos los servicios
7 | services:
8 | # MARIA DB
9 | mariadb:
10 | build: ./mariadb
11 | image: mariadb
12 | container_name: mariadb
13 | ports:
14 | - 3306:3306
15 | expose:
16 | - 3306
17 | volumes:
18 | - mariadb-volume:/var/lib/mysql
19 | networks:
20 | - mariadb-network
21 | # restart: always
22 |
23 | # ADMIN MARIADB
24 | adminer:
25 | image: adminer
26 | container_name: adminer
27 | # restart: always
28 | ports:
29 | - 8080:8080
30 | networks:
31 | - mariadb-network
32 | depends_on:
33 | - mariadb
34 |
35 | # Mi volumenes de datos compartidos
36 | volumes:
37 | mariadb-volume:
38 |
39 | # Si queremos que tengan una red propia a otros contenedores
40 | networks:
41 | mariadb-network:
42 | driver: bridge
43 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/docker/mariadb/Dockerfile:
--------------------------------------------------------------------------------
1 | # MariaDB
2 | FROM yobasystems/alpine-mariadb:10
3 | # FROM mariadb:10.5
4 |
5 | # Configuramos BBDD
6 | ENV MYSQL_ROOT_PASSWORD 123
7 | ENV MYSQL_USER dam
8 | ENV MYSQL_PASSWORD dam1234
9 | ENV MYSQL_DATABASE dam
10 |
11 | # Copiamos los ficheros sql para que se ejecuten
12 | COPY ./sql /docker-entrypoint-initdb.d/
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | groupId
8 | SecuenciaPaises
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 11
13 | 11
14 | 3.10.1
15 |
16 |
17 |
18 |
19 |
20 | com.google.code.gson
21 | gson
22 | 2.9.0
23 |
24 |
25 |
26 | org.projectlombok
27 | lombok
28 | 1.18.22
29 | compile
30 |
31 |
32 |
33 | org.mariadb.jdbc
34 | mariadb-java-client
35 | 3.0.3
36 |
37 |
38 |
39 | org.mybatis
40 | mybatis
41 | 3.5.9
42 |
43 |
44 |
45 | org.junit.jupiter
46 | junit-jupiter
47 | 5.8.2
48 | test
49 |
50 |
51 |
52 | org.mockito
53 | mockito-core
54 | 4.4.0
55 | test
56 |
57 |
58 | org.mockito
59 | mockito-junit-jupiter
60 | 4.4.0
61 | test
62 |
63 |
64 |
65 | com.google.dagger
66 | dagger
67 | 2.41
68 |
69 |
70 |
71 |
72 |
73 |
75 |
76 | org.apache.maven.plugins
77 | maven-compiler-plugin
78 | ${maven-compiler-plugin.version}
79 |
80 |
81 |
82 | com.google.dagger
83 | dagger-compiler
84 | 2.41
85 |
86 |
87 | org.projectlombok
88 | lombok
89 | 1.18.22
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/DI/controllers/controllers/AcuerdoControllerDI.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.DI.controllers.controllers;
2 |
3 | import dagger.Component;
4 | import es.joseluisgs.dam.DI.modules.AcuerdoRepositoryModule;
5 | import es.joseluisgs.dam.DI.modules.DataBaseManagerModule;
6 | import es.joseluisgs.dam.controllers.AcuerdoController;
7 |
8 | import javax.inject.Singleton;
9 |
10 | @Singleton
11 | @Component(modules = {
12 | AcuerdoRepositoryModule.class,
13 | DataBaseManagerModule.class
14 | })
15 |
16 | public interface AcuerdoControllerDI {
17 | AcuerdoController build();
18 | }
19 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/DI/controllers/controllers/BackupManagerDI.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.DI.controllers.controllers;
2 |
3 | import dagger.Component;
4 | import es.joseluisgs.dam.DI.modules.AcuerdoRepositoryModule;
5 | import es.joseluisgs.dam.DI.modules.DataBaseManagerModule;
6 | import es.joseluisgs.dam.DI.modules.PaisRepositoryModule;
7 | import es.joseluisgs.dam.DI.modules.StorageBackupModule;
8 | import es.joseluisgs.dam.controllers.BackupManager;
9 |
10 | import javax.inject.Singleton;
11 |
12 | @Singleton
13 | @Component(modules = {
14 | PaisRepositoryModule.class,
15 | AcuerdoRepositoryModule.class,
16 | StorageBackupModule.class,
17 | DataBaseManagerModule.class
18 | })
19 |
20 | public interface BackupManagerDI {
21 | BackupManager build();
22 | }
23 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/DI/controllers/controllers/PaisControllerDI.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.DI.controllers.controllers;
2 |
3 | import dagger.Component;
4 | import es.joseluisgs.dam.DI.modules.DataBaseManagerModule;
5 | import es.joseluisgs.dam.DI.modules.PaisRepositoryModule;
6 | import es.joseluisgs.dam.controllers.PaisController;
7 |
8 | import javax.inject.Singleton;
9 |
10 | @Singleton
11 | @Component(modules = {
12 | PaisRepositoryModule.class,
13 | DataBaseManagerModule.class
14 | })
15 |
16 | public interface PaisControllerDI {
17 | PaisController build();
18 | }
19 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/DI/modules/AcuerdoRepositoryModule.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.DI.modules;
2 |
3 | import dagger.Binds;
4 | import dagger.Module;
5 | import es.joseluisgs.dam.repositories.acuerdos.AcuerdoRepository;
6 | import es.joseluisgs.dam.repositories.acuerdos.IAcuerdoRepository;
7 |
8 | import javax.inject.Singleton;
9 |
10 | @Module
11 | public interface AcuerdoRepositoryModule {
12 | @Singleton
13 | @Binds
14 | IAcuerdoRepository bindAcuerdoRepository(AcuerdoRepository impl);
15 | }
16 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/DI/modules/DataBaseManagerModule.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.DI.modules;
2 |
3 | import dagger.Module;
4 | import dagger.Provides;
5 | import es.joseluisgs.dam.controllers.DataBaseManager;
6 |
7 | import javax.inject.Singleton;
8 |
9 | @Module
10 | public class DataBaseManagerModule {
11 |
12 | @Provides
13 | @Singleton
14 | DataBaseManager provideDataBaseManager() {
15 | return DataBaseManager.getInstance();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/DI/modules/PaisRepositoryModule.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.DI.modules;
2 |
3 | import dagger.Binds;
4 | import dagger.Module;
5 | import es.joseluisgs.dam.repositories.paises.IPaisRepository;
6 | import es.joseluisgs.dam.repositories.paises.PaisRepository;
7 |
8 | import javax.inject.Singleton;
9 |
10 | @Module
11 | public interface PaisRepositoryModule {
12 | @Singleton
13 | @Binds
14 | IPaisRepository bindPaisRepository(PaisRepository impl);
15 | }
16 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/DI/modules/StorageBackupModule.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.DI.modules;
2 |
3 | import dagger.Binds;
4 | import dagger.Module;
5 | import es.joseluisgs.dam.services.Storage.IStorageBackup;
6 | import es.joseluisgs.dam.services.Storage.StorageBackupJsonFile;
7 |
8 | import javax.inject.Named;
9 | import javax.inject.Singleton;
10 |
11 | @Module
12 | public
13 | interface StorageBackupModule {
14 | @Binds
15 | @Singleton
16 | @Named("json")
17 | IStorageBackup provideApiStorageBackupService(StorageBackupJsonFile impl);
18 |
19 | }
20 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/Main.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | import es.joseluisgs.dam.controllers.DataBaseManager;
4 | import es.joseluisgs.dam.utils.ApplicationProperties;
5 | import es.joseluisgs.dam.views.PaisView;
6 |
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 | import java.sql.ResultSet;
10 | import java.sql.SQLException;
11 | import java.util.Optional;
12 |
13 | /**
14 | * Ejemplo de Patrón MVC para CRUD de países.
15 | * Siguiendo los diagramas de Secuencias en Clase
16 | * Modelo: Pais, gestionador por PaisRepository
17 | * Vista: La propia consola: comunicacion con el usuario
18 | * Controlador: PaisController, controla, cómo y de qué manera el modelo, repositorio y la vista interactúan
19 | * Como vista que soy, soy lo último y gestiono las excepciones con Try/Catch
20 | */
21 | public class Main {
22 | public static void main(String[] args) {
23 | checkServer();
24 | initData();
25 | PaisView view = PaisView.getInstance();
26 | view.menu();
27 |
28 | }
29 |
30 | private static void checkServer() {
31 | System.out.println("Comprobamos la conexión al Servidor BD");
32 | DataBaseManager controller = DataBaseManager.getInstance();
33 | try {
34 | controller.open();
35 | Optional rs = controller.select("SELECT 'Hello world'");
36 | if (rs.isPresent()) {
37 | rs.get().first();
38 | controller.close();
39 | System.out.println("Conexión con la Base de Datos realizada con éxito");
40 | }
41 | } catch (SQLException e) {
42 | System.err.println("Error al conectar al servidor de Base de Datos: " + e.getMessage());
43 | System.exit(1);
44 | }
45 | }
46 |
47 | private static void initData() {
48 | ApplicationProperties properties = new ApplicationProperties();
49 | boolean init = Boolean.parseBoolean(properties.readProperty("database.initdata"));
50 | if (init) {
51 | System.out.println("Iniciamos los datos de ejemplo de la Base de Datos");
52 | DataBaseManager controller = DataBaseManager.getInstance();
53 | String dataPath = "sql" + File.separator + "init-db.sql";
54 | try {
55 | var sqlFile = Main.class.getClassLoader().getResource(dataPath).getPath();
56 | System.out.println(dataPath);
57 | controller.open();
58 | controller.initData(sqlFile, false);
59 | controller.close();
60 | System.out.println("Datos inicializados con éxito");
61 | } catch (SQLException e) {
62 | System.err.println("Error al conectar al servidor de Base de Datos: " + e.getMessage());
63 | System.exit(1);
64 | } catch (FileNotFoundException e) {
65 | System.err.println("Error al leer el fichero de datos iniciales: " + e.getMessage());
66 | System.exit(1);
67 | }
68 | }
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/controllers/AcuerdoController.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.controllers;
2 |
3 | import es.joseluisgs.dam.exceptions.AcuerdoException;
4 | import es.joseluisgs.dam.models.Acuerdo;
5 | import es.joseluisgs.dam.models.LineaAcuerdo;
6 | import es.joseluisgs.dam.models.Pais;
7 | import es.joseluisgs.dam.repositories.acuerdos.IAcuerdoRepository;
8 |
9 | import javax.inject.Inject;
10 | import java.sql.SQLException;
11 | import java.time.LocalDate;
12 | import java.time.LocalDateTime;
13 | import java.util.ArrayList;
14 | import java.util.List;
15 |
16 | public class AcuerdoController {
17 | private final IAcuerdoRepository acuerdosRepository;
18 |
19 | @Inject
20 | public AcuerdoController(IAcuerdoRepository acuerdosRepository) {
21 | this.acuerdosRepository = acuerdosRepository;
22 | }
23 |
24 | /**
25 | * Crea un acuerdo con los datos pasados por parámetro.
26 | *
27 | * @param nombre Nombre del acuerdo.
28 | * @param paises Paises que participan en el acuerdo.
29 | * @return El acuerdo creado.
30 | * @throws SQLException Si hay un error en la base de datos.
31 | */
32 | public Acuerdo createAcuerdo(String nombre, List paises) throws SQLException {
33 | List lineas = new ArrayList<>();
34 | for (Pais pais : paises) {
35 | lineas.add(new LineaAcuerdo(pais, LocalDate.now().getYear()));
36 | }
37 | Acuerdo acuerdo = new Acuerdo(0, nombre, LocalDateTime.now(), lineas);
38 | return acuerdosRepository.save(acuerdo).get();
39 | }
40 |
41 | /**
42 | * Obtiene un acuerdo por su id.
43 | *
44 | * @param id Id del acuerdo.
45 | * @return El acuerdo.
46 | * @throws AcuerdoException Si no existe el acuerdo.
47 | * @throws SQLException Si hay un error en la base de datos.
48 | */
49 | public Acuerdo getAcuerdoById(int id) throws AcuerdoException, SQLException {
50 | return acuerdosRepository.findById(id).orElseThrow(() -> new AcuerdoException("No existe el acuerdo con id " + id));
51 | }
52 |
53 | /**
54 | * Obtiene todos los acuerdos.
55 | *
56 | * @return Lista de acuerdos.
57 | * @throws SQLException Si hay un error en la base de datos.
58 | */
59 | public List getAllAcuerdos() throws SQLException {
60 | return acuerdosRepository.findAll();
61 | }
62 |
63 | /**
64 | * Elimina un acuerdo por su id.
65 | *
66 | * @param id Id del acuerdo.
67 | * @return El acuerdo eliminado.
68 | * @throws SQLException Si hay un error en la base de datos.
69 | */
70 | public Acuerdo deleteAcuerdo(int id) throws SQLException {
71 | return acuerdosRepository.delete(id).get();
72 | }
73 |
74 | /**
75 | * Actualiza un acuerdo.
76 | *
77 | * @param id Id del acuerdo.
78 | * @param acuerdo Acuerdo con los nuevos datos.
79 | * @return El acuerdo actualizado.
80 | * @throws SQLException Si hay un error en la base de datos.
81 | */
82 | public Acuerdo updateAcuerdo(int id, Acuerdo acuerdo) throws SQLException {
83 | return acuerdosRepository.update(id, acuerdo).get();
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/controllers/BackupManager.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.controllers;
2 |
3 | import dagger.Lazy;
4 | import es.joseluisgs.dam.models.Acuerdo;
5 | import es.joseluisgs.dam.models.Backup;
6 | import es.joseluisgs.dam.models.Pais;
7 | import es.joseluisgs.dam.repositories.acuerdos.IAcuerdoRepository;
8 | import es.joseluisgs.dam.repositories.paises.IPaisRepository;
9 | import es.joseluisgs.dam.services.Storage.IStorageBackup;
10 |
11 | import javax.inject.Inject;
12 | import javax.inject.Named;
13 | import java.sql.SQLException;
14 |
15 | public class BackupManager {
16 | private final Lazy paisRepository;
17 | private final Lazy acuerdoRepository;
18 | private final Lazy storageBackup;
19 |
20 | @Inject
21 | public BackupManager(
22 | Lazy paisRepository,
23 | Lazy acuerdoRepository,
24 | @Named("json") Lazy storageBackup
25 | ) {
26 | this.paisRepository = paisRepository;
27 | this.acuerdoRepository = acuerdoRepository;
28 | this.storageBackup = storageBackup;
29 | }
30 |
31 |
32 | /**
33 | * Importa los datos desde un fichero de backup
34 | */
35 | public void importarDatos() throws SQLException {
36 | System.out.println("Importando datos de Backup: " + storageBackup.get().getStoragePath());
37 | var backup = storageBackup.get().load();
38 | System.out.println("Importando Paises...");
39 | if (backup.getPaises().size() > 0) {
40 | paisRepository.get().clearAll();
41 | for (Pais pais : backup.getPaises()) {
42 | paisRepository.get().save(pais);
43 | }
44 | System.out.println("Paises importados con éxito al repositorio: " + backup.getPaises().size() + " paises");
45 | } else {
46 | System.out.println("Ha existido un problema al importar los datos de Paises");
47 | }
48 | System.out.println("Importando Acuerdos...");
49 | if (backup.getAcuerdos().size() > 0) {
50 | acuerdoRepository.get().clearAll();
51 | for (Acuerdo acuerdo : backup.getAcuerdos()) {
52 | acuerdoRepository.get().save(acuerdo);
53 | }
54 | System.out.println("Acuerdos importados con éxito al repositorio: " + backup.getAcuerdos().size() + " acuerdos");
55 | } else {
56 | System.out.println("Ha existido un problema al importar los datos de Acuerdos");
57 | }
58 | }
59 |
60 |
61 | /**
62 | * Exporta los datos desde un fichero de Backup
63 | */
64 | public void exportarDatos() throws SQLException {
65 | System.out.println("Exportando datos a fichero de Backup...");
66 | var paises = paisRepository.get().findAll();
67 | var acuerdos = acuerdoRepository.get().findAll();
68 | Backup backup = Backup.builder()
69 | .paises(paises)
70 | .acuerdos(acuerdos)
71 | .build();
72 | var res = storageBackup.get().save(backup);
73 | if (res) {
74 | System.out.println("Exportando " + backup.getPaises().size() + " paises");
75 | System.out.println("Exportando " + backup.getAcuerdos().size() + " acuerdos");
76 | System.out.println("Datos exportados con éxito en: " + storageBackup.get().getStoragePath());
77 | } else {
78 | System.out.println("Ha existido un problema al exportar los datos");
79 | }
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/exceptions/AcuerdoException.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.exceptions;
2 |
3 | /**
4 | * Excepción asociada al comprotamiento de gestion de Acuerdos.
5 | */
6 | public class AcuerdoException extends Exception {
7 |
8 | public AcuerdoException(String mensaje) {
9 | super(mensaje);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/exceptions/PaisException.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.exceptions;
2 |
3 | /**
4 | * Excepción asociada al comprotamiento de gestion de paises.
5 | */
6 | public class PaisException extends Exception {
7 |
8 | public PaisException(String mensaje) {
9 | super(mensaje);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/models/Acuerdo.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import es.joseluisgs.dam.utils.Formatter;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDateTime;
7 | import java.util.List;
8 |
9 | @Data
10 | public class Acuerdo {
11 | private final LocalDateTime fecha;
12 | private String nombre;
13 | private double aportacion;
14 | private List lineas;
15 | private int id;
16 |
17 |
18 | public Acuerdo(int id, String nombre, LocalDateTime fecha, List lineas) {
19 | this.id = id;
20 | this.nombre = nombre;
21 | this.fecha = fecha;
22 | this.lineas = lineas;
23 | this.aportacion = calcularAportacion();
24 | }
25 |
26 | private double calcularAportacion() {
27 | return lineas.stream().mapToDouble(LineaAcuerdo::getSubvencion).sum();
28 | }
29 |
30 | public Integer getId() {
31 | return id;
32 | }
33 |
34 | @Override
35 | public String toString() {
36 | // Puedes imprimir listas como Arrays.toString(lista))
37 | return "Acuerdo{" + "id=" + id + ", nombre=" + nombre + ", fecha="
38 | + Formatter.dateParser(fecha) + ", lineas=" + lineas + ", aportacion=" + Formatter.moneyParser(aportacion) + '}';
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/models/Backup.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import lombok.Builder;
4 |
5 | import java.time.LocalDateTime;
6 | import java.util.List;
7 |
8 | @Builder
9 | public class Backup {
10 | private final String createdAt = LocalDateTime.now().toString();
11 | private List paises;
12 | private List acuerdos;
13 |
14 | public List getPaises() {
15 | return paises;
16 | }
17 |
18 | public List getAcuerdos() {
19 | return acuerdos;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/models/LineaAcuerdo.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import es.joseluisgs.dam.utils.Formatter;
4 | import lombok.Data;
5 |
6 | @Data
7 | public class LineaAcuerdo {
8 | private final Pais pais;
9 | private final int año;
10 | private final double subvencion;
11 |
12 | public LineaAcuerdo(Pais pais, int año) {
13 | this.pais = pais;
14 | this.año = año;
15 | this.subvencion = pais.getPresupuesto() * 0.25;
16 | }
17 |
18 | public LineaAcuerdo(Pais pais, int año, double subvencion) {
19 | this.pais = pais;
20 | this.año = año;
21 | this.subvencion = subvencion;
22 | }
23 |
24 | @Override
25 | public String toString() {
26 | return "LineaAcuerdo{" + "pais=" + pais.getNombre() + ", año=" + año + ", subvencion=" + Formatter.moneyParser(subvencion) + '}';
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/models/Pais.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import es.joseluisgs.dam.utils.Formatter;
4 | import lombok.Builder;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 |
8 | /**
9 | * Modelo. Clase que representa un país. POJO.
10 | * Se hace lo más limpia posible para que sirva a numerosos casos. No se implementa excepciones ni comparables
11 | * Es un POJO de "libro"
12 | */
13 |
14 | @Data
15 | @NoArgsConstructor
16 | @Builder
17 | public class Pais {
18 | private int id = 0;
19 | private String nombre;
20 | private String codigo;
21 | private String idioma;
22 | private String moneda;
23 | private String capital;
24 | private double presupuesto;
25 |
26 |
27 | public Pais(String nombre, String codigo, String idioma, String moneda, String capital) {
28 | this.nombre = nombre;
29 | this.codigo = codigo;
30 | this.idioma = idioma;
31 | this.moneda = moneda;
32 | this.capital = capital;
33 | // Voy a dejar el presupuesto aleatorio
34 | this.presupuesto = Math.random() * 1000000;
35 | }
36 |
37 | public Pais(int id, String nombre, String codigo, String idioma, String moneda, String capital, double presupuesto) {
38 | this.id = id;
39 | this.nombre = nombre;
40 | this.codigo = codigo;
41 | this.idioma = idioma;
42 | this.moneda = moneda;
43 | this.capital = capital;
44 | this.presupuesto = presupuesto;
45 | }
46 |
47 | @Override
48 | public String toString() {
49 | return "Pais{" + "id=" + id + ", nombre=" + nombre + ", codigo=" + codigo + ", idioma=" + idioma + ", moneda=" + moneda + ", capital=" + capital + ", presupuesto=" + Formatter.moneyParser(presupuesto) + '}';
50 | }
51 |
52 |
53 | public Pais nombre(String nombre) {
54 | this.nombre = nombre;
55 | return this;
56 | }
57 |
58 | public Pais codigo(String codigo) {
59 | this.codigo = codigo;
60 | return this;
61 | }
62 |
63 | public Pais idioma(String idioma) {
64 | this.idioma = idioma;
65 | return this;
66 | }
67 |
68 | public Pais moneda(String moneda) {
69 | this.moneda = moneda;
70 | return this;
71 | }
72 |
73 | public Pais capital(String capital) {
74 | this.capital = capital;
75 | return this;
76 | }
77 |
78 | public Pais presupuesto(double presupuesto) {
79 | this.presupuesto = presupuesto;
80 | return this;
81 | }
82 |
83 | public String toString(String separator) {
84 | return id + separator + nombre + separator + codigo + separator + idioma + separator + moneda + separator + capital + separator + presupuesto;
85 | }
86 | }
87 |
88 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/repositories/CRUDRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories;
2 |
3 | import java.sql.SQLException;
4 | import java.util.List;
5 | import java.util.Optional;
6 |
7 | public interface CRUDRepository {
8 | /**
9 | * Devuelve una lista de todos los elementos del repositorio
10 | *
11 | * @return Lista de elementos
12 | * @throws SQLException Si hay algún error en la base de datos
13 | */
14 | List findAll() throws SQLException;
15 |
16 | /**
17 | * Devuelve un Optional del elemento dada una id
18 | *
19 | * @param id Id del elemento
20 | * @return Optional del elemento
21 | * @throws SQLException Si hay algún error en la base de datos
22 | */
23 | Optional findById(ID id) throws SQLException;
24 |
25 | /**
26 | * Inserta un elemento en el repositorio
27 | *
28 | * @param entity Elemento a insertar
29 | * @return Elemento insertado
30 | * @throws SQLException Si hay algún error en la base de datos
31 | */
32 | Optional save(T entity) throws SQLException;
33 |
34 | /**
35 | * Actualiza un elemento en el repositorio
36 | *
37 | * @param id Id del elemento a actualizar
38 | * @param entity Elemento a actualizar
39 | * @return Elemento actualizado
40 | * @throws SQLException Si hay algún error en la base de datos
41 | */
42 | Optional update(ID id, T entity) throws SQLException;
43 |
44 | /**
45 | * Elimina un elemento del repositorio
46 | *
47 | * @param id Id del elemento a eliminar
48 | * @return Elemento eliminado
49 | * @throws SQLException Si hay algún error en la base de datos
50 | */
51 | Optional delete(ID id) throws SQLException;
52 | }
53 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/repositories/acuerdos/IAcuerdoRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories.acuerdos;
2 |
3 | import es.joseluisgs.dam.models.Acuerdo;
4 | import es.joseluisgs.dam.repositories.CRUDRepository;
5 |
6 | import java.sql.SQLException;
7 |
8 | public interface IAcuerdoRepository extends CRUDRepository {
9 |
10 | void clearAll() throws SQLException;
11 | }
12 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/repositories/paises/IPaisRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories.paises;
2 |
3 | import es.joseluisgs.dam.models.Pais;
4 | import es.joseluisgs.dam.repositories.CRUDRepository;
5 |
6 | import java.sql.SQLException;
7 | import java.util.Optional;
8 |
9 | // Toda nueva funcionalidad se extiende de la interfaz SOLID
10 | public interface IPaisRepository extends CRUDRepository {
11 |
12 | Optional findByNombre(String nombre) throws SQLException;
13 |
14 | void clearAll() throws SQLException;
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/services/Storage/IStorage.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services.Storage;
2 |
3 | public interface IStorage {
4 |
5 | /**
6 | * Salva los elementos almacenados en item.
7 | *
8 | * @param item Elementos a almacenar.
9 | * @return true si se ha almacenado correctamente, false en caso contrario.
10 | */
11 | boolean save(T item);
12 |
13 | /**
14 | * Le el almacenado y lo devuelve en un item T.
15 | *
16 | * @return Elementos almacenados.
17 | */
18 | T load();
19 |
20 | /**
21 | * Devuelve el path de la ubicación del almacenado.
22 | *
23 | * @return Path de la ubicación del almacenado.
24 | */
25 | String getStoragePath();
26 | }
27 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/services/Storage/IStorageBackup.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services.Storage;
2 |
3 | import es.joseluisgs.dam.models.Backup;
4 |
5 | public interface IStorageBackup extends IStorage {
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/services/Storage/StorageBackupJsonFile.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services.Storage;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.GsonBuilder;
5 | import com.google.gson.reflect.TypeToken;
6 | import es.joseluisgs.dam.models.Backup;
7 |
8 | import javax.inject.Inject;
9 | import java.io.*;
10 | import java.nio.file.Files;
11 | import java.nio.file.Path;
12 | import java.nio.file.Paths;
13 |
14 | public class StorageBackupJsonFile implements IStorageBackup {
15 |
16 | private final Path currentRelativePath = Paths.get("");
17 | private final String ruta = currentRelativePath.toAbsolutePath().toString();
18 | private final String dir = ruta + File.separator + "data";
19 | private final String backupFile = dir + File.separator + "backup.json";
20 |
21 | @Inject
22 | public StorageBackupJsonFile() {
23 | init();
24 | }
25 |
26 | private void init() {
27 | Path path = Paths.get(dir);
28 | if (!Files.exists(path)) {
29 | try {
30 | Files.createDirectories(path);
31 | } catch (IOException e) {
32 | System.out.println("Error: " + e.getMessage());
33 | }
34 | }
35 | }
36 |
37 | @Override
38 | public boolean save(Backup backup) {
39 | Gson gson = new GsonBuilder().setPrettyPrinting().create();
40 | boolean result = false;
41 | PrintWriter f = null;
42 | try {
43 | f = new PrintWriter(new FileWriter(backupFile));
44 | f.println(gson.toJson(backup));
45 | result = true;
46 |
47 | } catch (Exception e) {
48 | System.out.println("Error: " + e.getMessage());
49 | result = false;
50 | } finally {
51 | if (f != null) {
52 | f.close();
53 | }
54 | }
55 | return result;
56 | }
57 |
58 | @Override
59 | public Backup load() {
60 | Gson gson = new GsonBuilder().setPrettyPrinting().create();
61 | Backup backup = null;
62 | Reader reader = null;
63 | try {
64 | reader = Files.newBufferedReader(Paths.get(backupFile));
65 | backup = gson.fromJson(reader, new TypeToken() {
66 | }.getType());
67 | } catch (Exception e) {
68 | System.out.println("Error: " + e.getMessage());
69 | } finally {
70 | if (reader != null) {
71 | try {
72 | reader.close();
73 | } catch (IOException e) {
74 | System.out.println("Error: " + e.getMessage());
75 | }
76 | }
77 | }
78 | return backup;
79 | }
80 |
81 | @Override
82 | public String getStoragePath() {
83 | return backupFile;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/utils/ApplicationProperties.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import java.io.IOException;
4 | import java.util.Properties;
5 | import java.util.logging.Level;
6 | import java.util.logging.Logger;
7 |
8 | public class ApplicationProperties {
9 | private final Properties properties;
10 |
11 | public ApplicationProperties() {
12 | properties = new Properties();
13 | try {
14 | // De esta manera leemos desde el fichero de propiedades en resources
15 | properties.load(getClass().getClassLoader().getResourceAsStream("application.properties"));
16 |
17 | } catch (IOException ex) {
18 | System.err.println("IOException Ocurrido al leer el fichero de propiedades: " + ex.getMessage());
19 | Logger.getLogger(getClass().getName()).log(Level.ALL, "IOException Ocurrido al leer el fichero de propiedades: " + ex.getMessage());
20 | }
21 | }
22 |
23 | public String readProperty(String keyName) {
24 | // Logger.getLogger(getClass().getName()).log(Level.INFO, "Leyendo propiedad " + keyName);
25 | return properties.getProperty(keyName, "No existe esa clave en el fichero de propiedades");
26 | }
27 |
28 | }
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/utils/Console.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import java.util.Scanner;
4 |
5 | /**
6 | * Clase que permite leer datos desde la consola.
7 | */
8 | public class Console {
9 | public static String getString(String message) {
10 | System.out.println(message);
11 | return new Scanner(System.in).nextLine().trim();
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/java/es/joseluisgs/dam/utils/Formatter.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import java.text.NumberFormat;
4 | import java.time.LocalDateTime;
5 | import java.time.format.DateTimeFormatter;
6 | import java.time.format.FormatStyle;
7 | import java.util.Locale;
8 |
9 | public class Formatter {
10 |
11 | public static String dateParser(LocalDateTime date) {
12 | final Locale locale = new Locale("es", "ES");
13 | // private String pattern = "dd/MM/yyyy";
14 | return date.format(DateTimeFormatter
15 | .ofLocalizedDate(FormatStyle.MEDIUM).withLocale(locale));
16 | }
17 |
18 | public static String moneyParser(Double money) {
19 | final Locale locale = new Locale("es", "ES");
20 | return NumberFormat.getCurrencyInstance(locale).format(money);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joseluisgs/Programacion-09-2021-2022/188c0476c2f30e7149340dda33239a3df1488e4b/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/resources/application.properties
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/main/resources/sql/init-db.sql:
--------------------------------------------------------------------------------
1 | -- Adminer 4.8.1 MySQL 5.5.5-10.6.4-MariaDB dump
2 |
3 | SET NAMES utf8;
4 | SET
5 | time_zone = '+00:00';
6 | SET
7 | foreign_key_checks = 0;
8 | SET
9 | sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
10 |
11 | DROP
12 | DATABASE IF EXISTS `dam`;
13 | CREATE
14 | DATABASE `dam` /*!40100 DEFAULT CHARACTER SET utf8mb3 */;
15 | USE
16 | `dam`;
17 |
18 | DROP TABLE IF EXISTS `acuerdo`;
19 | CREATE TABLE `acuerdo`
20 | (
21 | `id` int(11) NOT NULL AUTO_INCREMENT,
22 | `nombre` varchar(100) NOT NULL,
23 | `fecha` datetime NOT NULL,
24 | `aportacion` double NOT NULL,
25 | PRIMARY KEY (`id`)
26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
27 |
28 | INSERT INTO `acuerdo` (`id`, `nombre`, `fecha`, `aportacion`)
29 | VALUES (1, 'Acuerdo Diplomático', '2022-03-25 20:59:57', 12345.89),
30 | (2, 'Acuerdo de Fronteras', '2022-03-25 21:01:40', 999.99);
31 |
32 | DROP TABLE IF EXISTS `linea_acuerdo`;
33 | CREATE TABLE `linea_acuerdo`
34 | (
35 | `id_acuerdo` int(11) NOT NULL,
36 | `id_pais` int(11) NOT NULL,
37 | `año` int(11) NOT NULL,
38 | `subvencion` double NOT NULL,
39 | KEY `id_acuerdo` (`id_acuerdo`),
40 | KEY `id_pais` (`id_pais`),
41 | CONSTRAINT `linea_acuerdo_ibfk_1` FOREIGN KEY (`id_acuerdo`) REFERENCES `acuerdo` (`id`) ON DELETE CASCADE
42 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
43 |
44 | INSERT INTO `linea_acuerdo` (`id_acuerdo`, `id_pais`, `año`, `subvencion`)
45 | VALUES (1, 1, 2022, 1234.56),
46 | (1, 2, 2022, 345.32),
47 | (2, 4, 2022, 450.8),
48 | (2, 7, 2022, 6666.66),
49 | (2, 2, 2022, 333.33);
50 |
51 | DROP TABLE IF EXISTS `pais`;
52 | CREATE TABLE `pais`
53 | (
54 | `id` int(11) NOT NULL AUTO_INCREMENT,
55 | `nombre` varchar(100) NOT NULL,
56 | `codigo` varchar(5) NOT NULL,
57 | `idioma` varchar(100) NOT NULL,
58 | `moneda` varchar(50) NOT NULL,
59 | `capital` varchar(100) NOT NULL,
60 | `presupuesto` double DEFAULT NULL,
61 | PRIMARY KEY (`id`)
62 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
63 |
64 | INSERT INTO `pais` (`id`, `nombre`, `codigo`, `idioma`, `moneda`, `capital`, `presupuesto`)
65 | VALUES (1, 'España', 'ES', 'Español', 'Euro', 'Madrid', 1234567.23),
66 | (2, 'Francia', 'FR', 'Francés', 'Euro', 'París', 123456.67),
67 | (3, 'Italia', 'IT', 'Italiano', 'Euro', 'Roma', 564568.34),
68 | (4, 'Alemania', 'DE', 'Alemán', 'Euro', 'Berlín', 234567.23),
69 | (5, 'Reino Unido', 'UK', 'Inglés', 'Libra', 'Londres', 232323.34),
70 | (6, 'Japón', 'JP', 'Jsaponés', 'Yen', 'Tokio', 21212.12),
71 | (7, 'China', 'CN', 'Chino', 'Yuan', 'Pekín', 121212.34),
72 | (8, 'Australia', 'AU', 'Inglés', 'Dólar', 'Canberra', 567654.23),
73 | (9, 'Argentina', 'AR', 'Español', 'Peso', 'Buenos Aires', 123456.34),
74 | (10, 'Brasil', 'BR', 'Portugués', 'Real', 'Brasilia', 251251.62),
75 | (11, 'Estados Unidos', 'US', 'Inglés', 'Dólar', 'Washington', 1212415.98);
76 |
77 | -- 2022-03-26 11:15:34
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/test/java/es/joseluisgs/dam/MainTest.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam;
2 |
3 | import org.junit.jupiter.api.Test;
4 |
5 | import static org.junit.jupiter.api.Assertions.assertTrue;
6 |
7 | class MainTest {
8 |
9 | @Test
10 | public void trueIsTrue() {
11 | assertTrue(true);
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/test/java/es/joseluisgs/dam/utilities/DataBase.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utilities;
2 |
3 | import es.joseluisgs.dam.Main;
4 | import es.joseluisgs.dam.controllers.DataBaseManager;
5 | import es.joseluisgs.dam.utils.ApplicationProperties;
6 |
7 | import java.io.File;
8 | import java.io.FileNotFoundException;
9 | import java.sql.SQLException;
10 |
11 | public class DataBase {
12 |
13 | /**
14 | * Inicia la base de datos con los datos de prueba si los hay, o la estructura de la tabla...
15 | */
16 | public static void init() {
17 | ApplicationProperties properties = new ApplicationProperties();
18 | boolean init = Boolean.parseBoolean(properties.readProperty("database.initdata"));
19 | if (init) {
20 | DataBaseManager controller = DataBaseManager.getInstance();
21 | String dataPath = "sql" + File.separator + "init-db.sql";
22 | try {
23 | var sqlFile = Main.class.getClassLoader().getResource(dataPath).getPath();
24 | controller.open();
25 | controller.initData(sqlFile, false);
26 | controller.close();
27 | } catch (SQLException e) {
28 | System.err.println("Error al conectar al servidor de Base de Datos: " + e.getMessage());
29 | System.exit(1);
30 | } catch (FileNotFoundException e) {
31 | System.err.println("Error al leer el fichero de datos iniciales: " + e.getMessage());
32 | System.exit(1);
33 | }
34 | }
35 | }
36 |
37 | /**
38 | * Borra todas las tablas, que cuesta menos que tirar toda la base de datos y levantarla de nuevo
39 | *
40 | * @throws SQLException
41 | */
42 | public static void deleteAll() throws SQLException {
43 | DataBaseManager db = DataBaseManager.getInstance();
44 | String query = "DELETE FROM pais";
45 | db.open();
46 | db.delete(query);
47 | query = "DELETE FROM acuerdo";
48 | db.beginTransaction();
49 | db.delete(query);
50 | query = "DELETE FROM linea_acuerdo";
51 | db.delete(query);
52 | db.commit();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/test/java/es/joseluisgs/dam/utilities/DataDB.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utilities;
2 |
3 | import es.joseluisgs.dam.controllers.DataBaseManager;
4 | import es.joseluisgs.dam.models.Acuerdo;
5 | import es.joseluisgs.dam.models.LineaAcuerdo;
6 | import es.joseluisgs.dam.models.Pais;
7 |
8 | import java.sql.ResultSet;
9 | import java.sql.SQLException;
10 | import java.util.Optional;
11 |
12 | public class DataDB {
13 | // Insertamos un dato de prueba, aquí vemos un acoplamiento...
14 | // Si no quiseramos esto, podríamos usar Order de test
15 | // Lo ideal es meterlo en el script, e iniciarlo cada vez...
16 | public static void insertPaisTest(Pais paisTest) throws SQLException {
17 | String query = "INSERT INTO pais VALUES (null, ?, ?, ?, ?, ?, ?)";
18 | DataBaseManager db = DataBaseManager.getInstance();
19 | db.open();
20 | Optional res = db.insert(query, paisTest.getNombre(), paisTest.getCodigo(), paisTest.getIdioma(), paisTest.getMoneda(),
21 | paisTest.getCapital(), paisTest.getPresupuesto());
22 | if (res.get().first()) {
23 | paisTest.setId(res.get().getInt(1));
24 | }
25 | db.close();
26 | }
27 |
28 | public static void insertAcuerdoTest(Acuerdo acuerdoTest) throws SQLException {
29 | // OJO pongo null en el primer parámetro porque no inserto el ID, este se genera automático. Mira el DBMAnager
30 | String query = "INSERT INTO acuerdo VALUES (null, ?, ?, ?)";
31 | DataBaseManager db = DataBaseManager.getInstance();
32 | // Es una transacción, por lo que si falla alguna de las dos, se cancela todo
33 | db.open();
34 | db.beginTransaction();
35 | ResultSet res = db.insert(query, acuerdoTest.getNombre(), acuerdoTest.getFecha(), acuerdoTest.getAportacion())
36 | .orElseThrow(() -> new SQLException("Error al insertar acuerdo"));
37 |
38 | // Para obtener su ID que ha generado la BD
39 | if (res.first()) {
40 | acuerdoTest.setId(res.getInt(1));
41 | // Ahora salvamos toda las lineas de acuerdo...
42 | for (LineaAcuerdo linea : acuerdoTest.getLineas()) {
43 | query = "INSERT INTO linea_acuerdo VALUES (?, ?, ?, ?)";
44 | db.insert(query, acuerdoTest.getId(), linea.getPais().getId(), linea.getAño(), linea.getSubvencion())
45 | .orElseThrow(() -> new SQLException("Error al insertar linea de acuerdo"));
46 | }
47 |
48 | // Y finalmente cerramos la conexión y devolvemos el acuerdo
49 | db.commit();
50 | db.close();
51 | }
52 | db.rollback();
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/test/resources/application.properties:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joseluisgs/Programacion-09-2021-2022/188c0476c2f30e7149340dda33239a3df1488e4b/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/test/resources/application.properties
--------------------------------------------------------------------------------
/Soluciones/10-MVC-Paises-BBDD-Dagger-Lombok/src/test/resources/sql/init-db.sql:
--------------------------------------------------------------------------------
1 | -- Adminer 4.8.1 MySQL 5.5.5-10.6.4-MariaDB dump
2 |
3 | SET NAMES utf8;
4 | SET
5 | time_zone = '+00:00';
6 | SET
7 | foreign_key_checks = 0;
8 | SET
9 | sql_mode = 'NO_AUTO_VALUE_ON_ZERO';
10 |
11 | DROP
12 | DATABASE IF EXISTS `dam`;
13 | CREATE
14 | DATABASE `dam` /*!40100 DEFAULT CHARACTER SET utf8mb3 */;
15 | USE
16 | `dam`;
17 |
18 | DROP TABLE IF EXISTS `acuerdo`;
19 | CREATE TABLE `acuerdo`
20 | (
21 | `id` int(11) NOT NULL AUTO_INCREMENT,
22 | `nombre` varchar(100) NOT NULL,
23 | `fecha` datetime NOT NULL,
24 | `aportacion` double NOT NULL,
25 | PRIMARY KEY (`id`)
26 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
27 |
28 |
29 | DROP TABLE IF EXISTS `linea_acuerdo`;
30 | CREATE TABLE `linea_acuerdo`
31 | (
32 | `id_acuerdo` int(11) NOT NULL,
33 | `id_pais` int(11) NOT NULL,
34 | `año` int(11) NOT NULL,
35 | `subvencion` double NOT NULL,
36 | KEY `id_acuerdo` (`id_acuerdo`),
37 | KEY `id_pais` (`id_pais`),
38 | CONSTRAINT `linea_acuerdo_ibfk_1` FOREIGN KEY (`id_acuerdo`) REFERENCES `acuerdo` (`id`) ON DELETE CASCADE
39 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
40 |
41 | DROP TABLE IF EXISTS `pais`;
42 | CREATE TABLE `pais`
43 | (
44 | `id` int(11) NOT NULL AUTO_INCREMENT,
45 | `nombre` varchar(100) NOT NULL,
46 | `codigo` varchar(5) NOT NULL,
47 | `idioma` varchar(100) NOT NULL,
48 | `moneda` varchar(50) NOT NULL,
49 | `capital` varchar(100) NOT NULL,
50 | `presupuesto` double DEFAULT NULL,
51 | PRIMARY KEY (`id`)
52 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;
53 |
54 | -- 2022-03-26 11:15:34
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/.gitignore:
--------------------------------------------------------------------------------
1 | target/
2 | !.mvn/wrapper/maven-wrapper.jar
3 | !**/src/main/**/target/
4 | !**/src/test/**/target/
5 |
6 | ### IntelliJ IDEA ###
7 | .idea/modules.xml
8 | .idea/jarRepositories.xml
9 | .idea/compiler.xml
10 | .idea/libraries/
11 | *.iws
12 | *.iml
13 | *.ipr
14 |
15 | ### Eclipse ###
16 | .apt_generated
17 | .classpath
18 | .factorypath
19 | .project
20 | .settings
21 | .springBeans
22 | .sts4-cache
23 |
24 | ### NetBeans ###
25 | /nbproject/private/
26 | /nbbuild/
27 | /dist/
28 | /nbdist/
29 | /.nb-gradle/
30 | build/
31 | !**/src/main/**/build/
32 | !**/src/test/**/build/
33 |
34 | ### VS Code ###
35 | .vscode/
36 |
37 | ### Mac OS ###
38 | .DS_Storedata/
39 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/.idea/dataSources.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | sqlite.xerial
6 | true
7 | org.sqlite.JDBC
8 | jdbc:sqlite:$PROJECT_DIR$/db/personas.db
9 | $ProjectFileDir$
10 |
11 |
12 | file://$APPLICATION_CONFIG_DIR$/jdbc-drivers/Xerial SQLiteJDBC/3.36.0.3/sqlite-jdbc-3.36.0.3.jar
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/.idea/deployment.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/data/personas.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": 93,
4 | "uuid": "c5833b1f-808e-4fad-9971-553035418e1a",
5 | "nombre": "Pepito Update",
6 | "edad": 31,
7 | "createdAt": "2022-04-22"
8 | },
9 | {
10 | "id": 95,
11 | "uuid": "e75e379e-64d1-4623-90f3-dc7dccadebfd",
12 | "nombre": "Anita",
13 | "edad": 25,
14 | "createdAt": "2022-04-22"
15 | }
16 | ]
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/db/personas.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joseluisgs/Programacion-09-2021-2022/188c0476c2f30e7149340dda33239a3df1488e4b/Soluciones/11-CRUD-SQLite-GSon/db/personas.db
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | es.joseluisgs.dam
8 | CRUDSQlite
9 | 1.0-SNAPSHOT
10 |
11 |
12 | 17
13 | 17
14 |
15 |
16 |
17 |
18 | org.xerial
19 | sqlite-jdbc
20 | 3.36.0.3
21 |
22 |
23 |
24 | org.projectlombok
25 | lombok
26 | 1.18.22
27 | compile
28 |
29 |
30 |
31 | org.mybatis
32 | mybatis
33 | 3.5.9
34 |
35 |
36 |
37 | org.projectlombok
38 | lombok
39 | 1.18.22
40 | compile
41 |
42 |
43 |
44 | com.google.code.gson
45 | gson
46 | 2.9.0
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/src/main/java/es/joseluisgs/dam/controllers/PersonasController.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.controllers;
2 |
3 | import es.joseluisgs.dam.models.Persona;
4 | import es.joseluisgs.dam.repositories.IPersonasRepository;
5 |
6 | import java.io.IOException;
7 | import java.sql.SQLException;
8 | import java.util.List;
9 |
10 | public class PersonasController {
11 | private final IPersonasRepository personasRepository;
12 |
13 | public PersonasController(IPersonasRepository personasRepository) {
14 | this.personasRepository = personasRepository;
15 | }
16 |
17 | public Persona savePersona(Persona persona) {
18 | try {
19 | return personasRepository.save(persona);
20 | } catch (SQLException e) {
21 | System.err.println("Error al guardar persona: " + e.getMessage());
22 | }
23 | return null;
24 | }
25 |
26 | public void deleteAll() {
27 | try {
28 | personasRepository.deleteAll();
29 | } catch (SQLException e) {
30 | System.err.println("Error al borrar todas las personas: " + e.getMessage());
31 | }
32 | }
33 |
34 | public List findAll() {
35 | try {
36 | return personasRepository.findAll();
37 | } catch (SQLException e) {
38 | System.err.println("Error al buscar todas las personas: " + e.getMessage());
39 | }
40 | return null;
41 | }
42 |
43 | public Persona update(Persona persona) {
44 | try {
45 | return personasRepository.update(persona.getId(), persona);
46 | } catch (SQLException e) {
47 | System.err.println("Error al actualizar persona: " + e.getMessage());
48 | }
49 | return null;
50 | }
51 |
52 | public Persona findById(int id) {
53 | try {
54 | return personasRepository.findById(id).orElseThrow(() -> new RuntimeException("No existe la persona con id " + id));
55 | } catch (SQLException e) {
56 | System.err.println("Error al buscar persona: " + e.getMessage());
57 | }
58 | return null;
59 | }
60 |
61 | public Persona delete(Persona persona) {
62 | try {
63 | return personasRepository.delete(persona.getId());
64 | } catch (SQLException e) {
65 | System.err.println("Error al borrar persona: " + e.getMessage());
66 | }
67 | return null;
68 | }
69 |
70 | public void backup() {
71 | try {
72 | personasRepository.backup();
73 | } catch (IOException | SQLException e) {
74 | System.err.println("Error al hacer backup: " + e.getMessage());
75 | }
76 | }
77 |
78 | public void restore() {
79 | try {
80 | personasRepository.restore();
81 | } catch (IOException | SQLException e) {
82 | System.err.println("Error al hacer restore: " + e.getMessage());
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/src/main/java/es/joseluisgs/dam/models/Persona.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.models;
2 |
3 | import lombok.Builder;
4 | import lombok.Data;
5 |
6 | import java.time.LocalDate;
7 | import java.util.UUID;
8 |
9 | /**
10 | * Mi consejo es que a partir de poco uses UUIDs para identificar a las personas.
11 | * y no claves autonumericas, pronto lo entenderás
12 | */
13 | @Data
14 | @Builder
15 | public class Persona {
16 | private int id;
17 | private UUID uuid;
18 | private String nombre;
19 | private int edad;
20 | private LocalDate createdAt;
21 | }
22 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/src/main/java/es/joseluisgs/dam/repositories/CRUDRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories;
2 |
3 | import java.sql.SQLException;
4 | import java.util.List;
5 | import java.util.Optional;
6 |
7 | public interface CRUDRepository {
8 | /**
9 | * Devuelve una lista de todos los elementos del repositorio
10 | *
11 | * @return Lista de elementos
12 | * @throws SQLException Si hay algún error en la base de datos
13 | */
14 | List findAll() throws SQLException;
15 |
16 | /**
17 | * Devuelve un Optional del elemento dada una id
18 | *
19 | * @param id Id del elemento
20 | * @return Optional del elemento
21 | * @throws SQLException Si hay algún error en la base de datos
22 | */
23 | Optional findById(ID id) throws SQLException;
24 |
25 | /**
26 | * Inserta un elemento en el repositorio
27 | *
28 | * @param entity Elemento a insertar
29 | * @return Elemento insertado
30 | * @throws SQLException Si hay algún error en la base de datos
31 | */
32 | T save(T entity) throws SQLException;
33 |
34 | /**
35 | * Actualiza un elemento en el repositorio
36 | *
37 | * @param id Id del elemento a actualizar
38 | * @param entity Elemento a actualizar
39 | * @return Elemento actualizado
40 | * @throws SQLException Si hay algún error en la base de datos
41 | */
42 | T update(ID id, T entity) throws SQLException;
43 |
44 | /**
45 | * Elimina un elemento del repositorio
46 | *
47 | * @param id Id del elemento a eliminar
48 | * @return Elemento eliminado
49 | * @throws SQLException Si hay algún error en la base de datos
50 | */
51 | T delete(ID id) throws SQLException;
52 | }
53 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/src/main/java/es/joseluisgs/dam/repositories/IPersonasRepository.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.repositories;
2 |
3 | import es.joseluisgs.dam.models.Persona;
4 |
5 | import java.io.IOException;
6 | import java.sql.SQLException;
7 |
8 | public interface IPersonasRepository extends CRUDRepository {
9 | void deleteAll() throws SQLException;
10 |
11 | void backup() throws SQLException, IOException;
12 |
13 | void restore() throws SQLException, IOException;
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/src/main/java/es/joseluisgs/dam/services/Backup.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services;
2 |
3 | import java.io.IOException;
4 | import java.util.List;
5 |
6 | public interface Backup {
7 | void backup(List data) throws IOException;
8 |
9 | List restore() throws IOException;
10 | }
11 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/src/main/java/es/joseluisgs/dam/services/BackupJSON.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services;
2 |
3 | import com.google.gson.Gson;
4 | import com.google.gson.GsonBuilder;
5 | import com.google.gson.reflect.TypeToken;
6 | import es.joseluisgs.dam.models.Persona;
7 | import es.joseluisgs.dam.utils.LocalDateAdapter;
8 |
9 | import java.io.File;
10 | import java.io.IOException;
11 | import java.nio.file.Files;
12 | import java.time.LocalDate;
13 | import java.util.List;
14 |
15 | public class BackupJSON implements IBackupJSON {
16 | private static BackupJSON instance;
17 | private final String APP_PATH = System.getProperty("user.dir");
18 | private final String DATA_DIR = APP_PATH + File.separator + "data";
19 | private final String BACKUP_FILE = DATA_DIR + File.separator + "personas.json";
20 |
21 | private BackupJSON() {
22 | File dataDir = new File(DATA_DIR);
23 | if (!dataDir.exists()) {
24 | dataDir.mkdir();
25 | }
26 | }
27 |
28 |
29 | public static BackupJSON getInstance() {
30 | if (instance == null) {
31 | instance = new BackupJSON();
32 | }
33 | return instance;
34 | }
35 |
36 |
37 | @Override
38 | public void backup(List personas) throws IOException {
39 | Gson gson = new GsonBuilder()
40 | .registerTypeAdapter(LocalDate.class, new LocalDateAdapter())
41 | .setPrettyPrinting()
42 | .create();
43 | String json = gson.toJson(personas);
44 | Files.writeString(new File(BACKUP_FILE).toPath(), json);
45 | }
46 |
47 |
48 | @Override
49 | public List restore() throws IOException {
50 | Gson gson = new GsonBuilder()
51 | .registerTypeAdapter(LocalDate.class, new LocalDateAdapter())
52 | .create();
53 | String json = "";
54 | json = Files.readString(new File(BACKUP_FILE).toPath());
55 | return gson.fromJson(json, new TypeToken>() {
56 | }.getType());
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/src/main/java/es/joseluisgs/dam/services/IBackupJSON.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.services;
2 |
3 | import es.joseluisgs.dam.models.Persona;
4 |
5 | public interface IBackupJSON extends Backup {
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/Soluciones/11-CRUD-SQLite-GSon/src/main/java/es/joseluisgs/dam/utils/LocalDateAdapter.java:
--------------------------------------------------------------------------------
1 | package es.joseluisgs.dam.utils;
2 |
3 | import com.google.gson.TypeAdapter;
4 | import com.google.gson.stream.JsonReader;
5 | import com.google.gson.stream.JsonWriter;
6 |
7 | import java.io.IOException;
8 | import java.time.LocalDate;
9 |
10 | // Esto es porque GSON no se pensó para Java 11 hacia arriba, mejor usar Jackson o Moshi
11 | // Tiene problemas con las fechas LocalDate y LocalDateTime
12 | public class LocalDateAdapter extends TypeAdapter {
13 |
14 | @Override
15 | public LocalDate read(final JsonReader jsonReader) throws IOException {
16 | return LocalDate.parse(jsonReader.nextString());
17 | }
18 |
19 | @Override
20 | public void write(JsonWriter jsonWriter, LocalDate localDate) throws IOException {
21 | jsonWriter.value(localDate.toString());
22 |
23 | }
24 | }
--------------------------------------------------------------------------------
/UD09.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/joseluisgs/Programacion-09-2021-2022/188c0476c2f30e7149340dda33239a3df1488e4b/UD09.pdf
--------------------------------------------------------------------------------