Commit 07b489ed by Patryk Czarnik

Eksperymenty dot. dostępu do baz danych w Springu

parent 61a42ca0
...@@ -5,7 +5,9 @@ import java.util.List; ...@@ -5,7 +5,9 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model; import org.springframework.ui.Model;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
...@@ -29,7 +31,7 @@ public class ProductController { ...@@ -29,7 +31,7 @@ public class ProductController {
@GetMapping(produces="text/html") @GetMapping(produces="text/html")
public String getProducts(Model model) { public String getProducts(Model model) {
List<Product> products = productRepository.findAll(); List<Product> products = productRepository.findAll(Sort.by("id"));
model.addAttribute("products", products); model.addAttribute("products", products);
return "products"; return "products";
} }
...@@ -60,7 +62,7 @@ public class ProductController { ...@@ -60,7 +62,7 @@ public class ProductController {
model.addAttribute("products", products); model.addAttribute("products", products);
return "wyszukiwarka"; return "wyszukiwarka";
} }
@GetMapping(path="/{id}", produces="text/html") @GetMapping(path="/{id}", produces="text/html")
public String getOneProduct(Model model, @PathVariable("id") Integer id) { public String getOneProduct(Model model, @PathVariable("id") Integer id) {
Optional<Product> optProduct = productRepository.findById(id); Optional<Product> optProduct = productRepository.findById(id);
...@@ -72,6 +74,26 @@ public class ProductController { ...@@ -72,6 +74,26 @@ public class ProductController {
} }
} }
@GetMapping("/max")
public String najdrozszyProdukt(Model model) {
Product produkt = productRepository.najdrozszyProdukt();
model.addAttribute("product", produkt);
return "product";
}
// @GetMapping(path="/min", produces="text/plain")
// @ResponseBody
// public String najtanszyProdukt() {
// return productRepository.nazwaNajtanszego();
// }
@GetMapping("/{id}/ile_drozszych")
@ResponseBody
public long najdrozszyProdukt(@PathVariable Integer id) {
long wynik = productRepository.ileDrozszychNiz(id);
return wynik;
}
@GetMapping("/{id}/add-to-basket") @GetMapping("/{id}/add-to-basket")
public String addToBasket(@PathVariable("id") Integer productId, public String addToBasket(@PathVariable("id") Integer productId,
@SessionAttribute Basket basket) { @SessionAttribute Basket basket) {
...@@ -101,7 +123,6 @@ public class ProductController { ...@@ -101,7 +123,6 @@ public class ProductController {
} }
} }
@PostMapping({"/new", "/{id}/edit"})
// Ta metoda zapisuje dane przysłane z formularza obojętnie, czy to było edit, czy new // Ta metoda zapisuje dane przysłane z formularza obojętnie, czy to było edit, czy new
// Adnotacja @Valid powoduje, że Spring dokona walidacji obiektu PRZED uruchomieniem tej metody. // Adnotacja @Valid powoduje, że Spring dokona walidacji obiektu PRZED uruchomieniem tej metody.
// Jeśli nie ma dodatkowego parametru BindingResult, a są błędy walidacji, to Spring naszej metody w ogóle nie uruchomi. // Jeśli nie ma dodatkowego parametru BindingResult, a są błędy walidacji, to Spring naszej metody w ogóle nie uruchomi.
...@@ -109,6 +130,11 @@ public class ProductController { ...@@ -109,6 +130,11 @@ public class ProductController {
// metoda zawsze jest uruchamiana przez Springa, // metoda zawsze jest uruchamiana przez Springa,
// a w tym parametrze zawarte są informacje o przebiegu walidacji, w tym błędy. // a w tym parametrze zawarte są informacje o przebiegu walidacji, w tym błędy.
// Bez adnotacji @ModelAttribute też działało // Bez adnotacji @ModelAttribute też działało
// @Transactional oznacza, że cała metoda jest realizowana w jednej transakcji bazodanowej
// To miałoby znaczenie, gdyby występowało więcej operacji zapisu.
// Wtedy sukces tej metody skutkowałby zatwierdzeniem transakcji, a wyjątek powodowałby wyofanie wszystkich save'ów
@Transactional
@PostMapping({"/new", "/{id}/edit"})
public String saveProduct(@ModelAttribute @Valid Product product, public String saveProduct(@ModelAttribute @Valid Product product,
BindingResult bindingResult) { BindingResult bindingResult) {
// W tej wersji dane z wypełnionego formularza odbieramy w postaci jednego obiektu Product. // W tej wersji dane z wypełnionego formularza odbieramy w postaci jednego obiektu Product.
......
...@@ -53,7 +53,7 @@ public class ProductControllerAlt { ...@@ -53,7 +53,7 @@ public class ProductControllerAlt {
public byte[] foto(@PathVariable Integer id, Model model) { public byte[] foto(@PathVariable Integer id, Model model) {
return photoUtil.readBytes(id); return photoUtil.readBytes(id);
} }
@GetMapping("/new") @GetMapping("/new")
public String nowyProdukt() { public String nowyProdukt() {
return "product_form_alt"; return "product_form_alt";
......
...@@ -4,7 +4,9 @@ import java.math.BigDecimal; ...@@ -4,7 +4,9 @@ import java.math.BigDecimal;
import java.util.List; import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import jakarta.persistence.EntityManager;
import sklep.model.Product; import sklep.model.Product;
/* Gdy w projekcie umieścimy interfejs rozszerzający interfejs JpaRepository (albo podobny) /* Gdy w projekcie umieścimy interfejs rozszerzający interfejs JpaRepository (albo podobny)
...@@ -36,5 +38,16 @@ public interface ProductRepository extends JpaRepository<Product, Integer> { ...@@ -36,5 +38,16 @@ public interface ProductRepository extends JpaRepository<Product, Integer> {
List<Product> findByProductNameContainingIgnoringCaseAndPriceBetween(String name, BigDecimal min, BigDecimal max); List<Product> findByProductNameContainingIgnoringCaseAndPriceBetween(String name, BigDecimal min, BigDecimal max);
List<Product> findByProductNameContainingIgnoreCase(String name); List<Product> findByProductNameContainingIgnoreCase(String name);
@Query("SELECT p FROM Product p ORDER BY p.price DESC LIMIT 1")
Product najdrozszyProdukt();
@Query(nativeQuery=true, value="""
SELECT count(*)
FROM products
WHERE price > (SELECT price FROM products
WHERE product_id = :idInnegoProduktu)
""")
long ileDrozszychNiz(int idInnegoProduktu);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment