SpringMVC+Hibernate+Thymeleaf ManyToOne formularz wwww

SpringMVC+Hibernate+Thymeleaf ManyToOne formularz wwww
P5
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 6 lat
  • Postów:28
0

Kombinuję i nic. Przejrzałem już cały internet :) Próbowałem różnych rozwiązań, ale nic mi z tego nie wychodzi. Być może jest gdzieś jakiś dobry tutorial jak zrobić formularz www, w którym można dodawać dane do bazy zawierający relacje? (formularz bez relacji to nie problem, takich tutoriali jest milion w internecie i jestem w stanie to zrobić)

To na czym jestem w tej chwili to: (nazwy przykładowe, żeby łatwiej było opisywać):

  • mam stworzoną relacyjną bazę danych, tabele Pracodawca, Pracownik
  • mam formularz z polami input (tabela Pracodawca) i polami select (z tabeli Pracownik) zwracającymi ID
  • dwie klasy encje

Zatwierdzenie formularza powoduje wysłanie danych, i obiekt ma być zapisany do bazy, ale obiekt Pracodawca nie jest tworzony, ponieważ (dość logiczne w sumie) zamiast parametru typu Pracownik pojawia się wartość typu String (czyli ID pracownika). Próbowałem stworzyć konwerter (kod poniżej), ale ciągle coś mi nie działa... Zanim wkleję więcej kodu, pytanie czy ja w ogóle idę w dobrym kierunku? Czy rzeczywiście powinien być konwerter, czy może to się powinno w jakiś 'magiczny' sposób robić samo, ale się nie robi bo na przykład spaprałem coś z encjami?

Kopiuj
public class UserTypeConverter implements Converter<String, User> {

    private UserHelper userhelper;

    @Override
    public User convert(String s) {
        return userhelper.getUserByID(Integer.parseInt(s));
    }
} 

Pytanie drugie dodatkowe: czy te framworki to najlepszy z możliwych wybór jeżeli chodzi o tworzenie www z dużą ilością formularzy i relacji w bazie?

edytowany 1x, ostatnio: pin54
0

Specem nie jestem, też dopiero zaczynam. Pewnie da się to zrobić lepiej i ktoś mnie poprawi.

Jeżeli robisz formularz z polem typu select to w kontrolerze możesz przekazać ów obiekt do widoku :

Kopiuj
@RequestMapping(value = "/myForm", method = RequestMethod.GET)
    public ModelAndView form() {
        ModelAndView mav = new ModelAndView("empList");
        mav.addObject("employeeList", employeeService.getEmployees());
        mav.addObject("employer", new Employer());
        return mav;
    }

Dzięki temu w thymeleaf możesz odwołać się bezpośrednio do obiektów typu Employer, który stworzyłeś w kontrolerze (na razie pust) th:object="${employer}" i listy pracowników iterowanych do option :

Kopiuj
<select class="form-control" th:field="*{employee}">
<option th:each="p : ${employeeList}" th:value="${p.name}" th:text="${p.name}"></option>
</select>

Zakładam że Employer posiada listę obiektów typu Employee.
Do wysłaniu formularza robisz kontroler :

Kopiuj
 @RequestMapping(value = "/add", method = RequestMethod.POST)
    public String add(@Valid @ModelAttribute Employer employer, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "error";
        }
        employerService.addEmployer(employer);
        return "redirect:empList";
    }

W serwisach piszesz sobie logikę która pewnie sprowadzi się do zapisania rekordu do bazy.
W ten mniej więcej sposób robisz zapis nowego pracodawcy wraz z listą pracowników. Oczywiście pisane z palca mam jednak nadzieję że załapiesz idee.
Jeżeli da się to zrobić inaczej lub lepiej to również chętnie się dowiem :)

P5
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 6 lat
  • Postów:28
0

Właśnie chodzi o to, że to co napisałeś to ja już mam - chyba, że gdzieś jest błąd, którego nie zauważam.

Kopiuj
              <tr>
                 <td> 
                        <select th:field="*{userByQcname}">
                            <option th:each="u : ${user}" th:value="${u.id}" th:text="${u.name}">Opcja</option>
                        </select> 
                    </td>
                    <td th:if="${#fields.hasErrors('userByQcname')}" th:errors="*{userByQcname}" th:value="*{userByQcname}"></td></tr>
Kopiuj
    @RequestMapping(method = RequestMethod.GET, path = "/add")
    public String showNewCardForm(Model model) {
        model.addAttribute("card", new Card());
        model.addAttribute("user", userhelper.getUserNames(1, 2)); 
        return "addnewcard";
    }

     @RequestMapping(method = RequestMethod.POST, path = "/add")
    public String addNewCard(@Valid Card card, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "addnewcard";
        }
        cardhelper.session.save(card);
        return "showcard";
    }

Cały problem sprowadza się właśnie do zapisania rekordu do bazy, czego nie mogę zrobić. Rozumiem, że po zatwierdzeniu formularza tworzony jest nowy obiekt Pracodawca i wywoływany konstruktor - ale konstruktor musi być wywołany z parametrem typu Pracownik, a dostaje parametr typu String - i dokładnie taki błąd jest zwracany. Pytanie czy muszę dodać jakiś konwerter, czy przegapiłem coś co 'uruchamia automatyczny mechanizm' zamiany Stringa z ID Pracownika na obiekt typu Pracownik i wcale nie powinienem mieć tu błędu?
Kolejnym krokiem byłoby tylko zapisanie do bazy, co powinno być załatwione dzięki prostemu cardhelper.session.save(card);

artur52
  • Rejestracja:ponad 10 lat
  • Ostatnio:9 miesięcy
  • Lokalizacja:Warszawa
  • Postów:223
0
0

Dzięki.

P5
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 6 lat
  • Postów:28
0

Może i pomoże...ale spędziłem chyba z 6 godzin próbując ten projekt odpalić w Netbeansie i mi się nie udało :/ Ledwie jakieś podstawy Mavena załapałem, a tu jest Gradle więc leżę i kwiczę. Powalczę jeszcze trochę :) jak się nie uda to wrócę, albo se chociaż poprzeglądam w notatniku źródła :)

EDIT:
Ten przykład jest świetny, w zasadzie czegoś takiego szukałem bo coś takiego chcę zrobić, dużo się z niego zapewne nauczę - POLECAM ;). Szkoda, że jest mało komentarzy, ale nie można mieć wszystkiego. Niestety jest też dość mocno skomplikowany (jak dla mnie)...choć i tak dobrze, że zajarzyłem w końcu, że można zamiast wersji 5.0 ściągnąć 1.8 :D

edytowany 1x, ostatnio: pin54
P5
  • Rejestracja:ponad 10 lat
  • Ostatnio:ponad 6 lat
  • Postów:28
1

Jednak ten przykład nie zawierał dokładnie tego co chciałem, ale jest dużo innych ciekawych rzeczy, z których skorzystałem.
Formularz udało mi się zrobić w taki sposób jaki próbowałem na początku, czyli poprzez dodanie dodatkowego formatera formatterRegistry.addConverter. Mam tylko jeden problem, na wszystkich parametrach ustawiony jest validator, jeżeli dane są nieprawidłowe to zwracamy ten sam formularz oraz błąd - wszystkie pola pojawiają się z danymi, które zostały wpisane, oprócz pola select. Nie byłoby wielkim problemem gdyby było po prostu puste, ale niestety obiekt odpowiedzialny za wypełnianie pól option 'znika' i nie ma możliwości ponownego wyboru. Co robię źle, albo co jeszcze muszę zrobić?

Kopiuj
    @RequestMapping(value = "/card/new", method = RequestMethod.GET)
    public String initAddCardForm(Model model) {
        Card card = new Card();
        model.addAttribute("card",card);

        Collection<User> results = userService.getAllUsers();
        model.addAttribute("users", results);
        
        return CARD_FORM_VIEW;
    }

    @RequestMapping(value = "/card/new", method = RequestMethod.POST)
    public String addCard(@Valid Card card, BindingResult result,
                             SessionStatus status, RedirectAttributes attributes) {
        if (result.hasErrors()) {
            return CARD_FORM_VIEW;
        } else {
            CardDTO cardDTO = CardUtils.cardToCardDTO(card);
            Card added = cardService.add(cardDTO);
            logger.info("Added card with information: {}", added);
            status.setComplete();

            addFeedbackMessage(attributes, FEEDBACK_MESSAGE_KEY_CARD_ADDED,
                    added.getCardNr(), added.getArticleName());

            return "redirect:/cards/";
        }
    } 
OK
  • Rejestracja:ponad 8 lat
  • Ostatnio:prawie 8 lat
0

Możesz sobie zdefiniować w kontrolerze metodę oznaczoną annotacją @ModelAttribute zwracjącą kolekcję potrzebną w widoku. Ewentualnie przy zwracaniu widoku po błędzie dodać do modelu tą kolekcję.

edytowany 1x, ostatnio: okcam
Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)