{"id":2847,"date":"2023-04-11T12:21:00","date_gmt":"2023-04-11T12:21:00","guid":{"rendered":"https:\/\/www.juniorjavadeveloper.pl\/?p=2847"},"modified":"2024-07-03T18:33:36","modified_gmt":"2024-07-03T18:33:36","slug":"przejscie-z-junior-na-mid-level-java-developer-praktyczny-poradnik","status":"publish","type":"post","link":"https:\/\/www.juniorjavadeveloper.pl\/en\/2023\/04\/11\/przejscie-z-junior-na-mid-level-java-developer-praktyczny-poradnik\/","title":{"rendered":"Przej\u015bcie z Junior na Mid-Level Java Developer? Praktyczny poradnik"},"content":{"rendered":"<p class=\"wp-block-paragraph\">Coraz wi\u0119cej os\u00f3b zg\u0142asza si\u0119 do mnie poszukuj\u0105c pomocy w przej\u015bciu ze stanowiska Junior Java Developer na Mid-Level Java Developer. Chc\u0105c pom\u00f3c jak najwi\u0119kszej liczbie os\u00f3b w tym artykule przedstawi\u0119 najcz\u0119\u015bciej zadawane mi pytania oraz moje podej\u015bcie do tematu przej\u015bcia z Junior na Mid-Level Java Developer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Cz\u0119\u015b\u0107 os\u00f3b, kt\u00f3re zg\u0142aszaj\u0105 si\u0119 do mnie czuj\u0105, \u017ce <strong>stoj\u0105 w miejscu, nie rozwijaj\u0105 si\u0119<\/strong>, to ich motywuje do zmiany. Spora cz\u0119\u015b\u0107 os\u00f3b zg\u0142asza si\u0119 do mnie, co jest smutne, poniewa\u017c <strong>nie otrzymuje w\u0142a\u015bciwego wsparcia w projekcie<\/strong> od do\u015bwiadczonych programist\u00f3w. Dobra informacja jest taka, \u017ce ka\u017cda z tych os\u00f3b mo\u017ce przej\u015b\u0107 od junior do mid-level.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pomijaj\u0105c kwestie nazewnictwa Junior vs. Mid-Level, to nale\u017cy pami\u0119ta\u0107, \u017ce w tym wszystkim chodzi o doskonalenie warsztatu programistycznego. Dodatkowo ka\u017cda firma inaczej nazywa stanowiska, np.: M\u0142odszy Specjalista ds. Rozwoju Oprogramowania, Junior Java Developer, Software Engineer.  Dlatego w tym artykule du\u017cy nacisk po\u0142o\u017c\u0119 na kwesti\u0119 doskonalenia.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Najcz\u0119\u015bciej zadawane pytania:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Po ilu latach mog\u0119 zosta\u0107 Mid-Level Java Developerem, Developerk\u0105? <\/li>\n\n\n\n<li>Jaki zakres wiedzy musz\u0119 posiada\u0107?<\/li>\n\n\n\n<li>Ile projekt\u00f3w musz\u0119 zrealizowa\u0107?<\/li>\n\n\n\n<li>Jak uzyska\u0107 wsparcie w projekcie od do\u015bwiadczonych programist\u00f3w?<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Po ilu latach mog\u0119 zosta\u0107 Mid-Level Java Developerem, Developerk\u0105?<\/em>  <strong>Granica przej\u015bcia z Junior na Mid-Level Java Developer<\/strong> jest bardzo umowna. Moim zdaniem <strong>nie zale\u017cy ona od sta\u017cu pracy w latach<\/strong>, najwa\u017cniejsza jest &#8220;ilo\u015b\u0107&#8221; oraz r\u00f3\u017cnorodno\u015b\u0107 projekt\u00f3w, w kt\u00f3rych Junior Java Developer, Developerka brali udzia\u0142. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Pytania &#8220;Jaki zakres wiedzy musz\u0119 posiada\u0107?&#8221; oraz &#8220;Ile projekt\u00f3w musz\u0119 zrealizowa\u0107?&#8221; zamieni\u0142bym na jedno zasadnicze pytanie: <strong>Jak zapewni\u0107 sobie r\u00f3\u017cnorodno\u015b\u0107 projekt\u00f3w w firmie?<\/strong> Zacznijmy od tego, \u017ce r\u00f3\u017cne projekty pozwalaj\u0105 na prac\u0119 z wieloma technologiami i narz\u0119dziami. Najwa\u017cniejsze, to nie zamyka\u0107 si\u0119 we w\u0142asnej strefie komfortu, dzia\u0142aj\u0105c w dobrze nam znanym i bezpiecznym projekcie.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>R\u00f3\u017cnorodno\u015b\u0107 mo\u017cna znale\u017a\u0107 nawet w obr\u0119bie jednego projektu<\/strong>, implementuj\u0105c jego r\u00f3\u017cne modu\u0142y\/funkcjonalno\u015bci. Pracuj\u0105c przy np.: module przelew\u00f3w bankowych mo\u017cna &#8220;przej\u015b\u0107&#8221; do modu\u0142u odpowiedzialnego za generowanie i\/lub archiwizacj\u0119 dokument\u00f3w bankowych &#8211; potwierdzenie przelewu, wyci\u0105g z karty kredytowej.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Zazwyczaj projekty wchodz\u0105 w sk\u0142ad wi\u0119kszego systemu informatycznego, ka\u017cdy projekt jest realizowany przez inny dzia\u0142 w firmie, to stwarza <strong>mo\u017cliwo\u015b\u0107 zmiany projektu w ramach r\u00f3\u017cnych dzia\u0142\u00f3w<\/strong>. Pracuj\u0105c przy np. projekcie billingowym dla operatora telekomunikacyjnego mo\u017cna przej\u015b\u0107 do dzia\u0142u wsparcia sprzeda\u017cy urz\u0105dze\u0144.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><em>Jak uzyska\u0107 wsparcie w projekcie od do\u015bwiadczonych programist\u00f3w?<\/em> Zak\u0142adaj\u0105c, \u017ce wychodzimy z pozycji Junior Java Developera, Developerki z kilkunastoma miesi\u0105cami do\u015bwiadczenia oraz ze znajomo\u015bci\u0105 element\u00f3w opisanych w <a href=\"https:\/\/www.juniorjavadeveloper.pl\/en\/2022\/08\/17\/jak-powinny-wygladac-realne-wymagania-dla-junior-java-developera-just-join-it\/\" data-type=\"post\" data-id=\"1822\">Jak powinny wygl\u0105da\u0107 realne wymagania dla Junior Java Developer\u2019a? \u2013 Just Join IT<\/a> &#8211; Java, git, Maven\/Gradle, JUnit5, HTTP, REST, Spring Framework, Hibernate ORM.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Temat uzyskania wsparcia od do\u015bwiadczonych programist\u00f3w jest do\u015b\u0107 z\u0142o\u017cony, bo chodzi tu o interakcj\u0119 z drugim cz\u0142owiekiem. Mog\u0119 poda\u0107 jeden sprawdzony spos\u00f3b. Dla tworzonego kodu &#8211; umieszczanego na nowym branchu w git &#8211; tworzymy Pull Request\/Megre Request, przypisuj\u0105c do\u015bwiadczonych koleg\u00f3w jako osoby do review &#8211; przegl\u0105d, weryfikacja naszego kodu. Mo\u017cna r\u00f3wnie\u017c wykorzysta\u0107 (w granicach rozs\u0105dku) wszystkie dost\u0119pne \u015brodki komunikacji, np.: chat, video, telefon oraz  rozmowa w cztery oczy.<\/p>\n\n\n\n<hr class=\"wp-block-separator alignwide has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Moje podej\u015bcie do tematu wsparcia przej\u015bcia z Junior do Mid-Level Java Developer.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"#doglebne_poznanie_frameworkow\" data-type=\"internal\" data-id=\"#doglebne_poznanie_frameworkow\">Dog\u0142\u0119bne poznanie wykorzystywanych framework\u00f3w oraz narz\u0119dzi:<\/a>\n<ul class=\"wp-block-list\">\n<li><a href=\"#spring_mvc_java_servlet\" data-type=\"internal\" data-id=\"#spring_mvc_java_servlet\">Spring MVC wykorzystuje Java Servlet,<\/a><\/li>\n\n\n\n<li><a href=\"#hibernate_jdbc\" data-type=\"internal\" data-id=\"#hibernate_jdbc\">Hibernate wykorzystuje JDBC (Java Database Connectivity),<\/a><\/li>\n\n\n\n<li><a href=\"#properties_zamiast_spring_value\">Java Properties zamiast Spring @Value,<\/a><\/li>\n\n\n\n<li><a href=\"#nakladanie_di_oop\">&#8220;Nak\u0142adanie&#8221; Spring DI w czystym OOP,<\/a><\/li>\n\n\n\n<li><a href=\"#spring_bez_spring_boot\">Spring Framework bez Spring Boot.<\/a><\/li>\n<\/ul>\n<\/li>\n\n\n\n<li><a href=\"#junit_mocking_tdd\">Testy jednostkowe, mockowanie, idealnie TDD.<\/a><\/li>\n\n\n\n<li><a href=\"#rozbicie_problemu\">Rozbicie, wyizolowanie istoty problemu do postaci nowego oddzielnego projektu.<\/a><\/li>\n\n\n\n<li><a href=\"#zadania_na_codewars\">Zadania &#8211; https:\/\/www.codewars.com\/<\/a><\/li>\n\n\n\n<li><a href=\"#wyzwania_na_challengerocket\">Wyzwania &#8211; https:\/\/challengerocket.com\/<\/a><\/li>\n\n\n\n<li><a href=\"#get_trained_careerkarma\">&#8220;Get Trained For The Future, Today&#8221; &#8211; https:\/\/careerkarma.com\/<\/a><\/li>\n<\/ol>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\"><div class=\"wp-block-image\"><!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/REC-html40\/loose.dtd\">\n<html><body><figure class=\"aligncenter size-large is-resized\"><img decoding=\"async\" src=\"https:\/\/github.githubassets.com\/images\/modules\/logos_page\/GitHub-Mark.png\" alt=\"\" style=\"width:140px;height:140px\"><\/figure>\n<\/body><\/html>\n<\/div><\/div>\n\n\n\n<div class=\"wp-block-column is-vertically-aligned-center has-normal-font-size is-layout-flow wp-block-column-is-layout-flow\">\n<p class=\"has-text-align-center wp-block-paragraph\">Ca\u0142o\u015b\u0107 kodu \u017ar\u00f3d\u0142owego mo\u017cna znale\u017a\u0107 na moim koncie GitHub pod adresem <a href=\"https:\/\/github.com\/juniorjavadeveloper-pl\/java-junior-transition-mid-level\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/juniorjavadeveloper-pl\/java-junior-transition-mid-level<\/a><\/p>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Cz\u0119\u015b\u0107 prezentowanego kodu \u017ar\u00f3d\u0142owego w samym artykule mo\u017ce by\u0107  w wersji &#8220;okrojonej&#8221;, tak,  aby przedstawi\u0107 istot\u0119 zagadnienia bez zaciemniania obrazu szczeg\u00f3\u0142ami. Ca\u0142y kod \u017ar\u00f3d\u0142owy jest na GitHub.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"doglebne_poznanie_frameworkow\"><em>Dog\u0142\u0119bne poznanie wykorzystywanych framework\u00f3w oraz narz\u0119dzi<\/em> pozwala pokaza\u0107 jak kiedy\u015b wygl\u0105da\u0142o &#8220;programowanie&#8221;. To pozwala zobaczy\u0107 jak wiele u\u0142atwie\u0144 daj\u0105 wsp\u00f3\u0142czesne rozwi\u0105zania. Pozwala r\u00f3wnie\u017c lepiej zrozumie\u0107 dlaczego co\u015b dzia\u0142a tak, a nie inaczej oraz jak lepiej wykorzysta\u0107 technologi\u0119 i rozwi\u0105za\u0107 pojawiaj\u0105ce si\u0119 b\u0142\u0119dy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"spring_mvc_java_servlet\"><strong>Spring MVC wykorzystuje Java Servlet<\/strong>, technologia Servlet\u00f3w ma 26 lat &#8211; <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Jakarta_Servlet\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Jakarta_Servlet\" target=\"_blank\">Jakarta Servlet<\/a> &#8211; wchodzi w sk\u0142ad Java EE &#8211; Java EE, to obecnie Jakarta EE po \u201coddelegowaniu projektu\u201d przez firm\u0119 Oracle do <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Eclipse_Foundation\" target=\"_blank\">Eclipse Foundation<\/a>. U\u017cywaj\u0105c Java\/Jakarta EE trzeba &#8220;zainstalowa\u0107&#8221; serwer webowy obs\u0142uguj\u0105cy protoku\u0142 HTTP &#8211; <a rel=\"noreferrer noopener\" href=\"https:\/\/en.wikipedia.org\/wiki\/Apache_Tomcat\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Apache_Tomcat\" target=\"_blank\">Apache Tomcat<\/a> &#8211; skonfigurowa\u0107 go, doda\u0107 plugin do Maven i ju\u017c mo\u017cna uruchamia\u0107 aplikacje web. Korzystaj\u0105c ze Spring MVC + Spring Boot wystarczy wygenerowa\u0107 aplikacj\u0119 web &#8211; <a rel=\"noreferrer noopener\" href=\"https:\/\/start.spring.io\/\" data-type=\"URL\" data-id=\"https:\/\/start.spring.io\/\" target=\"_blank\">Spring Initializr<\/a> &#8211; nast\u0119pnie po prostu uruchomi\u0107 aplikacj\u0119.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">Web on Servlet Stack &#8211; 1. Spring Web MVC<\/p>\n<cite>Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, &#8220;Spring Web MVC,&#8221; comes from the name of its source module (<a href=\"https:\/\/github.com\/spring-projects\/spring-framework\/tree\/main\/spring-webmvc\"><code>spring-webmvc<\/code><\/a>), but it is more commonly known as &#8220;Spring MVC&#8221;. &#8211; <a href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/6.0.7\/reference\/html\/web.html#mvc\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/docs.spring.io\/spring-framework\/docs\/6.0.7\/reference\/html\/web.html#mvc<\/a><\/cite><\/blockquote>\n\n\n\n<p class=\"wp-block-paragraph\">Poni\u017cszy kod pokazuje jak obs\u0142u\u017cy\u0107 \u017c\u0105danie protoko\u0142u HTTP dla metody GET wraz z przes\u0142aniem parametru \u017c\u0105dania. Dla technologi Java\/Jakarta EE potrzebujemy klasy Java <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">NotThatSimpleJavaServlet<\/code> oraz pliku <code data-enlighter-language=\"xml\" class=\"EnlighterJSRAW\">web.xml<\/code> z konfiguracj\u0105. Dla Spring MVC wystarczy jedna klasa Java <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">SimpleSpringController<\/code>. W przypadku Java\/Jakarta Servlet niepotrzebnie wi\u0105\u017cemy si\u0119 z klas\u0105 <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">HttpServlet<\/code> &#8211; poprzez dziedziczenie, <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">extends<\/code> &#8211; jak wiemy w j\u0119zyku Java nie ma wielodziedziczenia, obs\u0142uga wyj\u0105tk\u00f3w jest utrudniona.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import jakarta.servlet.RequestDispatcher;\nimport jakarta.servlet.ServletException;\nimport jakarta.servlet.http.HttpServlet;\nimport jakarta.servlet.http.HttpServletRequest;\nimport jakarta.servlet.http.HttpServletResponse;\n\nimport java.io.IOException;\n\npublic class NotThatSimpleJavaServlet extends HttpServlet {\n    @Override\n    protected void doGet(HttpServletRequest request, HttpServletResponse response) \n            throws ServletException, IOException {\n        String dashboardMode = request.getParameter(\"dashboardMode\");\n        if (dashboardMode != null) {\n            request.setAttribute(\"dashboardMode\", dashboardMode);\n        }\n\n        RequestDispatcher requestDispatcher = \n                request.getRequestDispatcher(\"\/WEB-INF\/views\/dashboard.jsp\");\n        requestDispatcher.forward(request, response);\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Obs\u0142uga end-point, np.: http:\/\/localhost:8080\/dashboard\/java\/servlet\/ &#8211; po\u0142\u0105czenie klasy Java <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">NotThatSimpleJavaServlet<\/code> oraz pliku konfiguracyjnego <code data-enlighter-language=\"xml\" class=\"EnlighterJSRAW\">web.xml<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?>\n&lt;web-app xmlns=\"https:\/\/jakarta.ee\/xml\/ns\/jakartaee\"\n         xmlns:xsi=\"http:\/\/www.w3.org\/2001\/XMLSchema-instance\"\n         xsi:schemaLocation=\"https:\/\/jakarta.ee\/xml\/ns\/jakartaee \n            https:\/\/jakarta.ee\/xml\/ns\/jakartaee\/web-app_5_0.xsd\"\n         version=\"5.0\"\n         metadata-complete=\"false\">\n\n    &lt;servlet>\n        &lt;servlet-name>NotThatSimpleJavaServlet&lt;\/servlet-name>\n        &lt;!-- NOTE: package name shortened for readability -->\n        &lt;servlet-class>\n            pl.juniorjavadeveloper.java.mvc_java_servlet.NotThatSimpleJavaServlet\n        &lt;\/servlet-class>\n    &lt;\/servlet>\n\n    &lt;servlet-mapping>\n        &lt;servlet-name>NotThatSimpleJavaServlet&lt;\/servlet-name>\n        &lt;url-pattern>\/dashboard\/java\/servlet\/*&lt;\/url-pattern>\n    &lt;\/servlet-mapping>\n&lt;\/web-app><\/pre>\n<\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import org.springframework.stereotype.Controller;\nimport org.springframework.ui.Model;\nimport org.springframework.web.bind.annotation.GetMapping;\nimport org.springframework.web.bind.annotation.RequestMapping;\n\n@Controller\n@RequestMapping(value = \"\/dashboard\/simple\/spring\")\npublic class SimpleSpringController {\n    @GetMapping\n    public String dashboardView(String dashboardMode, Model model) {\n        if (dashboardMode != null) {\n            model.addAttribute(\"mode\", dashboardMode);\n        }\n        return \"dashboard.html\";\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Obs\u0142uga end-point, np.: http:\/\/localhost:8080\/dashboard\/simple\/spring\/ &#8211; wymaga tylko jednej klasy Java <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">SimpleSpringController<\/code> &#8211; konfiguracja dostarczona przez Spring Boot. <\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"hibernate_jdbc\"><strong>Hibernate wykorzystuje JDBC (Java Database Connectivity)<\/strong>, co oznacza, \u017ce warto wiedzie\u0107, co dzieje si\u0119 &#8220;pod spodem&#8221;. Poznanie czystego JDBC wymusza r\u00f3wnie\u017c znajomo\u015b\u0107 SQL, co jest bardzo wa\u017cnym elementem w warsztacie Mid-Level Java Developera, Developerki. Dodatkowo, je\u017celi nam na wydajno\u015bci operacji bazodanowych, to JDBC jest bardzo dobrym rozwi\u0105zaniem. Nale\u017cy pami\u0119ta\u0107, \u017ce mamy wi\u0119cej mo\u017cliwo\u015bci utrwalania danych w Java &#8211; wi\u0119cej szczeg\u00f3\u0142\u00f3w w artykule <a rel=\"noreferrer noopener\" href=\"https:\/\/dev.to\/yigi\/hibernate-vs-jdbc-vs-jpa-vs-spring-data-jpa-1421\" target=\"_blank\">https:\/\/dev.to\/yigi\/hibernate-vs-jdbc-vs-jpa-vs-spring-data-jpa-1421<\/a>. Kod \u017ar\u00f3d\u0142owy z przyk\u0142adami wykorzystania Hibernate mo\u017cna znale\u017a\u0107 na moim GitHub &#8211; <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/juniorjavadeveloper-pl\/hibernate-examples\/\" target=\"_blank\">https:\/\/github.com\/juniorjavadeveloper-pl\/hibernate-examples\/<\/a>.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p class=\"wp-block-paragraph\">1. Architecture &#8211; 1.1. Overview<\/p>\n\n\n<div class=\"wp-block-image\"><!DOCTYPE html PUBLIC \"-\/\/W3C\/\/DTD HTML 4.0 Transitional\/\/EN\" \"http:\/\/www.w3.org\/TR\/REC-html40\/loose.dtd\">\n<html><body><figure class=\"aligncenter size-large\"><a href=\"https:\/\/docs.jboss.org\/hibernate\/orm\/6.2\/userguide\/html_single\/images\/architecture\/data_access_layers.svg\" target=\"_blank\" rel=\"noreferrer noopener\"><img decoding=\"async\" src=\"https:\/\/docs.jboss.org\/hibernate\/orm\/6.2\/userguide\/html_single\/images\/architecture\/data_access_layers.svg\" alt=\"\"><\/a><\/figure>\n<\/body><\/html>\n<\/div><cite>Hibernate, as an ORM solution, effectively &#8220;sits between&#8221; the Java application data access layer and the Relational Database, as can be seen in the diagram above. &#8211; <a href=\"https:\/\/docs.jboss.org\/hibernate\/orm\/6.2\/userguide\/html_single\/Hibernate_User_Guide.html#architecture-overview\" data-type=\"URL\" data-id=\"https:\/\/docs.jboss.org\/hibernate\/orm\/6.2\/userguide\/html_single\/Hibernate_User_Guide.html#architecture-overview\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/docs.jboss.org\/hibernate\/orm\/6.2\/userguide\/html_single\/Hibernate_User_Guide.html#architecture-overview<\/a><\/cite><\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"sql\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CREATE TABLE EMPLOYEES(\n    ID INT PRIMARY KEY,\n    FIRST_NAME VARCHAR(255),\n    LAST_NAME VARCHAR(255),\n    DEPARTMENT VARCHAR(255)\n);<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Korzystaj\u0105c z JDBC nale\u017cy samemu utworzy\u0107 elementy w bazie danych, np.: tabele. Powy\u017cszy skrypt SQL tworzy tabel\u0119 o nazwie EMPLOYEES.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class EmployeeModel {\n    private Long id;\n\n    private String firstName;\n    private String lastName;\n\n    private String department;\n\n    \/\/ getters\/setters\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Potrzebujemy r\u00f3wnie\u017c klas\u0119 POJO, kt\u00f3ra b\u0119dzie odpowiada\u0107 strukturze tabeli w bazie danych, ale klas\u0119 POJO musimy samodzielnie wype\u0142ni\u0107 za pomoc\u0105 klasy DAO &#8211; w odr\u00f3\u017cnieniu od Hibernate, gdzie dzieje si\u0119, to automatycznie.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import java.sql.Connection;\nimport java.sql.DriverManager;\nimport java.sql.PreparedStatement;\nimport java.sql.SQLException;\n\npublic class EmployeeModelDao {\n\n    private static final String DB_URL =\n            \"jdbc:h2:~\/h2database\/hibernate-orm-jdbc-database\";\n    private static final String INSERT_EMPLOYEE_SQL =\n            \"INSERT INTO EMPLOYEES(ID, FIRST_NAME, LAST_NAME, DEPARTMENT)\" +\n                    \" VALUES(?, ?, ?, ?);\";\n\n    public void create(EmployeeModelJDBC employeeModel) {\n        \/\/ NOTE: Connection code must be moved to a separate class and reused!\n        try (Connection connection = DriverManager.getConnection(DB_URL, \"sa\", \"\");\n             PreparedStatement preparedStatement =\n                     connection.prepareStatement(INSERT_EMPLOYEE_SQL)) {\n\n            preparedStatement.setLong(1, employeeModel.getId());\n            preparedStatement.setString(2, employeeModel.getFirstName());\n            preparedStatement.setString(3, employeeModel.getLastName());\n            preparedStatement.setString(4, employeeModel.getDepartment());\n\n            preparedStatement.executeUpdate();\n        } catch (SQLException e) {\n            e.printStackTrace();\n        }\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Dla JDBC trzeba stworzy\u0107 klas\u0119 DAO (Data Access Object) &#8211; oddzieln\u0105 dla ka\u017cdej tabeli w bazie danych. Klasa DAO b\u0119dzie zawiera\u0142a operacje CRUD na tabeli, dla SQL b\u0119d\u0105, to INSERT, SELECT, UPDATE oraz DELETE.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"xml\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;?xml version='1.0' encoding='utf-8'?>\n&lt;!DOCTYPE hibernate-configuration PUBLIC\n        \"-\/\/Hibernate\/Hibernate Configuration DTD 3.0\/\/EN\"\n        \"http:\/\/www.hibernate.org\/dtd\/hibernate-configuration-3.0.dtd\">\n&lt;hibernate-configuration>\n    &lt;session-factory>\n        &lt;!-- Database connection settings -->\n        &lt;property name=\"connection.driver_class\">org.h2.Driver&lt;\/property>\n        &lt;property name=\"connection.url\">jdbc:h2:~\/hibernate-database&lt;\/property>\n        &lt;property name=\"connection.username\">sa&lt;\/property>\n        &lt;property name=\"connection.password\">&lt;\/property>\n        &lt;!-- JDBC connection pool (use the built-in) -->\n        &lt;property name=\"connection.pool_size\">1&lt;\/property>\n        &lt;!-- SQL dialect -->\n        &lt;property name=\"dialect\">org.hibernate.dialect.H2Dialect&lt;\/property>\n        &lt;!-- Echo all executed SQL to stdout -->\n        &lt;property name=\"show_sql\">true&lt;\/property>\n        &lt;!-- Drop and re-create the database schema on startup -->\n        &lt;property name=\"hbm2ddl.auto\">create&lt;\/property>\n\n        &lt;!-- Names the annotated entity class -->\n        &lt;!-- NOTE: package name shortened for readability -->\n        &lt;mapping class=\"pl.juniorjavadeveloper.java.orm_jdbc.UserEntity\"\/>\n    &lt;\/session-factory>\n&lt;\/hibernate-configuration><\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Dla Hibernate ORM trzeba jednorazowo stworzy\u0107 plik konfiguracyjny dla po\u0142\u0105czenia z baz\u0105 danych oraz utrwalanych encji. <\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import jakarta.persistence.Column;\nimport jakarta.persistence.Entity;\nimport jakarta.persistence.GeneratedValue;\nimport jakarta.persistence.Id;\n\n@Entity\n@Table(name = \"USERS\")\npublic class UserEntity {\n    @Id\n    @GeneratedValue\n    private Long id;\n\n    @Column(unique = true)\n    private String login;\n    private String password;\n\n    @Column(name = \"FIRST_NAME\")\n    private String firstName;\n    @Column(name = \"LAST_NAME\")\n    private String lastName;\n\n    public UserEntity() {\n    }\n\n    public UserEntity(String login, String password) {\n        this.login = login;\n        this.password = password;\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">W Hibernate operujemy poj\u0119ciem <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">@Entity<\/code>, kt\u00f3re pozwalaj\u0105 za pomoc\u0105 adnotacji odwzorowa\u0107 elementy klasy Java (r\u00f3wnie\u017c POJO) na struktur\u0119 tabeli w bazie danych. Dla powy\u017cszej encji Hibernate automatycznie stworzy tabel\u0119 o nazwie USERS.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">public class UserEntityDao {\n    private static SessionFactory sessionFactory;\n\n    \/\/ NOTE: this code must be moved to a separate class and then should be reused!\n    static {\n        StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()\n                .configure(\"hibernate.cfg.xml\")\n                .build();\n        try {\n            sessionFactory = new MetadataSources(serviceRegistry)\n                    .buildMetadata()\n                    .buildSessionFactory();\n        } catch (Exception e) {\n            e.printStackTrace();\n            StandardServiceRegistryBuilder.destroy(serviceRegistry);\n        }\n    }\n\n    public void create(UserEntity userEntity) {\n        Session session = sessionFactory.openSession();\n        session.beginTransaction();\n        session.save(userEntity);\n        session.getTransaction().commit();\n        session.close();\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">DAO dla Hibernate b\u0119dzie u\u017cywa\u0107 poj\u0119cia sesji oraz transakcji, kt\u00f3re b\u0119d\u0105 &#8220;oplata\u0142y&#8221; operacje CRUD na obiektach encji. Dla r\u00f3\u017cnych encji, np.: Student, Notebook, Employee b\u0119d\u0105 u\u017cywane te same metody do operacji na encjach, np.: SQL INSERT, to metoda save().<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"properties_zamiast_spring_value\"><strong>Java Properties zamiast Spring @Value.<\/strong> Korzystaj\u0105c z dobrodziejstwa Spring Framework mo\u017cna \u0142atwo pomin\u0105\u0107 fakt, \u017ce pewne elementy konfiguracyjne w pliku application.properties musz\u0105 by\u0107 w jaki\u015b spos\u00f3b za\u0142adowane i odczytane. Do tego dochodzi fakt, \u017ce takie elementy konfiguracyjne musz\u0105 by\u0107 r\u00f3\u017cne dla r\u00f3\u017cnych \u015brodowisk, np. dev, test, prod. Poni\u017cej prezentuj\u0119 czysto Javowe rozwi\u0105zanie w kwestii odczytu klucz\/warto\u015b\u0107 z plik\u00f3w properties oraz jego wykorzystanie w DAO z u\u017cyciem JDBC.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import java.io.IOException;\nimport java.util.Properties;\n\npublic class JdbcPropertiesHelper {\n    private static final Properties properties = new Properties();\n\n    static {\n        try {\n            properties.load(ClassLoader.getSystemClassLoader()\n                    .getResourceAsStream(\"jdbc.properties\"));\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n    }\n\n    public static String getProperty(String key) {\n        return properties.getProperty(key);\n    }\n\n    public static String getProperty(String key, String defaultValue) {\n        return properties.getProperty(key, defaultValue);\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Powy\u017cej przyk\u0142adowa implementacja w\u0142asnego mechanizmu odczytu plik\u00f3w properties.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/\/ JdbcPropertiesHelper example usage in EmployeeModelDao.\ntry (Connection connection = DriverManager.getConnection(\n        JdbcPropertiesHelper.getProperty(\"jdbc.url\"),\n        JdbcPropertiesHelper.getProperty(\"jdbc.username\"),\n        JdbcPropertiesHelper.getProperty(\"jdbc.password\"));\n     PreparedStatement preparedStatement =\n             connection.prepareStatement(INSERT_EMPLOYEE_SQL,\n                     Statement.RETURN_GENERATED_KEYS)) {\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Odczyt parametr\u00f3w konfiguracji po\u0142\u0105czenia z baz\u0105 danych za pomoc\u0105 plik\u00f3w properties pozwala nam odseparowa\u0107 si\u0119 od konfiguracji oraz dostarczy\u0107 klucz\/warto\u015b\u0107 dla r\u00f3\u017cnych \u015brodowisk, np.: dev, test.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import org.springframework.beans.factory.annotation.Value;\nimport org.springframework.context.annotation.PropertySource;\nimport org.springframework.stereotype.Component;\n\n@Component\n@PropertySource(\"classpath:jdbc.properties\")\npublic class SimpleSpringValueProperties {\n    @Value(\"${jdbc.url}\")\n    private String jdbcUrl;\n    @Value(\"${jdbc.username}\")\n    private String username;\n    @Value(\"${jdbc.password}\")\n    private String password;\n\n    \/\/ getters\/setters\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Powy\u017cej kod pokazuj\u0105cy jak \u0142atwo i auto-magicznie odczytywanie klucz\/warto\u015b\u0107 mo\u017cna zaimplementowa\u0107 w Spring Framework.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"nakladanie_di_oop\"><strong>&#8220;Nak\u0142adanie&#8221; Spring DI w czystym OOP.<\/strong> Na temat &#8220;DI w czystym OOP&#8221; pisa\u0142em ju\u017c w artykule <a rel=\"noreferrer noopener\" href=\"https:\/\/www.juniorjavadeveloper.pl\/en\/2023\/01\/19\/trzy-trojce-programistyczne-jak-ulatwic-poczatki-programowania\/#trzy-elementy-wspierajace-programowanie-obiektowe\" data-type=\"URL\" data-id=\"https:\/\/www.juniorjavadeveloper.pl\/2023\/01\/19\/trzy-trojce-programistyczne-jak-ulatwic-poczatki-programowania\/#trzy-elementy-wspierajace-programowanie-obiektowe\" target=\"_blank\">Trzy tr\u00f3jce programistyczne \u2013 jak u\u0142atwi\u0107 pocz\u0105tki programowania<\/a>, wykorzystam przedstawione tam klasy Java, aby doda\u0107 elementy Springa. Dlaczego u\u017cy\u0142em @Scope(value = &#8220;prototype&#8221;) ? &#8211; <a rel=\"noreferrer noopener\" href=\"https:\/\/docs.spring.io\/spring-framework\/docs\/current\/reference\/html\/core.html#beans-factory-scopes\" target=\"_blank\">https:\/\/docs.spring.io\/spring-framework\/docs\/current\/reference\/html\/core.html#beans-factory-scopes<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import org.springframework.context.annotation.Scope;\nimport org.springframework.stereotype.Component;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.logging.Logger;\n\n@Component\n@Scope(value = \"prototype\")\npublic class Notebook {\n\n    protected int pages;\n    protected int currentPage;\n    protected Map&lt;Integer, String> contents = new HashMap&lt;>();\n\n    \/\/ NOTE: skipped methods for code clarity.\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Powy\u017cej zwyk\u0142a  klasa Java &#8220;zamieniona&#8221; na @Component, Bean Springowy. Kod w Spring Framework, kt\u00f3ry na\u0142o\u017cy\u0142em na przyk\u0142ad z kodem w czystej Javie.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">@Component\n@Scope(value = \"prototype\")\npublic class Student {\n\n    private final Notebook notebook;\n\n    public Student(Notebook notebook) {\n        this.notebook = notebook;\n    }\n\n    \/\/ NOTE: skipped methods for code clarity.\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Powy\u017cej zwyk\u0142a  klasa Java &#8220;zamieniona&#8221; na @Component, Bean Springowy.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"spring_bez_spring_boot\"><strong>Spring Framework bez Spring Boot.<\/strong> Dla powy\u017cszego kodu idealnie mo\u017cna przedstawi\u0107 aplikacj\u0119 napisan\u0105 z u\u017cyciem Spring Framework, ale bez wykorzystania Spring Boot. Tak, mo\u017cna tworzy\u0107 aplikacje w &#8220;czystym&#8221; Spring Framework bez u\u017cycia Spring Boot, kiedy\u015b by\u0142a, to jedyna dost\u0119pna opcja. Obecnie, to podej\u015bcie mo\u017cna wykorzysta\u0107 do nieszablonowego po\u0142\u0105czenia aplikacji napisanych w j\u0119zyku Java, np.: Spring Framework + <a href=\"https:\/\/en.wikipedia.org\/wiki\/JavaFX\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/JavaFX\" target=\"_blank\" rel=\"noreferrer noopener\">JavaFX<\/a> &#8211; funkcjonalno\u015b\u0107 DI i IoC w po\u0142\u0105czeniu z aplikacj\u0105 typu desktop. <\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import org.springframework.context.ApplicationContext;\nimport org.springframework.context.annotation.AnnotationConfigApplicationContext;\n\npublic class SpringApplicationWithoutSpringBoot {\n    public static void main(String[] args) {\n        ApplicationContext applicationContext =\n                new AnnotationConfigApplicationContext(\n                        \"pl.juniorjavadeveloper.java.juniortransitionmid\" +\n                                \".deepunderstanding.spring\");\n\n        Student firstStudentBean = applicationContext.getBean(Student.class);\n        firstStudentBean.notebookPages(100);\n\n        Student secondStudentBean = applicationContext.getBean(Student.class);\n        secondStudentBean.notebookPages(60);\n        secondStudentBean.startNote(\"Hello World!\", 11);\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Powy\u017cej kod Java tworz\u0105cy kontekst aplikacji Spring <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">ApplicationContext<\/code> dla opcji z adnotacjami <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">AnnotationConfigApplicationContext<\/code>. Po stworzeniu kontekstu aplikacji, dost\u0119p do Bean\u00f3w Springowych uzyskujemy za pomoc\u0105 metody <code data-enlighter-language=\"java\" class=\"EnlighterJSRAW\">getBean()<\/code>.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"raw\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">kwi 10, 2023 9:14:36 PM pl.jjd.j.j.d.spring.di_oop.Student notebookPages\nINFO: notebookPages(100)\nkwi 10, 2023 9:14:36 PM pl.jjd.java.j.d.spring.di_oop.Notebook setPages\nINFO: setPages(100)\nkwi 10, 2023 9:14:36 PM pl.jjd.java.j.d.spring.di_oop.Student notebookPages\nINFO: notebookPages(60)\nkwi 10, 2023 9:14:36 PM pl.jjd.java.j.d.spring.di_oop.Notebook setPages\nINFO: setPages(60)\nkwi 10, 2023 9:14:36 PM pl.jjd.java.j.d.spring.di_oop.Student startNote\nINFO: startNote(Hello World!, 11)\nkwi 10, 2023 9:14:36 PM pl.jjd.java.j.d.spring.di_oop.Notebook goToPage\nINFO: startNote(11)\nkwi 10, 2023 9:14:36 PM pl.jjd.java.j.d.spring.di_oop.Notebook writeNoteContent\nINFO: writeNoteContent(Hello World!)\nkwi 10, 2023 9:14:36 PM pl.jjd.java.j.d.spring.di_oop.Notebook writeNoteContent\nINFO: Notebook - append note content to the current page: Hello World!\n\nProcess finished with exit code 0\n<\/pre>\n<\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-wide\"\/>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"junit_mocking_tdd\">Testy jednostkowe, mockowanie, idealnie <a href=\"https:\/\/en.wikipedia.org\/wiki\/Test-driven_development\" data-type=\"URL\" data-id=\"https:\/\/en.wikipedia.org\/wiki\/Test-driven_development\" target=\"_blank\" rel=\"noreferrer noopener\">TDD<\/a>. Zapomnij o &#8220;testowaniu kodu&#8221; za pomoc\u0105 metody main(). Pisanie test\u00f3w jednostkowych, to podstawa, je\u017celi &#8220;chcemy spa\u0107 spokojnie&#8221;. Je\u017celi kto\u015b pisze testy jednostkowe, to znaczy, \u017ce rozumie tworzony system informatyczny. Kole\u017canka, kolega z zespo\u0142u, dwa razy si\u0119 zastanowi zanim zmodyfikuje kod \u017ar\u00f3d\u0142owy, a modyfikacja spowoduje b\u0142\u0119dy w testach &#8211; chyba, \u017ce znaj\u0105 i stosuj\u0105 &#8220;model Du\u0144ski&#8221; w testach \ud83d\ude09 <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Je\u017celi chcemy przetestowa\u0107 czy dzia\u0142a nowo dodana encja Hibernate, to szale\u0144stwem jest budowanie, uruchamianie aplikacji, nast\u0119pnie logowanie si\u0119 do systemu, aby wpisa\u0107 dane w formularzu na stronie web, a koniec \u015bledzenie b\u0142\u0119d\u00f3w w logach. W tej sytuacji potrzebne s\u0105 testy jednostkowe b\u0105d\u017a integracyjne. Wi\u0119cej o testach jednostkowych i nie tylko mo\u017cna poczyta\u0107 na <a href=\"https:\/\/martinfowler.com\/testing\/\">https:\/\/martinfowler.com\/testing\/<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">W sytuacji, kiedy nie mamy dost\u0119pu do us\u0142ug zewn\u0119trznych, np.: api firmy trzeciej, a nasz kod \u017ar\u00f3d\u0142owy, tego wymaga, to piszemy testy z wykorzystaniem mock\u00f3w. Nie jest, to \u0142atwe, ale je\u017celi raz poznamy ide\u0119 mockowania, to b\u0119dzie nam du\u017co \u0142atwiej. Najcz\u0119\u015bciej po prostu nie chemy modyfikowa\u0107 pewnych zasob\u00f3w, a przetestowa\u0107 nasz nowy kod. Przyk\u0142adem jest mock dla repository w service.<\/p>\n\n\n\n<div class=\"wp-block-columns alignwide are-vertically-aligned-center is-layout-flex wp-container-core-columns-is-layout-8f761849 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-vertically-aligned-center is-layout-flow wp-block-column-is-layout-flow\">\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import org.junit.jupiter.api.Assertions;\nimport org.junit.jupiter.api.Test;\nimport org.mockito.Mockito;\n\nclass EmployeeServiceMockTest {\n\n    private static final long EMPLOYEE_MODEL_ID_1 = 1L;\n\n    @Test\n    void register() {\n        \/\/ given\n        EmployeeModelDao employeeModelDaoMock = Mockito.mock(EmployeeModelDao.class);\n        EmployeeService employeeService = new EmployeeService(employeeModelDaoMock);\n\n        EmployeeModel employeeModel = new EmployeeModel(null, \"Tim\", \"Cook\", \"Sales\");\n        EmployeeModel registeredEmployeeModelMock = \n                new EmployeeModel(EMPLOYEE_MODEL_ID_1, \"Tim\", \"Cook\", \"Sales\");\n\n        \/\/ when\n        Mockito.when(employeeService.register(employeeModel))\n                .thenReturn(registeredEmployeeModelMock);\n        EmployeeModel registeredEmployeeModel = \n                employeeService.register(employeeModel);\n\n        \/\/ then\n        Assertions.assertAll(\n                () -> Assertions.assertNotNull(registeredEmployeeModel,\n                        \"registeredEmployeeModel is NULL\"),\n                () -> Assertions.assertNotNull(registeredEmployeeModel.getId(),\n                        \"registeredEmployeeModel ID is NULL\"),\n                () -> Assertions.assertEquals(EMPLOYEE_MODEL_ID_1, \n                        registeredEmployeeModel.getId(),\n                        \"registeredEmployeeModel ID is not equals\")\n        );\n    }\n}<\/pre>\n<\/div>\n<\/div>\n\n\n\n<p class=\"wp-block-paragraph\">Powy\u017cszy kod \u017ar\u00f3d\u0142owy prezentuje test jednostkowy z u\u017cyciem mock\u00f3w<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"rozbicie_problemu\"><em>Rozbicie, wyizolowanie istoty problemu do postaci nowego oddzielnego projektu.<\/em> Temat bardzo obszerny, a sposob\u00f3w na jego rozwi\u0105zanie wiele. Dlatego nie b\u0119d\u0119 przedstawia\u0142 kodu \u017ar\u00f3d\u0142owego, ale chc\u0119 umie\u015bci\u0107 ten punkt w moim artykule z prostego powodu. Na co dzie\u0144 w pracy programi\u015bci, programistki zajmuj\u0105 si\u0119 du\u017cymi i z\u0142o\u017conymi systemami, kt\u00f3re maj\u0105 wiele zale\u017cno\u015bci. Skupiaj\u0105c si\u0119 na jednym konkretnym wycinku tracimy z oczy szerszy kontekst.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Dla przyk\u0142adu, w projekcie do istniej\u0105cych @Entity mamy doda\u0107 now\u0105 encj\u0119<\/strong>, kt\u00f3ra b\u0119dzie mia\u0142a zale\u017cno\u015bci do ju\u017c istniej\u0105cych encji. Dodajemy jedn\u0105 tylko klas\u0119 encji i relacj\u0119, a projekt przestaje nam dzia\u0142a\u0107. Kontekst Springa nie inicjalizuje si\u0119, Hibernate m\u00f3wi, \u017ce nie &#8220;widzi&#8221; encji, kt\u00f3r\u0105 dodali\u015bmy.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Co ja bym zrobi\u0142 w takim przypadku?<\/strong> Wygenerowa\u0142 nowy projekt na start.spring.io, u\u017cy\u0142 IntelliJ w wersji Community, doda\u0142 minimalny zestaw zale\u017cno\u015bci, w tym przypadku spring-boot-starter-data-jpa. Skopiowa\u0142 bym utworz\u0105n\u0105 przeze mnie encj\u0119 oraz niezb\u0119dne encje zale\u017cne. Stworzy\u0142bym testy jednostkowe &#8220;dla encji&#8221;. Nast\u0119pnie sukcesywnie dodawa\u0142 bym kolejne elementy zale\u017cne, np.: repository, service.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Mo\u017ce, to si\u0119 wydawa\u0107 strat\u0105 czasu, ale w d\u0142u\u017cszej perspektywie, tak nie jest. Maj\u0105c na uwadze powy\u017csze, zak\u0142adam, \u017ce w trakcie tworzenia nowego projektu zg\u0142\u0119biam wiedz\u0119 na temat Hibernate, JUnit, Spring Context. Rzadko kiedy mamy szans\u0119 stworzy\u0107 projekt od nowa, dodawa\u0107 w nim pocz\u0105tkowe elementy. W wi\u0119kszo\u015bci przypadk\u00f3w &#8220;l\u0105dujemy&#8221; w istniej\u0105cym projekcie. <\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Dlaczego IntelliJ w wersji Community? Zaczn\u0119 od mojego ulubionego zdania w tym temacie, IntelliJ Ultimate rozleniwia i jest nadgorliwy &#8211; za du\u017co rzeczy robi za nas i za du\u017co podpowiada. Na etapie Junior i przej\u015bcia na Mid-Level Java Developer zalecam moim uczniom stosowanie IntelliJ Community. Je\u017celi mamy ju\u017c sporo do\u015bwiadczenia i wiedz\u0119 na temat framework\u00f3w i stosowanych technologii, to IntelliJ Ultimate bardzo pomaga. Chocia\u017c samemu ca\u0142y czas u\u017cywam IntelliJ w wersji Community.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"zadania_na_codewars\"><em>Zadania na <a rel=\"noreferrer noopener\" href=\"https:\/\/www.codewars.com\/\" data-type=\"URL\" data-id=\"https:\/\/www.codewars.com\/\" target=\"_blank\">https:\/\/www.codewars.com\/<\/a><\/em> &#8211; <strong>odskocznia od &#8220;nadmiaru kodu&#8221; &#8211; warstwy, loggery, frameworki &#8211; czysty, jednolinijkowy kod \u017ar\u00f3d\u0142owy<\/strong>. To tutaj mo\u017cemy zweryfikowa\u0107 nasze umiej\u0119tno\u015bci programistyczne, sprawdzi\u0107, co mamy jeszcze do poprawy, a co do nauki od zera. Bez goni\u0105cych nas termin\u00f3w w projekcie i masy codziennych rozm\u00f3w z programistami i osobami zlecaj\u0105cymi napisanie kodu \u017ar\u00f3d\u0142owego.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"wyzwania_na_challengerocket\"><em>Wyzwania na <a rel=\"noreferrer noopener\" href=\"https:\/\/challengerocket.com\/\" data-type=\"URL\" data-id=\"https:\/\/challengerocket.com\/\" target=\"_blank\">https:\/\/challengerocket.com\/<\/a><\/em> &#8211; <strong>ChallengeRocket offers a new formula to hire outstanding candidates with IT, analytical, tech and financial skills<\/strong>. W tym miejscu mo\u017cemy znale\u017a\u0107 zatrudnienie realizuj\u0105c wyzwania programistyczne. Weryfikuj\u0105c i \u0107wicz\u0105c nasze umiej\u0119tno\u015bci programistyczne na prawdziwych zadaniach, a nie na CRUD z formularzem HTML.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"get_trained_careerkarma\"><em><strong>&#8220;Get Trained For The Future, Today&#8221;<\/strong><\/em> &#8211; <a rel=\"noreferrer noopener\" href=\"https:\/\/careerkarma.com\/\" target=\"_blank\">https:\/\/careerkarma.com\/<\/a> &#8211; Career Karma gives you the information, tools and support to figure out the skills you need today that will get you the job you want in the future. <\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity is-style-dots\"\/>\n\n\n\n<p class=\"wp-block-paragraph\">Podsumowuj\u0105c, nie mo\u017cna porusza\u0107 si\u0119 tylko po powierzchni zagadnie\u0144 zwi\u0105zanych z wykorzystywanymi frameowrkami i technologiami. Dobry programista, programistka dobrze znaj\u0105 narz\u0119dzia, kt\u00f3rych u\u017cywaj\u0105. Moim zdaniem przej\u015bcie z Junior na Mid-Level Java Developer nie powinno by\u0107 &#8220;nominowane z urz\u0119du, ze wzgl\u0119du na ilo\u015b\u0107 przepracowanych lat&#8221;. Powinno nast\u0119powa\u0107 w &#8220;naturalny spos\u00f3b&#8221; wynikaj\u0105cy z ilo\u015bci oraz r\u00f3\u017cnorodno\u015bci projekt\u00f3w, w kt\u00f3rych uczestniczy\u0142a dana osoba.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-poradnik-dla-przysz-ych-junior-java-developer-039-w wp-block-embed-poradnik-dla-przysz-ych-junior-java-developer-039-w\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"UK08AKBkOk\"><a href=\"https:\/\/www.juniorjavadeveloper.pl\/en\/kontakt\/\">Contact<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"\u201eKontakt\u201d \u2014 Poradnik dla przysz\u0142ych Junior Java Developer&amp;apos;\u00f3w\" src=\"https:\/\/www.juniorjavadeveloper.pl\/kontakt\/embed\/#?secret=rMXW1ULxgA#?secret=UK08AKBkOk\" data-secret=\"UK08AKBkOk\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-poradnik-dla-przysz-ych-junior-java-developer-039-w wp-block-embed-poradnik-dla-przysz-ych-junior-java-developer-039-w\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"ReGhr571UK\"><a href=\"https:\/\/www.juniorjavadeveloper.pl\/en\/mentoring-rezerwuj-termin\/\">Mentoring - book an appointment<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"\u201eMentoring \u2013 rezerwuj termin\u201d \u2014 Poradnik dla przysz\u0142ych Junior Java Developer&amp;apos;\u00f3w\" src=\"https:\/\/www.juniorjavadeveloper.pl\/mentoring-rezerwuj-termin\/embed\/#?secret=5lxWHTa4DM#?secret=ReGhr571UK\" data-secret=\"ReGhr571UK\" width=\"600\" height=\"338\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Zdj\u0119cie autorstwa <a href=\"https:\/\/www.pexels.com\/photo\/a-close-up-shot-of-letter-dice-on-an-open-notebook-6120220\/\" data-type=\"URL\" data-id=\"https:\/\/www.pexels.com\/photo\/a-close-up-shot-of-letter-dice-on-an-open-notebook-6120220\/\" target=\"_blank\" rel=\"noreferrer noopener\">Nataliya Vaitkevich<\/a> z <a rel=\"noreferrer noopener\" href=\"https:\/\/www.pexels.com\/pl-pl\/\" target=\"_blank\">Pexels<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>Coraz wi\u0119cej os\u00f3b zg\u0142asza si\u0119 do mnie poszukuj\u0105c pomocy w przej\u015bciu ze stanowiska Junior Java Developer na Mid-Level Java Developer. Chc\u0105c pom\u00f3c jak najwi\u0119kszej liczbie os\u00f3b w tym artykule przedstawi\u0119 najcz\u0119\u015bciej zadawane mi pytania oraz moje podej\u015bcie do tematu przej\u015bcia z Junior na Mid-Level Java Developer. Cz\u0119\u015b\u0107 os\u00f3b, kt\u00f3re zg\u0142aszaj\u0105 si\u0119 do mnie czuj\u0105, \u017ce [&hellip;]<\/p>","protected":false},"author":1,"featured_media":2957,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_ppp_document_settings_meta":"","footnotes":"","jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[41,7],"tags":[],"class_list":["post-2847","post","type-post","status-publish","format-standard","has-post-thumbnail","category-mid-level","category-poradnik"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/www.juniorjavadeveloper.pl\/wp-content\/uploads\/2023\/04\/przejscie_junior_na_mid-level_java-developer_mentor-junior-java-developer.jpg","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"_links":{"self":[{"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/posts\/2847","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/comments?post=2847"}],"version-history":[{"count":94,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/posts\/2847\/revisions"}],"predecessor-version":[{"id":4685,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/posts\/2847\/revisions\/4685"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/media\/2957"}],"wp:attachment":[{"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/media?parent=2847"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/categories?post=2847"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.juniorjavadeveloper.pl\/en\/wp-json\/wp\/v2\/tags?post=2847"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}