diff --git a/L28-springDataJdbc/build.gradle.kts b/L28-springDataJdbc/build.gradle.kts new file mode 100644 index 0000000..9daff46 --- /dev/null +++ b/L28-springDataJdbc/build.gradle.kts @@ -0,0 +1,25 @@ +plugins { + id ("org.springframework.boot") +} + + +dependencies { + dependencies { + implementation ("ch.qos.logback:logback-classic") + implementation ("org.flywaydb:flyway-core") + implementation ("org.postgresql:postgresql") + implementation ("com.google.code.findbugs:jsr305") + implementation ("org.springframework.boot:spring-boot-starter-data-jdbc") + implementation("org.postgresql:postgresql") + + implementation("org.springframework.boot:spring-boot-starter-web") + implementation("org.springframework.boot:spring-boot-starter-thymeleaf") + implementation("org.springframework.boot:spring-boot-starter-data-jdbc") + implementation("org.flywaydb:flyway-core") + + runtimeOnly("org.flywaydb:flyway-database-postgresql") + + compileOnly ("org.projectlombok:lombok") + annotationProcessor ("org.projectlombok:lombok") + } +} diff --git a/L28-springDataJdbc/docker/runDb.sh b/L28-springDataJdbc/docker/runDb.sh new file mode 100755 index 0000000..f2c3084 --- /dev/null +++ b/L28-springDataJdbc/docker/runDb.sh @@ -0,0 +1,6 @@ +docker run --rm --name pg-docker \ +-e POSTGRES_PASSWORD=pwd \ +-e POSTGRES_USER=usr \ +-e POSTGRES_DB=demoDB \ +-p 5430:5432 \ +postgres:17 \ No newline at end of file diff --git a/L28-springDataJdbc/src/main/java/ru/otus/AppRunner.java b/L28-springDataJdbc/src/main/java/ru/otus/AppRunner.java new file mode 100644 index 0000000..57f0996 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/AppRunner.java @@ -0,0 +1,53 @@ +package ru.otus; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; +import ru.otus.model.Address; +import ru.otus.model.Client; +import ru.otus.model.Phone; +import ru.otus.model.User; +import ru.otus.repository.AddressRepository; +import ru.otus.repository.ClientRepository; +import ru.otus.repository.PhoneRepository; +import ru.otus.repository.UserRepository; + +@Component("actionDemo") +public class AppRunner implements CommandLineRunner { + private static final Logger log = LoggerFactory.getLogger(AppRunner.class); + + private final ClientRepository clientRepository; + private final AddressRepository addressRepository; + private final PhoneRepository phoneRepository; + private final UserRepository userRepository; + + public AppRunner( + UserRepository userRepository, + ClientRepository clientRepository, + AddressRepository addressRepository, + PhoneRepository phoneRepository) { + this.clientRepository = clientRepository; + this.addressRepository = addressRepository; + this.phoneRepository = phoneRepository; + this.userRepository = userRepository; + } + + @Override + public void run(String... args) { + + Client client = new Client("Иван"); + + Address address = new Address("ул. Ленина"); + client.setAddress(address); + + client.addPhone(new Phone("+7-900-111-22-33")); + client.addPhone(new Phone("+7-900-444-55-66")); + + clientRepository.save(client); + addressRepository.save(address); + + userRepository.save(new User("Пользователь", "user", "user")); + userRepository.save(new User("Administrator", "admin", "admin")); + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/DbServiceDemo.java b/L28-springDataJdbc/src/main/java/ru/otus/DbServiceDemo.java new file mode 100644 index 0000000..76f26c4 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/DbServiceDemo.java @@ -0,0 +1,23 @@ +package ru.otus; + +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; + +/* + Полезные для демо ссылки + + // Стартовая страница + http://localhost:8080 + + // Страница пользователей + http://localhost:8080/users + + // REST сервис + http://localhost:8080/api/user/3 +*/ +@SpringBootApplication +public class DbServiceDemo { + public static void main(String[] args) { + SpringApplication.run(DbServiceDemo.class, args); + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/controller/ClientsController.java b/L28-springDataJdbc/src/main/java/ru/otus/controller/ClientsController.java new file mode 100644 index 0000000..c3e375b --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/controller/ClientsController.java @@ -0,0 +1,27 @@ +package ru.otus.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import ru.otus.model.Client; +import ru.otus.repository.ClientRepository; + +@Controller +public class ClientsController { + + private final ClientRepository clientRepository; + + @Autowired + public ClientsController(ClientRepository clientRepository) { + this.clientRepository = clientRepository; + } + + @GetMapping("/clients") + public String clients(Model model) { + Iterable clients = clientRepository.findAll(); + model.addAttribute("clients", clients); + + return "clients"; + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/controller/ClientsRestController.java b/L28-springDataJdbc/src/main/java/ru/otus/controller/ClientsRestController.java new file mode 100644 index 0000000..a6c1138 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/controller/ClientsRestController.java @@ -0,0 +1,124 @@ +package ru.otus.controller; + +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ru.otus.model.Address; +import ru.otus.model.Client; +import ru.otus.model.Phone; +import ru.otus.model.RequestAddPhone; +import ru.otus.model.RequestCreateClient; +import ru.otus.model.RequestEditClient; +import ru.otus.repository.AddressRepository; +import ru.otus.repository.ClientRepository; +import ru.otus.repository.PhoneRepository; + +@RestController +@RequestMapping("/api/clients") +public class ClientsRestController { + private final ClientRepository clientRepository; + private final AddressRepository addressRepository; + private final PhoneRepository phoneRepository; + + @Autowired + public ClientsRestController( + ClientRepository clientRepository, AddressRepository addressRepository, PhoneRepository phoneRepository) { + this.clientRepository = clientRepository; + this.addressRepository = addressRepository; + this.phoneRepository = phoneRepository; + } + + @PostMapping + public ResponseEntity createClient(@RequestBody RequestCreateClient request) { + if (request.getName() == null || request.getName().trim().isEmpty()) { + JsonResponse error = new JsonResponse("Invalid input", "Client name cannot be empty"); + return ResponseEntity.status(400).body(error); // 400 Bad Request + } + + Address address = new Address(request.getAddress()); + Client client = new Client(request.getName()); + client.setAddress(address); + client.addPhone(new Phone(request.getNumber())); + var savedClient = clientRepository.save(client); + addressRepository.save(address); + + return ResponseEntity.status(201).body(savedClient); + } + + @DeleteMapping("/{clientId}/phone/{phoneId}") + public ResponseEntity deletePhone(@PathVariable Long clientId, @PathVariable Long phoneId) { + Optional client = clientRepository.findById(clientId); + if (client.isEmpty()) { + JsonResponse error = new JsonResponse("Invalid input", "Client not found"); + return ResponseEntity.status(404).body(error); + } + + phoneRepository.deleteById(phoneId); + return ResponseEntity.status(200).body(new JsonResponse("Phone deleted", "Phone Deleted")); + } + + @PostMapping("/{clientId}/phone") + public ResponseEntity addPhone(@PathVariable Long clientId, @RequestBody RequestAddPhone request) { + Optional client = clientRepository.findById(clientId); + if (client.isEmpty()) { + JsonResponse error = new JsonResponse("Invalid input", "Client not found"); + return ResponseEntity.status(404).body(error); + } + + if (request.getNumber() == null || request.getNumber().trim().isEmpty()) { + return ResponseEntity.status(400).body(new JsonResponse("Invalid input", "Phone number cannot be empty")); + } + + Phone phone = new Phone(request.getNumber(), clientId); + + Phone savedPhone = phoneRepository.save(phone); + return ResponseEntity.status(201).body(savedPhone); + } + + @DeleteMapping("/{clientId}") + public ResponseEntity deleteClient(@PathVariable Long clientId) { + Optional client = clientRepository.findById(clientId); + if (client.isEmpty()) { + JsonResponse error = new JsonResponse("Invalid input", "Client not found"); + return ResponseEntity.status(404).body(error); + } + + clientRepository.deleteById(clientId); + return ResponseEntity.status(201).body(new JsonResponse("Client deleted", "Client Deleted")); + } + + @PutMapping("/{clientId}/{field}") + public ResponseEntity editClient( + @PathVariable Long clientId, @PathVariable String field, @RequestBody RequestEditClient request) { + Optional clientOpt = clientRepository.findById(clientId); + if (clientOpt.isEmpty()) { + JsonResponse error = new JsonResponse("Invalid input", "Client not found"); + return ResponseEntity.status(404).body(error); + } + + Client client = clientOpt.get(); + + if (field.equals("name")) { + client.setName(request.getValue()); + clientRepository.save(client); + return ResponseEntity.status(201).body(new JsonResponse("Client name updated", "Client name updated")); + } + + if (field.equals("address")) { + Optional
addressOpt = + addressRepository.findById(client.getAddress().getId()); + if (addressOpt.isEmpty()) { + return ResponseEntity.status(404) + .body(new JsonResponse( + "Address not found", + "Address with ID: " + client.getAddress().getId() + " not found")); + } + Address address = addressOpt.get(); + address.setAddress(request.getValue()); + Address updatedAddress = addressRepository.save(address); + return ResponseEntity.status(201).body(new JsonResponse("Address updated", "Address updated")); + } + return ResponseEntity.status(400).body(new JsonResponse("bad Request", "Bad request")); + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/controller/JsonResponse.java b/L28-springDataJdbc/src/main/java/ru/otus/controller/JsonResponse.java new file mode 100644 index 0000000..f2e0e47 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/controller/JsonResponse.java @@ -0,0 +1,19 @@ +package ru.otus.controller; + +public class JsonResponse { + private String message; + private String details; + + public JsonResponse(String message, String details) { + this.message = message; + this.details = details; + } + + public String getMessage() { + return message; + } + + public String getDetails() { + return details; + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/controller/UsersController.java b/L28-springDataJdbc/src/main/java/ru/otus/controller/UsersController.java new file mode 100644 index 0000000..bc3b663 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/controller/UsersController.java @@ -0,0 +1,29 @@ +package ru.otus.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import ru.otus.model.User; +import ru.otus.repository.UserRepository; + +@Controller +public class UsersController { + + private final UserRepository userRepository; + + @Autowired + public UsersController(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @GetMapping("/users") + public String users(Model model) { + Iterable users = userRepository.findAll(); + model.addAttribute("users", users); + + model.addAttribute("message", "helloWorld"); + + return "users"; + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/controller/UsersRestController.java b/L28-springDataJdbc/src/main/java/ru/otus/controller/UsersRestController.java new file mode 100644 index 0000000..1bc29c7 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/controller/UsersRestController.java @@ -0,0 +1,48 @@ +package ru.otus.controller; + +import java.util.Optional; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import ru.otus.model.RequestCreateUser; +import ru.otus.model.User; +import ru.otus.repository.UserRepository; + +@RestController +@RequestMapping("/api/users") +public class UsersRestController { + + private final UserRepository userRepository; + + @Autowired + public UsersRestController(UserRepository userRepository) { + this.userRepository = userRepository; + } + + @GetMapping("/{id}") + public ResponseEntity getUserById(@PathVariable Long id) { + Optional user = userRepository.findById(id); + if (user.isEmpty()) { + JsonResponse error = new JsonResponse("User not found", "No user exists with ID: " + id); + return ResponseEntity.status(404).body(error); + } + + return ResponseEntity.ok(user.orElse(null)); + } + + @PostMapping + public ResponseEntity createUser(@RequestBody RequestCreateUser request) { + if (request.getName() == null || request.getName().trim().isEmpty()) { + JsonResponse error = new JsonResponse("Invalid input", "User name cannot be empty"); + return ResponseEntity.status(400).body(error); // 400 Bad Request + } + + User user = new User(); + user.setName(request.getName()); + user.setLogin(request.getLogin()); + user.setPassword(request.getPassword()); + User savedUser = userRepository.save(user); + + return ResponseEntity.status(201).body(savedUser); + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/model/Address.java b/L28-springDataJdbc/src/main/java/ru/otus/model/Address.java new file mode 100644 index 0000000..431a2ee --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/model/Address.java @@ -0,0 +1,25 @@ +package ru.otus.model; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +@Getter +@Setter +@NoArgsConstructor +@Table("addresses") +public class Address { + @Id + @Column("id") + private Long id; + + @Column("address") + private String address; + + public Address(String address) { + this.address = address; + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/model/Client.java b/L28-springDataJdbc/src/main/java/ru/otus/model/Client.java new file mode 100644 index 0000000..b6510b1 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/model/Client.java @@ -0,0 +1,38 @@ +package ru.otus.model; + +import java.util.HashSet; +import java.util.Set; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.MappedCollection; +import org.springframework.data.relational.core.mapping.Table; + +@Getter +@Setter +@NoArgsConstructor +@Table("clients") +public class Client { + @Id + @Column("id") + private Long id; + + @Column("name") + private String name; + + @Column("client_id") + private Address address; + + @MappedCollection(idColumn = "client_id") + private Set phones = new HashSet<>(); + + public Client(String name) { + this.name = name; + } + + public void addPhone(Phone phone) { + this.phones.add(phone); + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/model/Phone.java b/L28-springDataJdbc/src/main/java/ru/otus/model/Phone.java new file mode 100644 index 0000000..2c8498c --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/model/Phone.java @@ -0,0 +1,33 @@ +package ru.otus.model; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +@Getter +@Setter +@NoArgsConstructor +@Table("phones") +public class Phone { + @Id + @Column("id") + private Long id; + + @Column("number") + private String number; + + @Column("client_id") + private Long clientId; // Внешний ключ на Client + + public Phone(String number) { + this.number = number; + } + + public Phone(String number, Long clientId) { + this.number = number; + this.clientId = clientId; + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/model/RequestAddPhone.java b/L28-springDataJdbc/src/main/java/ru/otus/model/RequestAddPhone.java new file mode 100644 index 0000000..4eeb7c3 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/model/RequestAddPhone.java @@ -0,0 +1,12 @@ +package ru.otus.model; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class RequestAddPhone { + private String number; +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/model/RequestCreateClient.java b/L28-springDataJdbc/src/main/java/ru/otus/model/RequestCreateClient.java new file mode 100644 index 0000000..f9cf7a3 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/model/RequestCreateClient.java @@ -0,0 +1,14 @@ +package ru.otus.model; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class RequestCreateClient { + private String name; + private String address; + private String number; +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/model/RequestCreateUser.java b/L28-springDataJdbc/src/main/java/ru/otus/model/RequestCreateUser.java new file mode 100644 index 0000000..fe9bbfc --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/model/RequestCreateUser.java @@ -0,0 +1,14 @@ +package ru.otus.model; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class RequestCreateUser { + private String name; + private String login; + private String password; +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/model/RequestEditClient.java b/L28-springDataJdbc/src/main/java/ru/otus/model/RequestEditClient.java new file mode 100644 index 0000000..d7c5eda --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/model/RequestEditClient.java @@ -0,0 +1,12 @@ +package ru.otus.model; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +@Getter +@Setter +@NoArgsConstructor +public class RequestEditClient { + private String value; +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/model/User.java b/L28-springDataJdbc/src/main/java/ru/otus/model/User.java new file mode 100644 index 0000000..1c5f6d5 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/model/User.java @@ -0,0 +1,35 @@ +package ru.otus.model; + +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.annotation.Id; +import org.springframework.data.relational.core.mapping.Column; +import org.springframework.data.relational.core.mapping.Table; + +@Getter +@Setter +@NoArgsConstructor +@Table("users") +public class User { + + @Id + @Column("id") + private Long id; + + @Column("name") + private String name; + + @Column("login") + private String login; + + @Column("password") + private String password; + + public User(String name, String login, String password) { + // this.id = null; + this.name = name; + this.login = login; + this.password = password; + } +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/repository/AddressRepository.java b/L28-springDataJdbc/src/main/java/ru/otus/repository/AddressRepository.java new file mode 100644 index 0000000..39b2460 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/repository/AddressRepository.java @@ -0,0 +1,6 @@ +package ru.otus.repository; + +import org.springframework.data.repository.CrudRepository; +import ru.otus.model.Address; + +public interface AddressRepository extends CrudRepository {} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/repository/ClientRepository.java b/L28-springDataJdbc/src/main/java/ru/otus/repository/ClientRepository.java new file mode 100644 index 0000000..d9f2b41 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/repository/ClientRepository.java @@ -0,0 +1,6 @@ +package ru.otus.repository; + +import org.springframework.data.repository.CrudRepository; +import ru.otus.model.Client; + +public interface ClientRepository extends CrudRepository {} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/repository/PhoneRepository.java b/L28-springDataJdbc/src/main/java/ru/otus/repository/PhoneRepository.java new file mode 100644 index 0000000..a4e6651 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/repository/PhoneRepository.java @@ -0,0 +1,9 @@ +package ru.otus.repository; + +import org.springframework.data.repository.CrudRepository; +import ru.otus.model.Phone; + +public interface PhoneRepository extends CrudRepository { + + void deleteById(Long Id); +} diff --git a/L28-springDataJdbc/src/main/java/ru/otus/repository/UserRepository.java b/L28-springDataJdbc/src/main/java/ru/otus/repository/UserRepository.java new file mode 100644 index 0000000..775ee01 --- /dev/null +++ b/L28-springDataJdbc/src/main/java/ru/otus/repository/UserRepository.java @@ -0,0 +1,6 @@ +package ru.otus.repository; + +import org.springframework.data.repository.CrudRepository; +import ru.otus.model.User; + +public interface UserRepository extends CrudRepository {} diff --git a/L28-springDataJdbc/src/main/resources/application.yml b/L28-springDataJdbc/src/main/resources/application.yml new file mode 100644 index 0000000..e745683 --- /dev/null +++ b/L28-springDataJdbc/src/main/resources/application.yml @@ -0,0 +1,11 @@ +spring: + datasource: + url: jdbc:postgresql://localhost:5430/demoDB + username: usr + password: pwd + flyway: + enabled: true + +logging: + level: + org.springframework.jdbc.core.JdbcTemplate: TRACE \ No newline at end of file diff --git a/L28-springDataJdbc/src/main/resources/db/migration/V1__initial_schema.sql b/L28-springDataJdbc/src/main/resources/db/migration/V1__initial_schema.sql new file mode 100644 index 0000000..8beeb9c --- /dev/null +++ b/L28-springDataJdbc/src/main/resources/db/migration/V1__initial_schema.sql @@ -0,0 +1,29 @@ +create table users +( + id bigint generated by default as identity primary key, + name varchar(50), + login varchar(50), + password varchar(50) +); + +create table clients +( + id bigint generated by default as identity primary key, + name varchar(255) NOT NULL +); + +create table addresses +( + id bigint generated by default as identity primary key, + address varchar(255) NOT NULL, + client_id bigint, + foreign key (client_id) references clients (id) on delete cascade +); + +create table phones +( + id bigint generated by default as identity primary key, + number varchar(255) NOT NULL, + client_id bigint, + foreign key (client_id) references clients (id) on delete cascade +); \ No newline at end of file diff --git a/L28-springDataJdbc/src/main/resources/logback.xml b/L28-springDataJdbc/src/main/resources/logback.xml new file mode 100644 index 0000000..5ff97c1 --- /dev/null +++ b/L28-springDataJdbc/src/main/resources/logback.xml @@ -0,0 +1,18 @@ + + + + + + %d{yyyy-MM-dd_HH:mm:ss.SSS} %-5level %logger{36} - %msg%n + + + + + + + + + + + + diff --git a/L28-springDataJdbc/src/main/resources/static/img/login.png b/L28-springDataJdbc/src/main/resources/static/img/login.png new file mode 100644 index 0000000..c938199 Binary files /dev/null and b/L28-springDataJdbc/src/main/resources/static/img/login.png differ diff --git a/L28-springDataJdbc/src/main/resources/static/img/logo.svg b/L28-springDataJdbc/src/main/resources/static/img/logo.svg new file mode 100644 index 0000000..0002d77 --- /dev/null +++ b/L28-springDataJdbc/src/main/resources/static/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/L28-springDataJdbc/src/main/resources/static/index.html b/L28-springDataJdbc/src/main/resources/static/index.html new file mode 100644 index 0000000..434e006 --- /dev/null +++ b/L28-springDataJdbc/src/main/resources/static/index.html @@ -0,0 +1,14 @@ + + + Index + + +
+ +
+

Добро пожаловать на стартовую страницу примера

+ Пользователи
+ Клиенты +
+ + \ No newline at end of file diff --git a/L28-springDataJdbc/src/main/resources/templates/clients.html b/L28-springDataJdbc/src/main/resources/templates/clients.html new file mode 100644 index 0000000..58d9d3b --- /dev/null +++ b/L28-springDataJdbc/src/main/resources/templates/clients.html @@ -0,0 +1,174 @@ + + + Клиенты + + + + + +

+
+

Создать клиента

+ + + + +

+
+
+

Список клиентов

+ + + + + + + + + + + + + + + + + +
IdИмяАдресТелефоны
+ + + + + + + + + + +

+ + +

+ +
+ + \ No newline at end of file diff --git a/L28-springDataJdbc/src/main/resources/templates/users.html b/L28-springDataJdbc/src/main/resources/templates/users.html new file mode 100644 index 0000000..8dea814 --- /dev/null +++ b/L28-springDataJdbc/src/main/resources/templates/users.html @@ -0,0 +1,91 @@ + + + Пользователи + + + + + + + + +

Получить пользователя по id

+ + +

+
+

Создать пользователя

+ + + + +

+
+
+

Все пользователи

+ + + + + + + + + + + + + + +
IdИмяЛогинПароль
+ + + +
+ + \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 61b78f5..b28aaad 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -42,6 +42,7 @@ allprojects { val jetty: String by project val freemarker: String by project + val thymeleaf: String by project val reflections: String by project @@ -79,6 +80,7 @@ allprojects { dependency("org.eclipse.jetty:jetty-io:$jetty") dependency("org.eclipse.jetty:jetty-util:$jetty") dependency("org.freemarker:freemarker:$freemarker") + dependency("org.thymeleaf:thymeleaf:$thymeleaf") dependency("org.reflections:reflections:$reflections") diff --git a/gradle.properties b/gradle.properties index fcf5992..3502b64 100644 --- a/gradle.properties +++ b/gradle.properties @@ -23,6 +23,7 @@ redisson=3.31.0 jetty=12.0.16 freemarker=2.3.34 +thymeleaf=3.1.3.RELEASE reflections=0.10.2 diff --git a/settings.gradle.kts b/settings.gradle.kts index ae12322..658c4b0 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -21,6 +21,7 @@ include( "L38-webflux-chat:client-service", "L38-webflux-chat:datastore-service", "L24-webServer", + "L28-springDataJdbc", )