Commit a7a0531a by Patryk Czarnik

Gotowy projekt "SpringTechnicznie"

parent 53a1f2b2
...@@ -17,6 +17,8 @@ import sklep.model.Product; ...@@ -17,6 +17,8 @@ import sklep.model.Product;
* Np. findByPriceBetween szuka produktów o cenie między min i max. * Np. findByPriceBetween szuka produktów o cenie między min i max.
* *
* findByEmail - szuka rekordów z polem email równym parametrowi. * findByEmail - szuka rekordów z polem email równym parametrowi.
*
* https://www.baeldung.com/spring-data-derived-queries
*/ */
@Repository @Repository
......
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /usr/local/etc/mavenrc ] ; then
. /usr/local/etc/mavenrc
fi
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
if [ -z "$JAVA_HOME" ]; then
if [ -x "/usr/libexec/java_home" ]; then
export JAVA_HOME="`/usr/libexec/java_home`"
else
export JAVA_HOME="/Library/Java/Home"
fi
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Mingw, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`\\unset -f command; \\command -v java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
if [ -z "$1" ]
then
echo "Path not specified to find_maven_basedir"
return 1
fi
basedir="$1"
wdir="$1"
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
if [ -d "${wdir}" ]; then
wdir=`cd "$wdir/.."; pwd`
fi
# end of workaround
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
BASE_DIR=`find_maven_basedir "$(pwd)"`
if [ -z "$BASE_DIR" ]; then
exit 1;
fi
##########################################################################################
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
# This allows using the maven wrapper in projects that prohibit checking in binary data.
##########################################################################################
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found .mvn/wrapper/maven-wrapper.jar"
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
fi
if [ -n "$MVNW_REPOURL" ]; then
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
else
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
fi
while IFS="=" read key value; do
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
esac
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
if [ "$MVNW_VERBOSE" = true ]; then
echo "Downloading from: $jarUrl"
fi
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
if $cygwin; then
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
fi
if command -v wget > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found wget ... using wget"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
else
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
fi
elif command -v curl > /dev/null; then
if [ "$MVNW_VERBOSE" = true ]; then
echo "Found curl ... using curl"
fi
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
curl -o "$wrapperJarPath" "$jarUrl" -f
else
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
fi
else
if [ "$MVNW_VERBOSE" = true ]; then
echo "Falling back to using Java to download"
fi
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
# For Cygwin, switch paths to Windows format before running javac
if $cygwin; then
javaClass=`cygpath --path --windows "$javaClass"`
fi
if [ -e "$javaClass" ]; then
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Compiling MavenWrapperDownloader.java ..."
fi
# Compiling the Java class
("$JAVA_HOME/bin/javac" "$javaClass")
fi
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
# Running the downloader
if [ "$MVNW_VERBOSE" = true ]; then
echo " - Running MavenWrapperDownloader.java ..."
fi
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
fi
fi
fi
fi
##########################################################################################
# End of extension
##########################################################################################
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
if [ "$MVNW_VERBOSE" = true ]; then
echo $MAVEN_PROJECTBASEDIR
fi
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
fi
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
exec "$JAVACMD" \
$MAVEN_OPTS \
$MAVEN_DEBUG_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" \
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{"^
"$webclient = new-object System.Net.WebClient;"^
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
"}"^
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
"}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% ^
%JVM_CONFIG_MAVEN_PROPS% ^
%MAVEN_OPTS% ^
%MAVEN_DEBUG_OPTS% ^
-classpath %WRAPPER_JAR% ^
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%"=="on" pause
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
cmd /C exit /B %ERROR_CODE%
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>PC31-SpringTechnicznie</artifactId>
<version>1.0</version>
<name>PC31-SpringTechnicznie</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
package com.example.demo;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HelloController {
@RequestMapping("/")
public String root() {
return "index.html";
}
@RequestMapping("/hello")
public String hello(Model model) {
model.addAttribute("txt", "Hello world!");
model.addAttribute("time", LocalTime.now());
return "hello.html";
}
@RequestMapping("/ping")
public String ping(HttpServletRequest request, Model model) {
// Do modelu można też dodać słownik / mapę.
// Odczyt wartości wygląda później np. tak ${clientInfo.userAgent}
String ip = request.getRemoteAddr();
System.out.println("Zapytanie z adresu " + ip);
model.addAttribute("clientInfo", Map.of(
"userAgent", request.getHeader("User-Agent"),
"ip", ip,
"data", LocalDateTime.now()
));
return "ping.html";
}
}
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringTechnicznieApplication {
public static void main(String[] args) {
SpringApplication.run(SpringTechnicznieApplication.class, args);
}
}
package com.example.demo.data;
import java.util.List;
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 com.example.demo.model.Employee;
@Controller
public class Controller0 {
@Autowired
private Repository0_Memory repository;
@GetMapping("/emps0")
public String showExampleEmployee(Model model) {
List<Employee> emps = repository.findAll();
model.addAttribute("emps", emps);
return "employees.html";
}
}
package com.example.demo.data;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
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 org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.demo.model.Employee;
@Controller
@RequestMapping("/emps1")
public class Controller1_EM {
/* W tej wersji Controller bezpośrednio korzysta z technologii JPA/Hibernate.
* Ułatwieniem jest to, że Spring automatycznie "wstryknie" nam obiekt EntityManager.
*/
@Autowired
private EntityManager em;
@GetMapping
public String showAll(Model model) {
TypedQuery<Employee> query = em.createNamedQuery("Employee.findAll", Employee.class);
List<Employee> emps = query.getResultList();
model.addAttribute("emps", emps);
return "employees.html";
}
@GetMapping("/{id}")
public String showOne(Model model,
@PathVariable("id") Integer employeeId) {
Employee emp = em.find(Employee.class, employeeId);
model.addAttribute("emps", List.of(emp));
return "employees.html";
}
}
package com.example.demo.data;
import java.util.List;
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 org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.example.demo.model.Employee;
@Controller
@RequestMapping("/emps2")
public class Controller2 {
@Autowired
private Repository2 repository;
@GetMapping
public String showAll(Model model) {
List<Employee> emps = repository.findAll();
model.addAttribute("emps", emps);
return "employees.html";
}
@GetMapping("/{id}")
public String showOne(Model model,
@PathVariable("id") Integer employeeId) {
Employee emp = repository.findOne(employeeId);
model.addAttribute("emps", List.of(emp));
return "employees.html";
}
@GetMapping("/by_name")
public String showByName(Model model,
@RequestParam("name") String name) {
List<Employee> emps = repository.findByLastName(name);
model.addAttribute("emps", emps);
return "employees.html";
}
}
package com.example.demo.data;
import java.util.List;
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 org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import com.example.demo.model.Employee;
@Controller
@RequestMapping("/emps3")
public class Controller3 {
/* Aby bezpośrednio w Controllerze nie używać kodów dot. Hibernate, SQL itd...
* wydzielam operacje bazodanowe do oddzielnej klasy, opisanej jako Repository
* i wstrzykuję referencję do repozytorium tutaj w controllerze.
* W doatku robię to porzez interfejs (zgodne z najlepszymi praktykami Springa),
* aby ułatwić podmianę implementacji na inną.
*/
@Autowired
private Repository3_Interface repository;
@GetMapping
public String showAll(Model model) {
List<Employee> emps = repository.findAll();
model.addAttribute("emps", emps);
return "employees.html";
}
@GetMapping("/{id}")
public String showOne(Model model,
@PathVariable("id") Integer employeeId) {
Employee emp = repository.findOne(employeeId);
model.addAttribute("emps", List.of(emp));
return "employees.html";
}
@GetMapping("/by_name")
public String showByName(Model model,
@RequestParam("name") String name) {
List<Employee> emps = repository.findByLastName(name);
model.addAttribute("emps", emps);
return "employees.html";
}
}
package com.example.demo.data;
import java.util.List;
import java.util.Optional;
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 org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import com.example.demo.model.Employee;
@Controller
@RequestMapping("/emps4")
public class Controller4 {
@Autowired
private Repository4 repository;
@GetMapping
public String showAll(Model model) {
List<Employee> emps = repository.findAll();
model.addAttribute("emps", emps);
return "employees.html";
}
@GetMapping("/{id}")
public String showOne(Model model,
@PathVariable("id") Integer employeeId) {
Optional<Employee> emp = repository.findById(employeeId);
List<Employee> emps;
if (emp.isPresent()) {
emps = List.of(emp.get());
} else {
emps = List.of();
}
model.addAttribute("emps", emps);
return "employees.html";
}
}
package com.example.demo.data;
import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;
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 org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import com.example.demo.model.Employee;
@Controller
@RequestMapping("/emps5")
public class Controller5 {
@Autowired
private Repository5 repository;
@GetMapping("/all")
public String showAll(Model model) {
List<Employee> emps = repository.findAll();
model.addAttribute("emps", emps);
return "employees.html";
}
@GetMapping("/by_id/{id}")
public String showOne(Model model,
@PathVariable("id") Integer employeeId) {
Optional<Employee> emp = repository.findById(employeeId);
List<Employee> emps;
if (emp.isPresent()) {
emps = List.of(emp.get());
} else {
emps = List.of();
}
model.addAttribute("emps", emps);
return "employees.html";
}
@GetMapping("/by_name")
public String showByName(Model model,
@RequestParam("name") String name) {
List<Employee> emps = repository.findByLastName(name);
model.addAttribute("emps", emps);
return "employees.html";
}
// http://localhost:8080/emps5/by_job/IT_PROG
@GetMapping("/by_job/{job}")
public String getEmployeesByJobId(Model model,
@PathVariable("job") String jobId) {
List<Employee> emps = repository.findByJob_JobId(jobId);
model.addAttribute("emps", emps);
return "employees.html";
}
// http://localhost:8080/emps5/by_city/Oxford
@GetMapping("/by_city/{city}")
public String getEmployeesByCity(Model model,
@PathVariable("city") String city) {
List<Employee> emps = repository.findByDepartment_Location_City(city);
model.addAttribute("emps", emps);
return "employees.html";
}
// http://localhost:8080/emps5/by_salary?min=5000&max=10000
@GetMapping("/by_salary")
public String getEmployeesBySalary(Model model,
@RequestParam(name="min", defaultValue="0") BigDecimal min,
@RequestParam(name="max", defaultValue="1000000000") BigDecimal max) {
List<Employee> employees = repository.findBySalary(min, max);
model.addAttribute("emps", employees);
return "employees.html";
}
@GetMapping("/by_year/{year}")
public String getEmployeesByYear(Model model,
@PathVariable("year") int year) {
List<String> names = repository.namesByYear(year);
model.addAttribute("names", names);
return "names.html";
}
@GetMapping("/zara")
public String zarabiajacy(Model model,
@RequestParam("id") int id) {
List<Employee> emps = repository.zarabiajacyWiecejNiz(id);
model.addAttribute("emps", emps);
return "employees.html";
}
@GetMapping("/szef/{id}")
@ResponseBody
public String szef(@PathVariable("id") Integer idPracownika) {
return repository.nazwiskoSzefa(idPracownika);
}
@GetMapping("/save/{id}")
public String modify(Model model,
@PathVariable("id") Integer idPracownika,
@RequestParam(value="salary", required=false) BigDecimal newSalary,
@RequestParam(value="first_name", required=false) String newFirstName,
@RequestParam(value="last_name", required=false) String newLastName) {
Optional<Employee> found = repository.findById(idPracownika);
List<Employee> emps;
if(found.isPresent()) {
Employee emp = found.get();
if(newSalary != null)
emp.setSalary(newSalary);
if(newFirstName != null)
emp.setFirstName(newFirstName);
if(newLastName != null)
emp.setLastName(newLastName);
repository.save(emp);
emps = List.of(emp);
} else {
emps = List.of();
}
model.addAttribute("emps", emps);
return "employees.html";
}
@GetMapping("/move/{id}")
@ResponseBody
public String modify(Model model,
@PathVariable("id") Integer idPracownika,
@RequestParam(value="dep", required=false) int newDep,
@RequestParam(value="job", required=false) String newJob) {
repository.moveEmployee(idPracownika, newDep, newJob);
return "Przeniesiono";
}
}
package com.example.demo.data;
import java.math.BigDecimal;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.example.demo.model.Department;
import com.example.demo.model.Employee;
import com.example.demo.model.Job;
import com.example.demo.model.Location;
/* Klasa pełniąca rolę repozytoium, czyli dostraczanie danych,
* ale zaimplementowana bez bazy danych - po prostu zwraca przykładowe obiekty.
*/
@Repository
public class Repository0_Memory {
public List<Employee> findAll() {
Employee emp = exampleEmployee1();
return List.of(emp);
}
private Employee exampleEmployee1() {
Employee emp = new Employee();
emp.setFirstName("Jan");
emp.setLastName("Kowalski");
emp.setSalary(BigDecimal.valueOf(12345));
emp.setJob(exampleJob());
emp.setDepartment(exampleDepartment());
return emp;
}
private Department exampleDepartment() {
Location loc = new Location();
loc.setCity("Warszawa");
Department dep = new Department();
dep.setDepartmentName("Szkolenia");
dep.setLocation(loc);
return dep;
}
private Job exampleJob() {
Job job = new Job();
job.setJobTitle("Trainer");
return job;
}
}
package com.example.demo.data;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.example.demo.model.Employee;
@Repository
public class Repository2 {
@Autowired
private EntityManager em;
public List<Employee> findAll() {
TypedQuery<Employee> query = em.createNamedQuery("Employee.findAll", Employee.class);
List<Employee> emps = query.getResultList();
return emps;
}
public Employee findOne(int employeeId) {
return em.find(Employee.class, employeeId);
}
public List<Employee> findByLastName(String lastName) {
TypedQuery<Employee> query = em.createQuery(
"SELECT emp FROM Employee emp WHERE emp.lastName = :name", Employee.class);
query.setParameter("name", lastName);
List<Employee> emps = query.getResultList();
return emps;
}
}
package com.example.demo.data;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.example.demo.model.Employee;
@Repository
public class Repository3_Impl implements Repository3_Interface {
@Autowired
private EntityManager em;
@Override
public List<Employee> findAll() {
TypedQuery<Employee> query = em.createNamedQuery("Employee.findAll", Employee.class);
List<Employee> emps = query.getResultList();
return emps;
}
@Override
public Employee findOne(int employeeId) {
return em.find(Employee.class, employeeId);
}
@Override
public List<Employee> findByLastName(String lastName) {
TypedQuery<Employee> query = em.createQuery(
"SELECT emp FROM Employee emp WHERE emp.lastName = :name", Employee.class);
query.setParameter("name", lastName);
List<Employee> emps = query.getResultList();
return emps;
}
}
package com.example.demo.data;
import java.util.List;
import com.example.demo.model.Employee;
public interface Repository3_Interface {
List<Employee> findAll();
Employee findOne(int employeeId);
List<Employee> findByLastName(String lastName);
}
\ No newline at end of file
package com.example.demo.data;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import com.example.demo.model.Employee;
@Repository
public interface Repository4 extends JpaRepository<Employee, Integer> {
// Spring sam tworzy instancję tego interfejsu, która zawiera implementację wszystkich standardowych metod
}
package com.example.demo.data;
import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.example.demo.model.Employee;
@Repository
public interface Repository5 extends JpaRepository<Employee, Integer> {
List<Employee> findByLastName(String name);
List<Employee> findByJob_JobId(String jobId);
// employee.getDepartment().getLocation().getCity()
// ale w zapytaniu zostanie to zamienione na SQL, który JOIN-em dołącza tabele departments i locations i w WHERE sprawdza city
List<Employee> findByDepartment_Location_City(String city);
// Zapytanie w składni JPQL
@Query("SELECT emp FROM Employee emp WHERE emp.salary BETWEEN :min AND :max ORDER BY emp.salary")
List<Employee> findBySalary(BigDecimal min, BigDecimal max);
@Query(nativeQuery=true,
value="SELECT first_name || ' ' || last_name"
+ " FROM employees"
+ " WHERE extract(year FROM hire_date) = :year"
+ " ORDER BY last_name")
List<String> namesByYear(int year);
// W ramach takiego interfejsu można też pisać metody z własną implementacją.
// Tu przykład już nie bazodanowy...
default List<Integer> losowe(int limit, int ilosc) {
return ThreadLocalRandom.current().ints(ilosc, 0, limit).boxed().collect(Collectors.toList());
}
// podobno tak wygląda wywołanie procedury składowanej, ale nam nie działa
@Query(nativeQuery=true, value="CALL przenies_pracownika(:idPracownika, :newDep, :newJob)")
void moveEmployee(Integer idPracownika, int newDep, String newJob);
@Query(nativeQuery=true, value="SELECT zarabiajacy_wiecej_niz(:id)")
List<Employee> zarabiajacyWiecejNiz(int id);
@Query(nativeQuery=true, value="SELECT nazwisko_szefa(:idPracownika)")
String nazwiskoSzefa(Integer idPracownika);
}
package com.example.demo.licznik;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
@Controller
public class AController1 {
@GetMapping("/test0")
public String test0() {
return "licznik.html";
}
@GetMapping("/test1")
public String test1(Model model) {
model.addAttribute("licznik", "Ala ma kota, a nie żaden licznik");
return "licznik.html";
}
@GetMapping("/test2")
public String test2(Model model, Licznik licznik) {
// Nawet gdy sami nie dodamy obiektu do modelu, to Spring i tak to zrobi
// model.addAttribute("licznik", licznik);
return "licznik.html";
}
@GetMapping("/test3")
public String test3(@ModelAttribute Licznik licznik) {
// Ta adnotacja mówi jednoznacznie, że ten parametr jest elementem modelu
return "licznik.html";
}
}
package com.example.demo.licznik;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
@Controller
public class AController4 {
@ModelAttribute
public Licznik getLicznik() {
// Gdy w klasie istynieje taka metoda oznaczona @ModelAttribute, to ona zostanie użyta do utworzenia obiektu.
// Jeśli nie ma takiej metody (jak w Controller1), to konstruktor domyślny.
return new Licznik("ModelAttribute z metody", 400);
}
@GetMapping("/test4")
public String test4(@ModelAttribute Licznik licznik) {
return "licznik.html";
}
@GetMapping("/test4a")
public String test4a(Licznik licznik) {
return "licznik.html";
}
}
package com.example.demo.licznik;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;
@Controller
@SessionAttributes({"licznik"})
public class AController5 {
// W tej wersji atrybut modelu żyje w zakresie sesji.
@ModelAttribute
public Licznik getLicznik() {
return new Licznik("v5 z metody", 500);
}
@GetMapping("/test5")
public String test5(@ModelAttribute Licznik licznik) {
return "licznik.html";
}
}
package com.example.demo.licznik;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AController6 {
@Autowired
private LicznikComponent6 licznikComponent6;
@GetMapping("/test6")
public String test6(Model model) {
model.addAttribute("licznik", licznikComponent6.getLicznik());
return "licznik.html";
}
}
package com.example.demo.licznik;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AController7 {
@Autowired
private LicznikComponent7 licznikComponent7;
@GetMapping("/test7")
public String test7(Model model) {
model.addAttribute("licznik", licznikComponent7.getLicznik());
return "licznik.html";
}
}
package com.example.demo.licznik;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class AController8 {
@Autowired
private LicznikBean8 licznikBean8;
@GetMapping("/test8")
public String test8(Model model) {
model.addAttribute("licznik", licznikBean8.getLicznik());
return "licznik.html";
}
}
package com.example.demo.licznik;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class Configuration8 {
// Adnotacja @Bean jest używana na poziomie metody.
// Wynik wywołania tej metody zostanie zapamiętany przez Springa i będzie traktowany jak "bean",
// czyli zostanie wstrzyknięty tam, gdzie będzie go ktoś potrzebował.
// Taka metoda musi być umieszczona w klasie, którą "przeczyta" Spring i wykona takie metody.
// Najczęściej stosuje się klasy oznaczone @Configuration
@Bean
public LicznikBean8 generuj() {
LicznikBean8 wynik = new LicznikBean8();
wynik.setLicznik(new Licznik("bean z konfiguracji", 800));
return wynik;
}
}
package com.example.demo.licznik;
public class Licznik {
private String napis;
private int value;
public Licznik(String napis, int value) {
this.napis = napis;
this.value = value;
}
public Licznik() {
this("default", 0);
}
public synchronized String getNapis() {
return napis;
}
public synchronized void setNapis(String napis) {
this.napis = napis;
}
public synchronized int getValue() {
return ++value;
}
@Override
public String toString() {
return "Licznik [napis: " + getNapis() + ", value: " + getValue() + "]";
}
}
package com.example.demo.licznik;
public class LicznikBean8 {
private Licznik licznik;
public Licznik getLicznik() {
return licznik;
}
public void setLicznik(Licznik licznik) {
this.licznik = licznik;
}
}
package com.example.demo.licznik;
import org.springframework.stereotype.Component;
@Component // albo @Service, @Repository
public class LicznikComponent6 {
private Licznik licznik = new Licznik();
public Licznik getLicznik() {
return licznik;
}
public void setLicznik(Licznik licznik) {
this.licznik = licznik;
}
}
package com.example.demo.licznik;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.stereotype.Component;
@Component
@Scope(scopeName="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class LicznikComponent7 {
private Licznik licznik = new Licznik();
public Licznik getLicznik() {
return licznik;
}
public void setLicznik(Licznik licznik) {
this.licznik = licznik;
}
}
package com.example.demo.model;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the countries database table.
*
*/
@Entity
@Table(name="countries")
@NamedQuery(name="Country.findAll", query="SELECT c FROM Country c")
public class Country implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="country_id")
private String countryId;
@Column(name="country_name")
private String countryName;
//bi-directional many-to-one association to Region
@ManyToOne
@JoinColumn(name="region_id")
private Region region;
public Country() {
}
public String getCountryId() {
return this.countryId;
}
public void setCountryId(String countryId) {
this.countryId = countryId;
}
public String getCountryName() {
return this.countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public Region getRegion() {
return this.region;
}
public void setRegion(Region region) {
this.region = region;
}
}
\ No newline at end of file
package com.example.demo.model;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
/**
* The persistent class for the departments database table.
*
*/
@Entity
@Table(name="departments")
@NamedQuery(name="Department.findAll", query="SELECT d FROM Department d")
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name="DEPARTMENTS_DEPARTMENTID_GENERATOR", sequenceName="DEPARTMENTS_SEQ", allocationSize=10)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="DEPARTMENTS_DEPARTMENTID_GENERATOR")
@Column(name="department_id")
private Integer departmentId;
@Column(name="department_name")
private String departmentName;
@Column(name="manager_id")
private Integer managerId;
//uni-directional many-to-one association to Location
@ManyToOne
@JoinColumn(name="location_id")
private Location location;
//bi-directional many-to-one association to Employee
@OneToMany(mappedBy="department")
private List<Employee> employees;
public Department() {
}
public Integer getDepartmentId() {
return this.departmentId;
}
public void setDepartmentId(Integer departmentId) {
this.departmentId = departmentId;
}
public String getDepartmentName() {
return this.departmentName;
}
public void setDepartmentName(String departmentName) {
this.departmentName = departmentName;
}
public Integer getManagerId() {
return this.managerId;
}
public void setManagerId(Integer managerId) {
this.managerId = managerId;
}
public Location getLocation() {
return this.location;
}
public void setLocation(Location location) {
this.location = location;
}
public List<Employee> getEmployees() {
return this.employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public Employee addEmployee(Employee employee) {
getEmployees().add(employee);
employee.setDepartment(this);
return employee;
}
public Employee removeEmployee(Employee employee) {
getEmployees().remove(employee);
employee.setDepartment(null);
return employee;
}
}
\ No newline at end of file
package com.example.demo.model;
import java.io.Serializable;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;
/**
* The persistent class for the employees database table.
*
*/
@Entity
@Table(name="employees")
@NamedQuery(name="Employee.findAll", query="SELECT e FROM Employee e")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name="EMPLOYEES_EMPLOYEEID_GENERATOR", sequenceName="EMPLOYEES_SEQ", allocationSize=1)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="EMPLOYEES_EMPLOYEEID_GENERATOR")
@Column(name="employee_id")
private Integer employeeId;
@Column(name="commission_pct")
private BigDecimal commissionPct;
private String email;
@Column(name="first_name")
private String firstName;
@Temporal(TemporalType.DATE)
@Column(name="hire_date")
private Date hireDate;
@Column(name="last_name")
private String lastName;
@Column(name="phone_number")
private String phoneNumber;
private BigDecimal salary;
//bi-directional many-to-one association to Department
@ManyToOne
@JoinColumn(name="department_id")
private Department department;
//uni-directional many-to-one association to Employee
@ManyToOne
@JoinColumn(name="manager_id")
private Employee manager;
//bi-directional many-to-one association to Job
@ManyToOne
@JoinColumn(name="job_id")
private Job job;
public Employee() {
}
public Integer getEmployeeId() {
return this.employeeId;
}
public void setEmployeeId(Integer employeeId) {
this.employeeId = employeeId;
}
public BigDecimal getCommissionPct() {
return this.commissionPct;
}
public void setCommissionPct(BigDecimal commissionPct) {
this.commissionPct = commissionPct;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getFirstName() {
return this.firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public Date getHireDate() {
return this.hireDate;
}
public void setHireDate(Date hireDate) {
this.hireDate = hireDate;
}
public String getLastName() {
return this.lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public BigDecimal getSalary() {
return this.salary;
}
public void setSalary(BigDecimal salary) {
this.salary = salary;
}
public Department getDepartment() {
return this.department;
}
public void setDepartment(Department department) {
this.department = department;
}
public Employee getManager() {
return this.manager;
}
public void setManager(Employee manager) {
this.manager = manager;
}
public Job getJob() {
return this.job;
}
public void setJob(Job job) {
this.job = job;
}
}
\ No newline at end of file
package com.example.demo.model;
import java.io.Serializable;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.List;
/**
* The persistent class for the jobs database table.
*
*/
@Entity
@Table(name="jobs")
@NamedQuery(name="Job.findAll", query="SELECT j FROM Job j")
public class Job implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="job_id")
private String jobId;
@Column(name="job_title")
private String jobTitle;
@Column(name="max_salary")
private BigDecimal maxSalary;
@Column(name="min_salary")
private BigDecimal minSalary;
//bi-directional many-to-one association to Employee
@OneToMany(mappedBy="job")
private List<Employee> employees;
public Job() {
}
public String getJobId() {
return this.jobId;
}
public void setJobId(String jobId) {
this.jobId = jobId;
}
public String getJobTitle() {
return this.jobTitle;
}
public void setJobTitle(String jobTitle) {
this.jobTitle = jobTitle;
}
public BigDecimal getMaxSalary() {
return this.maxSalary;
}
public void setMaxSalary(BigDecimal maxSalary) {
this.maxSalary = maxSalary;
}
public BigDecimal getMinSalary() {
return this.minSalary;
}
public void setMinSalary(BigDecimal minSalary) {
this.minSalary = minSalary;
}
public List<Employee> getEmployees() {
return this.employees;
}
public void setEmployees(List<Employee> employees) {
this.employees = employees;
}
public Employee addEmployee(Employee employee) {
getEmployees().add(employee);
employee.setJob(this);
return employee;
}
public Employee removeEmployee(Employee employee) {
getEmployees().remove(employee);
employee.setJob(null);
return employee;
}
}
\ No newline at end of file
package com.example.demo.model;
import java.io.Serializable;
import javax.persistence.*;
/**
* The persistent class for the locations database table.
*
*/
@Entity
@Table(name="locations")
@NamedQuery(name="Location.findAll", query="SELECT l FROM Location l")
public class Location implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@SequenceGenerator(name="LOCATIONS_LOCATIONID_GENERATOR", sequenceName="LOCATIONS_SEQ", allocationSize=100)
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="LOCATIONS_LOCATIONID_GENERATOR")
@Column(name="location_id")
private Integer locationId;
private String city;
@Column(name="postal_code")
private String postalCode;
@Column(name="state_province")
private String stateProvince;
@Column(name="street_address")
private String streetAddress;
//uni-directional many-to-one association to Country
@ManyToOne
@JoinColumn(name="country_id")
private Country country;
public Location() {
}
public Integer getLocationId() {
return this.locationId;
}
public void setLocationId(Integer locationId) {
this.locationId = locationId;
}
public String getCity() {
return this.city;
}
public void setCity(String city) {
this.city = city;
}
public String getPostalCode() {
return this.postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getStateProvince() {
return this.stateProvince;
}
public void setStateProvince(String stateProvince) {
this.stateProvince = stateProvince;
}
public String getStreetAddress() {
return this.streetAddress;
}
public void setStreetAddress(String streetAddress) {
this.streetAddress = streetAddress;
}
public Country getCountry() {
return this.country;
}
public void setCountry(Country country) {
this.country = country;
}
}
\ No newline at end of file
package com.example.demo.model;
import java.io.Serializable;
import javax.persistence.*;
import java.util.List;
/**
* The persistent class for the regions database table.
*
*/
@Entity
@Table(name="regions")
@NamedQuery(name="Region.findAll", query="SELECT r FROM Region r")
public class Region implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@Column(name="region_id")
private Integer regionId;
@Column(name="region_name")
private String regionName;
//bi-directional many-to-one association to Country
@OneToMany(mappedBy="region")
private List<Country> countries;
public Region() {
}
public Integer getRegionId() {
return this.regionId;
}
public void setRegionId(Integer regionId) {
this.regionId = regionId;
}
public String getRegionName() {
return this.regionName;
}
public void setRegionName(String regionName) {
this.regionName = regionName;
}
public List<Country> getCountries() {
return this.countries;
}
public void setCountries(List<Country> countries) {
this.countries = countries;
}
public Country addCountry(Country country) {
getCountries().add(country);
country.setRegion(this);
return country;
}
public Country removeCountry(Country country) {
getCountries().remove(country);
country.setRegion(null);
return country;
}
}
\ No newline at end of file
package com.example.demo.wstrzykiwanie;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Inject1 {
// 1. sposób wstrzykiwania: pole
@Autowired
private Komponent komponent;
@Autowired
private Repo repo;
{ System.out.println("Inject1 init"); } // initialization block
public Inject1() {
System.out.println("Inject1 constr, komponent = " + komponent); // null
}
@PostConstruct
public void pc() {
System.out.println("inject1 @PostConstruct, komponent = " + komponent);
}
@RequestMapping("/inject1")
@ResponseBody
public String get() {
return repo.getText() + " " + komponent.getValue();
}
}
package com.example.demo.wstrzykiwanie;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Inject2 {
{ System.out.println("Inject2 init"); }
// 2. sposób wstrzykiwania: setter
private Komponent komponent;
private Repo repo;
public Komponent getKomponent() {
return komponent;
}
@Autowired
public void setKomponent(Komponent komponent) {
System.out.println("SET KOMPONENT");
this.komponent = komponent;
}
public Repo getRepo() {
return repo;
}
@Autowired
public void setRepo(Repo repo) {
this.repo = repo;
}
@RequestMapping("/inject2")
@ResponseBody
public String get() {
return repo.getText() + " " + komponent.getValue();
}
}
package com.example.demo.wstrzykiwanie;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Inject3 {
{ System.out.println("Inject3 init"); }
// 3. sposób wstrzykiwania: konstruktor
// To podejście zwykle jest podawane jako najlepsze, bo umożliwia łatwą podmianę komponentów na "mocki" podczas testów
private Komponent komponent;
private Repo repo;
// Zauważmy, że ta klasa nie jest już poprawnym "JavaBean", bo nie posiada konstruktora domyślnego.
// Adnotacja Autowired tym razem nie jest potrzebna.
public Inject3(Komponent komponent, Repo repo) {
System.out.println("KONSTRUKTOR Inject3(komponent, repo)");
this.komponent = komponent;
this.repo = repo;
}
@RequestMapping("/inject3")
@ResponseBody
public String get() {
return repo.getText() + " " + komponent.getValue();
}
}
package com.example.demo.wstrzykiwanie;
import java.util.concurrent.atomic.AtomicInteger;
import org.springframework.stereotype.Component;
@Component
public class Komponent {
{ System.out.println("Komponent init"); }
private AtomicInteger licznik = new AtomicInteger();
public int getValue() {
return licznik.incrementAndGet();
}
}
package com.example.demo.wstrzykiwanie;
import org.springframework.stereotype.Repository;
@Repository
public class Repo {
{ System.out.println("Repo init"); }
public String getText() {
return "Ala ma kota";
}
}
spring.datasource.url=jdbc:postgresql://localhost:5432/hr
spring.datasource.username=kurs
spring.datasource.password=abc123
spring.jpa.show-sql=true
body {
background-color: #FFFFCC;
font-family: 'Arial', sans-serif;
}
h1 {
color: green;
text-align: center;
}
form {
margin: 30px auto;
padding: 20px;
width: 800px;
border: 4px solid blue;
background-color: #AAEEFF;
}
.wynik {
background-color: #FFFFFF;
border: 3px solid green;
margin: 20px auto;
width: 800px;
padding: 10px;
color: green;
}
.error {
background-color: #FFFFFF;
border: 6px double red;
margin: 20px auto;
padding: 10px;
width: 800px;
color: red;
font-weight: bold;
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Employees</title>
<style type="text/css">
table {
border-collapse: collapse;
}
th, td {
border: 1px solid #444444;
padding: 4px;
}
</style>
</head>
<body>
<table>
<tr>
<th>Imię</th><th>Nazwisko</th><th>Stanowisko</th><th>Pensja</th><th>Departament</th><th>Miasto</th>
</tr>
<tr th:each="emp : ${emps}">
<td th:text="${emp.firstName}">firstName</td>
<td th:text="${emp.lastName}">lastName</td>
<td th:text="${emp.job.jobTitle}">jobTitle</td>
<td th:text="${emp.salary}">salary</td>
<td th:text="${emp.department.departmentName}" th:if="${emp.department != null}">departmentName</td>
<td th:text="${emp.department.location.city}" th:if="${emp.department != null}">city</td>
</tr>
</table>
<p><a th:href="@{/}">wróć do spisu treści</a></p>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello</title>
</head>
<body>
<p>[[${txt}]]</p>
<p>Teraz jest godzina: [[${time}]]</p>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Spis treści</title>
<link rel="stylesheet" type="text/css" th:href="@{/styl.css}" href="../static/styl.css">
</head>
<body>
<h1>Spis treści</h1>
<ul>
<li><a href="/hello">Hello</a></li>
<li><a href="/ping">Ping</a></li>
</ul>
<h2>Spring Data</h2>
<ul>
<li><a href="/emps0">InMemoryRepository</a></li>
<li><a href="/emps1">emps1</a> - wersja z bespośrednio użytym JPA</li>
<li><a href="/emps1/100">emps1/100</a> - odczyt jednego pracownika po id</li>
<li><a href="/emps2">emps2</a> - wersja z użyciem JPA wyciągniętym do osobnej klasy @Repository</li>
<li><a href="/emps2/100">emps2/100</a> - odczyt jednego pracownika po id</li>
<li><a href="/emps2/by_name?name=King">emps2/by_name?last_name=King</a> - odczyt pracowników po nazwisku, przykład <strong>Query</strong></li>
<li><a href="/emps3">emps3</a> - j.w. ale interfejs</li>
<li><a href="/emps3/100">emps3/100</a> - odczyt jednego pracownika po id</li>
<li><a href="/emps3/by_name?name=King">emps3/by_name?last_name=King</a> - odczyt pracowników po nazwisku, przykład <strong>Query</strong></li>
<li><a href="/emps4">emps4</a> - Spring Data JpaRepository – domyślny interfejs</li>
<li><a href="/emps4/100">emps4/100</a> - odczyt jednego pracownika po id</li>
<li><a href="/emps5/all">emps5</a> - Spring Data JpaRepository – rozszerzony interfejs</li>
<li><a href="/emps5/by_id/101">emps5/by_id/101</a> - wg id</li>
<li><a href="/emps5/by_name?name=King">emps5/by_name?last_name=King</a> - odczyt pracowników po nazwisku, przykład <strong>Query</strong></li>
<li><a href="/emps5/by_job/ST_CLERK">/by_job/ST_CLERK</a> - wg stanowiska
<li><a href="/emps5/by_city/Seattle">emps5/by_city/Seattle</a> - wg miasta</li>
<li><a href="/emps5/by_salary?min=5000&amp;max=10000">emps5/by_salary</a> - wg pensji</li>
<li><a href="/emps5/by_year/1999">emps5/by_year</a> - wg roku zatrudneinia - przykład <strong>native query</strong></li>
<li><a href="/emps5/szef/105">szef/105</a> - nazwisko sefa (przykład własnej funkcji)
<li><a href="/emps5/zara/?id=103">zara?id=103</a> - zarabiający więcej niż (przykład własnej funkcji)
<li><a href="/emps5/move/110?dep=90&job=AD_PRES">move</a> - przenieś pracownika
</ul>
<h2>Wstrzykiwanie na 3 sposoby</h2>
<ul>
<li><a href="/inject1">Wstrzykiwanie 1</a> - pole</li>
<li><a href="/inject2">Wstrzykiwanie 2</a> - setter</li>
<li><a href="/inject3">Wstrzykiwanie 3</a> - konstruktor</li>
</ul>
<h2>Eksperymenty z beanami</h2>
<ul>
<li><a href="/test0">Test 0</a> &mdash; brak modelu</li>
<li><a href="/test1">Test 1</a> &mdash; <code>Model</code></li>
<li><a href="/test2">Test 2</a> &mdash; parametr metody i <code>Model</code></li>
<li><a href="/test3">Test 3</a> &mdash; parametr <code>@ModelAttribute</code></li>
<li><a href="/test4">Test 4</a> &mdash; <code>@ModelAttribute</code> przy metodzie i w parametrze</li>
<li><a href="/test4a">Test 4a</a> &mdash; <code>@ModelAttribute</code> przy metodzie, ale nie w parametrze</li>
<li><a href="/test5">Test 5</a> &mdash; <code>@ModelAttribute</code> w połączeniu z <code>@SessionAttributes</code></li>
<li><a href="/test6">Test 6</a> &mdash; <code>@Component</code> w połączeniu z <code>@Autowired</code></li>
<li><a href="/test7">Test 7</a> &mdash; <code>@Component @Scope(session)</code></li>
<li><a href="/test8">Test 8</a> &mdash; <code>@Bean</code> w połączeniu z <code>@Autowired</code></li>
</ul>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Test beanów za pomocą licznika</title>
<link rel="stylesheet" type="text/css" th:href="@{/styl.css}"/>
</head>
<body>
<h1>Test beanów za pomocą licznika</h1>
<p>licznik = <strong th:text="${licznik}">X</strong></p>
</body>
</html>
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Names</title>
</head>
<body>
<ul>
<li th:each="name : ${names}" th:text="${name}">ktoś</li>
</ul>
<p><a th:href="@{/}">wróć do spisu treści</a></p>
</body>
</html>
<!DOCTYPE html>
<html lang="pl" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Ping</title>
<link rel="stylesheet" type="text/css" th:href="@{/styl.css}" href="../static/styl.css">
</head>
<body>
<h2>Informacje o kliencie</h2>
<ul>
<li>Adres: <strong th:text="${clientInfo.ip}">1.2.3.4</strong></li>
<li>Przeglądarka: <strong th:text="${clientInfo.userAgent}">IE</strong></li>
<li>Data: <strong th:text="${clientInfo.data}">data</strong></li>
</ul>
</body>
</html>
package com.example.demo;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class Pc19SpringTechnicznieApplicationTests {
@Test
void contextLoads() {
}
}
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