/00-framework-tool-introductions/01.Spring-Introduction-In-10-Steps/pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion >4.0.0</modelVersion >
<groupId >com.in28minutes.spring.basics</groupId >
<artifactId >spring-in-5-steps</artifactId >
<version >0.0.1-SNAPSHOT</version >
<packaging >jar</packaging >
<name >spring-in-5-steps</name >
<description >Demo project for Spring Boot</description >
<parent >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-starter-parent</artifactId >
<version >2.0.0.RELEASE</version >
<relativePath /> <!-- lookup parent from repository -->
</parent >
<properties >
<project .build.sourceEncoding>UTF-8</project .build.sourceEncoding>
<project .reporting.outputEncoding>UTF-8</project .reporting.outputEncoding>
<java .version>1.8</java .version>
</properties >
<dependencies >
<dependency >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-starter</artifactId >
</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 >
<repositories >
<repository >
<id >spring-snapshots</id >
<name >Spring Snapshots</name >
<url >https://repo.spring.io/snapshot</url >
<snapshots >
<enabled >true</enabled >
</snapshots >
</repository >
<repository >
<id >spring-milestones</id >
<name >Spring Milestones</name >
<url >https://repo.spring.io/milestone</url >
<snapshots >
<enabled >false</enabled >
</snapshots >
</repository >
</repositories >
<pluginRepositories >
<pluginRepository >
<id >spring-snapshots</id >
<name >Spring Snapshots</name >
<url >https://repo.spring.io/snapshot</url >
<snapshots >
<enabled >true</enabled >
</snapshots >
</pluginRepository >
<pluginRepository >
<id >spring-milestones</id >
<name >Spring Milestones</name >
<url >https://repo.spring.io/milestone</url >
<snapshots >
<enabled >false</enabled >
</snapshots >
</pluginRepository >
</pluginRepositories >
</project >
/00-framework-tool-introductions/01.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/BinarySearchImpl.java
package com .in28minutes .spring .basics .springin5steps ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .stereotype .Component ;
@ Component
public class BinarySearchImpl {
@ Autowired
private SortAlgorithm sortAlgorithm ;
public int binarySearch (int [] numbers , int numberToSearchFor ) {
int [] sortedNumbers = sortAlgorithm .sort (numbers );
System .out .println (sortAlgorithm );
// Search the array
return 3 ;
}
}
/00-framework-tool-introductions/01.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/BubbleSortAlgorithm.java
package com .in28minutes .spring .basics .springin5steps ;
import org .springframework .context .annotation .Primary ;
import org .springframework .stereotype .Component ;
@ Component
@ Primary
public class BubbleSortAlgorithm implements SortAlgorithm {
public int [] sort (int [] numbers ) {
// Logic for Bubble Sort
return numbers ;
}
}
/00-framework-tool-introductions/01.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/QuickSortAlgorithm.java
package com .in28minutes .spring .basics .springin5steps ;
import org .springframework .stereotype .Component ;
@ Component
public class QuickSortAlgorithm implements SortAlgorithm {
public int [] sort (int [] numbers ) {
// Logic for Quick Sort
return numbers ;
}
}
/00-framework-tool-introductions/01.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/SortAlgorithm.java
package com .in28minutes .spring .basics .springin5steps ;
public interface SortAlgorithm {
public int [] sort (int [] numbers );
}
/00-framework-tool-introductions/01.Spring-Introduction-In-10-Steps/src/main/java/com/in28minutes/spring/basics/springin5steps/SpringIn5StepsApplication.java
package com .in28minutes .spring .basics .springin5steps ;
import org .springframework .boot .SpringApplication ;
import org .springframework .boot .autoconfigure .SpringBootApplication ;
import org .springframework .context .ApplicationContext ;
@ SpringBootApplication
public class SpringIn5StepsApplication {
// What are the beans?
// What are the dependencies of a bean?
// Where to search for beans? => No need
public static void main (String [] args ) {
// BinarySearchImpl binarySearch =
// new BinarySearchImpl(new QuickSortAlgorithm());
// Application Context
ApplicationContext applicationContext =
SpringApplication .run (SpringIn5StepsApplication .class , args );
BinarySearchImpl binarySearch =
applicationContext .getBean (BinarySearchImpl .class );
int result =
binarySearch .binarySearch (new int [] { 12 , 4 , 6 }, 3 );
System .out .println (result );
}
}
/00-framework-tool-introductions/01.Spring-Introduction-In-10-Steps/src/main/resources/application.properties
logging.level.org.springframework = debug
/00-framework-tool-introductions/01.Spring-Introduction-In-10-Steps/src/main/resources/log.txt
Searching directory [/in28Minutes/git/getting-started-in-5-steps/spring-in-5-steps/target/classes/com/in28minutes/spring/basics/springin5steps] for files matching pattern [/in28Minutes/git/getting-started-in-5-steps/spring-in-5-steps/target/classes/com/in28minutes/spring/basics/springin5steps/**/*.class]
Identified candidate component class: file [/in28Minutes/git/getting-started-in-5-steps/spring-in-5-steps/target/classes/com/in28minutes/spring/basics/springin5steps/BinarySearchImpl.class]
Identified candidate component class: file [/in28Minutes/git/getting-started-in-5-steps/spring-in-5-steps/target/classes/com/in28minutes/spring/basics/springin5steps/BubbleSortAlgorithm.class]
Creating instance of bean 'binarySearchImpl'
Creating instance of bean 'bubbleSortAlgorithm'
Finished creating instance of bean 'bubbleSortAlgorithm'
Constuctor - Autowiring by type from bean name 'binarySearchImpl' via constructor
to bean named 'bubbleSortAlgorithm'
Setter - Autowiring by type from bean name 'binarySearchImpl' to bean named 'bubbleSortAlgorithm'
No Setter or Constructor - Autowiring by type from bean name 'binarySearchImpl' to bean named 'bubbleSortAlgorithm'
Finished creating instance of bean 'binarySearchImpl'
/00-framework-tool-introductions/01.Spring-Introduction-In-10-Steps/src/test/java/com/in28minutes/spring/basics/springin5steps/SpringIn5StepsApplicationTests.java
package com .in28minutes .spring .basics .springin5steps ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .test .context .junit4 .SpringRunner ;
@ RunWith (SpringRunner .class )
@ SpringBootTest
public class SpringIn5StepsApplicationTests {
@ Test
public void contextLoads () {
}
}
/00-framework-tool-introductions/02.Spring-Boot-Introduction-In-10-Steps/notes.txt
Goals
Enable building production ready applications quickly
Provide common non-functional features
- embedded servers
- metrics
- health checks
- externalized configuration
What Spring Boot is NOT!
ZERO code generation
Neither an application server nor a web server
Features
Quick Starter Projects with Auto Configuration
- Web
- JPA
Embedded Servers - Tomcat, Jetty or Undertow
Production-ready features
- metrics and health checks
- externalized configuration
http://localhost:8080/books => Few hardcoded books
/00-framework-tool-introductions/02.Spring-Boot-Introduction-In-10-Steps/pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion >4.0.0</modelVersion >
<groupId >com.in28minutes.springboot.basics</groupId >
<artifactId >springboot-in-10-steps</artifactId >
<version >0.0.1-SNAPSHOT</version >
<packaging >jar</packaging >
<name >springboot-in-10-steps</name >
<description >Demo project for Spring Boot</description >
<parent >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-starter-parent</artifactId >
<version >2.0.0.RELEASE</version >
<relativePath /> <!-- lookup parent from repository -->
</parent >
<properties >
<project .build.sourceEncoding>UTF-8</project .build.sourceEncoding>
<project .reporting.outputEncoding>UTF-8</project .reporting.outputEncoding>
<java .version>1.8</java .version>
</properties >
<dependencies >
<dependency >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-starter-actuator</artifactId >
</dependency >
<dependency >
<groupId >org.springframework.data</groupId >
<artifactId >spring-data-rest-hal-browser</artifactId >
</dependency >
<!--
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
-->
<dependency >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-starter-test</artifactId >
<scope >test</scope >
</dependency >
<dependency >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-devtools</artifactId >
</dependency >
</dependencies >
<build >
<plugins >
<plugin >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-maven-plugin</artifactId >
</plugin >
</plugins >
</build >
<repositories >
<repository >
<id >spring-snapshots</id >
<name >Spring Snapshots</name >
<url >https://repo.spring.io/snapshot</url >
<snapshots >
<enabled >true</enabled >
</snapshots >
</repository >
<repository >
<id >spring-milestones</id >
<name >Spring Milestones</name >
<url >https://repo.spring.io/milestone</url >
<snapshots >
<enabled >false</enabled >
</snapshots >
</repository >
</repositories >
<pluginRepositories >
<pluginRepository >
<id >spring-snapshots</id >
<name >Spring Snapshots</name >
<url >https://repo.spring.io/snapshot</url >
<snapshots >
<enabled >true</enabled >
</snapshots >
</pluginRepository >
<pluginRepository >
<id >spring-milestones</id >
<name >Spring Milestones</name >
<url >https://repo.spring.io/milestone</url >
<snapshots >
<enabled >false</enabled >
</snapshots >
</pluginRepository >
</pluginRepositories >
</project >
/00-framework-tool-introductions/02.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/springboot/basics/springbootin10steps/Book.java
package com .in28minutes .springboot .basics .springbootin10steps ;
public class Book {
long id ;
String name ;
String author ;
public Book (long id , String name , String author ) {
super ();
this .id = id ;
this .name = name ;
this .author = author ;
}
public long getId () {
return id ;
}
public String getName () {
return name ;
}
public String getAuthor () {
return author ;
}
@ Override
public String toString () {
return String .format ("Book [id=%s, name=%s, author=%s]" , id , name , author );
}
}
/00-framework-tool-introductions/02.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/springboot/basics/springbootin10steps/BooksController.java
package com .in28minutes .springboot .basics .springbootin10steps ;
import java .util .Arrays ;
import java .util .List ;
import org .springframework .web .bind .annotation .GetMapping ;
import org .springframework .web .bind .annotation .RestController ;
@ RestController
public class BooksController {
@ GetMapping ("/books" )
public List <Book > getAllBooks () {
return Arrays .asList (
new Book (1l , "Mastering Spring 5.2" , "Ranga Karanam" ));
}
}
/00-framework-tool-introductions/02.Spring-Boot-Introduction-In-10-Steps/src/main/java/com/in28minutes/springboot/basics/springbootin10steps/SpringbootIn10StepsApplication.java
package com .in28minutes .springboot .basics .springbootin10steps ;
import org .springframework .boot .SpringApplication ;
import org .springframework .boot .autoconfigure .SpringBootApplication ;
import org .springframework .context .ApplicationContext ;
import org .springframework .context .ConfigurableApplicationContext ;
@ SpringBootApplication
public class SpringbootIn10StepsApplication {
public static void main (String [] args ) {
ApplicationContext applicationContext =
SpringApplication .run (SpringbootIn10StepsApplication .class , args );
for (String name : applicationContext .getBeanDefinitionNames ()) {
System .out .println (name );
}
}
}
/00-framework-tool-introductions/02.Spring-Boot-Introduction-In-10-Steps/src/main/resources/application.properties
# logging.level.org.springframework = DEBUG
management.endpoints.web.exposure.include =*
/00-framework-tool-introductions/02.Spring-Boot-Introduction-In-10-Steps/src/test/java/com/in28minutes/springboot/basics/springbootin10steps/SpringbootIn10StepsApplicationTests.java
package com .in28minutes .springboot .basics .springbootin10steps ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .test .context .junit4 .SpringRunner ;
@ RunWith (SpringRunner .class )
@ SpringBootTest
public class SpringbootIn10StepsApplicationTests {
@ Test
public void contextLoads () {
}
}
/00-framework-tool-introductions/03.JUnit-Introduction-In-5-Steps/src/com/in28minutes/junit/MyMath.java
package com .in28minutes .junit ;
public class MyMath {
int sum (int [] numbers ) {
int sum = 0 ;
for (int i : numbers ) {
sum += i ;
}
return sum ;
}
}
/00-framework-tool-introductions/03.JUnit-Introduction-In-5-Steps/test/com/in28minutes/junit/AssertTest.java
package com .in28minutes .junit ;
import static org .junit .Assert .assertEquals ;
import static org .junit .Assert .assertTrue ;
import org .junit .Test ;
public class AssertTest {
@ Test
public void test () {
boolean condn = true ;
assertEquals (true , condn );
assertTrue (condn );
// assertFalse(condn);
}
}
/00-framework-tool-introductions/03.JUnit-Introduction-In-5-Steps/test/com/in28minutes/junit/MyMathTest.java
package com .in28minutes .junit ;
import static org .junit .Assert .assertEquals ;
import org .junit .After ;
import org .junit .AfterClass ;
import org .junit .Before ;
import org .junit .BeforeClass ;
import org .junit .Test ;
public class MyMathTest {
MyMath myMath = new MyMath ();
@ Before
public void before () {
System .out .println ("Before" );
}
@ After
public void after () {
System .out .println ("After" );
}
@ BeforeClass
public static void beforeClass () {
System .out .println ("Before Class" );
}
@ AfterClass
public static void afterClass () {
System .out .println ("After Class" );
}
// MyMath.sum
// 1,2,3 => 6
@ Test
public void sum_with3numbers () {
System .out .println ("Test1" );
assertEquals (6 , myMath .sum (new int [] { 1 , 2 , 3 }));
}
@ Test
public void sum_with1number () {
System .out .println ("Test2" );
assertEquals (3 , myMath .sum (new int [] { 3 }));
}
}
/01-from-jdbc-to-jpa/pom.xml
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion >4.0.0</modelVersion >
<groupId >com.in28minutes.database</groupId >
<artifactId >database-demo</artifactId >
<version >0.0.1-SNAPSHOT</version >
<packaging >jar</packaging >
<name >database-demo</name >
<description >Demo project for Spring Boot</description >
<parent >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-starter-parent</artifactId >
<version >2.0.0.RELEASE</version >
<relativePath /> <!-- lookup parent from repository -->
</parent >
<properties >
<project .build.sourceEncoding>UTF-8</project .build.sourceEncoding>
<project .reporting.outputEncoding>UTF-8</project .reporting.outputEncoding>
<java .version>1.8</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-jdbc</artifactId >
</dependency >
<dependency >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-starter-web</artifactId >
</dependency >
<dependency >
<groupId >com.h2database</groupId >
<artifactId >h2</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 >
<repositories >
<repository >
<id >spring-snapshots</id >
<name >Spring Snapshots</name >
<url >https://repo.spring.io/snapshot</url >
<snapshots >
<enabled >true</enabled >
</snapshots >
</repository >
<repository >
<id >spring-milestones</id >
<name >Spring Milestones</name >
<url >https://repo.spring.io/milestone</url >
<snapshots >
<enabled >false</enabled >
</snapshots >
</repository >
</repositories >
<pluginRepositories >
<pluginRepository >
<id >spring-snapshots</id >
<name >Spring Snapshots</name >
<url >https://repo.spring.io/snapshot</url >
<snapshots >
<enabled >true</enabled >
</snapshots >
</pluginRepository >
<pluginRepository >
<id >spring-milestones</id >
<name >Spring Milestones</name >
<url >https://repo.spring.io/milestone</url >
<snapshots >
<enabled >false</enabled >
</snapshots >
</pluginRepository >
</pluginRepositories >
</project >
/01-from-jdbc-to-jpa/src/main/java/com/in28minutes/database/databasedemo/entity/Person.java
package com .in28minutes .database .databasedemo .entity ;
import java .util .Date ;
import javax .persistence .Entity ;
import javax .persistence .GeneratedValue ;
import javax .persistence .Id ;
import javax .persistence .NamedQuery ;
@ Entity
@ NamedQuery (name ="find_all_persons" , query ="select p from Person p" )
public class Person {
@ Id
@ GeneratedValue
private int id ;
private String name ;
private String location ;
private Date birthDate ;
public Person () {
}
public Person (int id , String name , String location , Date birthDate ) {
super ();
this .id = id ;
this .name = name ;
this .location = location ;
this .birthDate = birthDate ;
}
public Person (String name , String location , Date birthDate ) {
super ();
this .name = name ;
this .location = location ;
this .birthDate = birthDate ;
}
public int getId () {
return id ;
}
public void setId (int id ) {
this .id = id ;
}
public String getName () {
return name ;
}
public void setName (String name ) {
this .name = name ;
}
public String getLocation () {
return location ;
}
public void setLocation (String location ) {
this .location = location ;
}
public Date getBirthDate () {
return birthDate ;
}
public void setBirthDate (Date birthDate ) {
this .birthDate = birthDate ;
}
@ Override
public String toString () {
return String .format ("\n Person [id=%s, name=%s, location=%s, birthDate=%s]" , id , name , location , birthDate );
}
}
/01-from-jdbc-to-jpa/src/main/java/com/in28minutes/database/databasedemo/jdbc/PersonJbdcDao.java
package com .in28minutes .database .databasedemo .jdbc ;
import java .sql .ResultSet ;
import java .sql .SQLException ;
import java .sql .Timestamp ;
import java .util .List ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .jdbc .core .BeanPropertyRowMapper ;
import org .springframework .jdbc .core .JdbcTemplate ;
import org .springframework .jdbc .core .RowMapper ;
import org .springframework .stereotype .Repository ;
import com .in28minutes .database .databasedemo .entity .Person ;
@ Repository
public class PersonJbdcDao {
@ Autowired
JdbcTemplate jdbcTemplate ;
class PersonRowMapper implements RowMapper <Person >{
@ Override
public Person mapRow (ResultSet rs , int rowNum ) throws SQLException {
Person person = new Person ();
person .setId (rs .getInt ("id" ));
person .setName (rs .getString ("name" ));
person .setLocation (rs .getString ("location" ));
person .setBirthDate (rs .getTimestamp ("birth_date" ));
return person ;
}
}
public List <Person > findAll () {
return jdbcTemplate .query ("select * from person" , new PersonRowMapper ());
}
public Person findById (int id ) {
return jdbcTemplate .queryForObject ("select * from person where id=?" , new Object [] { id },
new BeanPropertyRowMapper <Person >(Person .class ));
}
public int deleteById (int id ) {
return jdbcTemplate .update ("delete from person where id=?" , new Object [] { id });
}
public int insert (Person person ) {
return jdbcTemplate .update ("insert into person (id, name, location, birth_date) " + "values(?, ?, ?, ?)" ,
new Object [] { person .getId (), person .getName (), person .getLocation (),
new Timestamp (person .getBirthDate ().getTime ()) });
}
public int update (Person person ) {
return jdbcTemplate .update ("update person " + " set name = ?, location = ?, birth_date = ? " + " where id = ?" ,
new Object [] { person .getName (), person .getLocation (), new Timestamp (person .getBirthDate ().getTime ()),
person .getId () });
}
}
/01-from-jdbc-to-jpa/src/main/java/com/in28minutes/database/databasedemo/jpa/PersonJpaRepository.java
package com .in28minutes .database .databasedemo .jpa ;
import java .util .List ;
import javax .persistence .EntityManager ;
import javax .persistence .PersistenceContext ;
import javax .persistence .TypedQuery ;
import javax .transaction .Transactional ;
import org .springframework .stereotype .Repository ;
import com .in28minutes .database .databasedemo .entity .Person ;
@ Repository
@ Transactional
public class PersonJpaRepository {
// connect to the database
@ PersistenceContext
EntityManager entityManager ;
public List <Person > findAll () {
TypedQuery <Person > namedQuery = entityManager .createNamedQuery ("find_all_persons" , Person .class );
return namedQuery .getResultList ();
}
public Person findById (int id ) {
return entityManager .find (Person .class , id );// JPA
}
public Person update (Person person ) {
return entityManager .merge (person );
}
public Person insert (Person person ) {
return entityManager .merge (person );
}
public void deleteById (int id ) {
Person person = findById (id );
entityManager .remove (person );
}
}
/01-from-jdbc-to-jpa/src/main/java/com/in28minutes/database/databasedemo/JpaDemoApplication.java
package com .in28minutes .database .databasedemo ;
import java .util .Date ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .boot .CommandLineRunner ;
import org .springframework .boot .SpringApplication ;
import org .springframework .boot .autoconfigure .SpringBootApplication ;
import com .in28minutes .database .databasedemo .entity .Person ;
import com .in28minutes .database .databasedemo .jpa .PersonJpaRepository ;
@ SpringBootApplication
public class JpaDemoApplication implements CommandLineRunner {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
PersonJpaRepository repository ;
public static void main (String [] args ) {
SpringApplication .run (JpaDemoApplication .class , args );
}
@ Override
public void run (String ... args ) throws Exception {
logger .info ("User id 10001 -> {}" , repository .findById (10001 ));
logger .info ("Inserting -> {}" ,
repository .insert (new Person ("Tara" , "Berlin" , new Date ())));
logger .info ("Update 10003 -> {}" ,
repository .update (new Person (10003 , "Pieter" , "Utrecht" , new Date ())));
repository .deleteById (10002 );
logger .info ("All users -> {}" , repository .findAll ());
}
}
/01-from-jdbc-to-jpa/src/main/java/com/in28minutes/database/databasedemo/SpringJdbcDemoApplication.java
package com .in28minutes .database .databasedemo ;
import java .util .Date ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .boot .CommandLineRunner ;
import org .springframework .boot .SpringApplication ;
import org .springframework .boot .autoconfigure .SpringBootApplication ;
import com .in28minutes .database .databasedemo .entity .Person ;
import com .in28minutes .database .databasedemo .jdbc .PersonJbdcDao ;
//@SpringBootApplication
public class SpringJdbcDemoApplication implements CommandLineRunner {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
PersonJbdcDao dao ;
public static void main (String [] args ) {
SpringApplication .run (SpringJdbcDemoApplication .class , args );
}
@ Override
public void run (String ... args ) throws Exception {
logger .info ("All users -> {}" , dao .findAll ());
logger .info ("User id 10001 -> {}" , dao .findById (10001 ));
logger .info ("Deleting 10002 -> No of Rows Deleted - {}" ,
dao .deleteById (10002 ));
logger .info ("Inserting 10004 -> {}" ,
dao .insert (new Person (10004 , "Tara" , "Berlin" , new Date ())));
logger .info ("Update 10003 -> {}" ,
dao .update (new Person (10003 , "Pieter" , "Utrecht" , new Date ())));
}
}
/01-from-jdbc-to-jpa/src/main/resources/application.properties
spring.h2.console.enabled =true
spring.jpa.show-sql =true
# logging.level.root=debug
/01-from-jdbc-to-jpa/src/main/resources/data.sql
/*
create table person
(
id integer not null,
name varchar(255) not null,
location varchar(255),
birth_date timestamp,
primary key(id)
);
*/
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE )
VALUES(10001, 'Ranga', 'Hyderabad',sysdate());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE )
VALUES(10002, 'James', 'New York',sysdate());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE )
VALUES(10003, 'Pieter', 'Amsterdam',sysdate());
/01-from-jdbc-to-jpa/src/test/java/com/in28minutes/database/databasedemo/SpringJdbcDemoApplicationTests.java
package com .in28minutes .database .databasedemo ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .test .context .junit4 .SpringRunner ;
@ RunWith (SpringRunner .class )
@ SpringBootTest
public class SpringJdbcDemoApplicationTests {
@ Test
public void contextLoads () {
}
}
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd" >
<modelVersion >4.0.0</modelVersion >
<groupId >com.in28minutes.jpa.hibernate</groupId >
<artifactId >demo</artifactId >
<version >0.0.1-SNAPSHOT</version >
<packaging >jar</packaging >
<name >demo</name >
<description >Demo project for Spring Boot</description >
<parent >
<groupId >org.springframework.boot</groupId >
<artifactId >spring-boot-starter-parent</artifactId >
<version >2.0.0.RELEASE</version >
<relativePath /> <!-- lookup parent from repository -->
</parent >
<properties >
<project .build.sourceEncoding>UTF-8</project .build.sourceEncoding>
<project .reporting.outputEncoding>UTF-8</project .reporting.outputEncoding>
<java .version>1.8</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-web</artifactId >
</dependency >
<dependency >
<groupId >com.h2database</groupId >
<artifactId >h2</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 >
<repositories >
<repository >
<id >spring-snapshots</id >
<name >Spring Snapshots</name >
<url >https://repo.spring.io/snapshot</url >
<snapshots >
<enabled >true</enabled >
</snapshots >
</repository >
<repository >
<id >spring-milestones</id >
<name >Spring Milestones</name >
<url >https://repo.spring.io/milestone</url >
<snapshots >
<enabled >false</enabled >
</snapshots >
</repository >
</repositories >
<pluginRepositories >
<pluginRepository >
<id >spring-snapshots</id >
<name >Spring Snapshots</name >
<url >https://repo.spring.io/snapshot</url >
<snapshots >
<enabled >true</enabled >
</snapshots >
</pluginRepository >
<pluginRepository >
<id >spring-milestones</id >
<name >Spring Milestones</name >
<url >https://repo.spring.io/milestone</url >
<snapshots >
<enabled >false</enabled >
</snapshots >
</pluginRepository >
</pluginRepositories >
</project >
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/DemoApplication.java
package com .in28minutes .jpa .hibernate .demo ;
import java .math .BigDecimal ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .boot .CommandLineRunner ;
import org .springframework .boot .SpringApplication ;
import org .springframework .boot .autoconfigure .SpringBootApplication ;
import com .in28minutes .jpa .hibernate .demo .entity .FullTimeEmployee ;
import com .in28minutes .jpa .hibernate .demo .entity .PartTimeEmployee ;
import com .in28minutes .jpa .hibernate .demo .repository .CourseRepository ;
import com .in28minutes .jpa .hibernate .demo .repository .EmployeeRepository ;
import com .in28minutes .jpa .hibernate .demo .repository .StudentRepository ;
@ SpringBootApplication
public class DemoApplication implements CommandLineRunner {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
private CourseRepository courseRepository ;
@ Autowired
private StudentRepository studentRepository ;
@ Autowired
private EmployeeRepository employeeRepository ;
public static void main (String [] args ) {
SpringApplication .run (DemoApplication .class , args );
}
@ Override
public void run (String ... arg0 ) throws Exception {
// studentRepository.saveStudentWithPassport();
// repository.playWithEntityManager();
// courseRepository.addHardcodedReviewsForCourse();
// List<Review> reviews = new ArrayList<>();
// reviews.add(new Review("5", "Great Hands-on Stuff."));
// reviews.add(new Review("5", "Hatsoff."));
// courseRepository.addReviewsForCourse(10003L, reviews );
// studentRepository.insertHardcodedStudentAndCourse();
// studentRepository.insertStudentAndCourse(new Student("Jack"),
// new Course("Microservices in 100 Steps"));
// Jack FullTimeEmployee salary - 10000$
// Jill PartTimeEmployee - 50$ per hour
/*
employeeRepository.insert(new PartTimeEmployee("Jill", new BigDecimal("50")));
employeeRepository.insert(new FullTimeEmployee("Jack", new BigDecimal("10000")));
logger.info("Full Time Employees -> {}",
employeeRepository.retrieveAllFullTimeEmployees());
logger.info("Part Time Employees -> {}",
employeeRepository.retrieveAllPartTimeEmployees());*/
}
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/entity/Course.java
package com .in28minutes .jpa .hibernate .demo .entity ;
import java .time .LocalDateTime ;
import java .util .ArrayList ;
import java .util .List ;
import javax .persistence .Column ;
import javax .persistence .Entity ;
import javax .persistence .GeneratedValue ;
import javax .persistence .Id ;
import javax .persistence .ManyToMany ;
import javax .persistence .NamedQueries ;
import javax .persistence .NamedQuery ;
import javax .persistence .OneToMany ;
import org .hibernate .annotations .CreationTimestamp ;
import org .hibernate .annotations .UpdateTimestamp ;
@ Entity
@ NamedQueries (value = {
@ NamedQuery (name = "query_get_all_courses" ,
query = "Select c From Course c" ),
@ NamedQuery (name = "query_get_100_Step_courses" ,
query = "Select c From Course c where name like '%100 Steps'" ) })
public class Course {
@ Id
@ GeneratedValue
private Long id ;
@ Column (nullable = false )
private String name ;
@ OneToMany (mappedBy ="course" )
private List <Review > reviews = new ArrayList <>();
@ ManyToMany (mappedBy ="courses" )
private List <Student > students = new ArrayList <>();
@ UpdateTimestamp
private LocalDateTime lastUpdatedDate ;
@ CreationTimestamp
private LocalDateTime createdDate ;
protected Course () {
}
public Course (String name ) {
this .name = name ;
}
public String getName () {
return name ;
}
public void setName (String name ) {
this .name = name ;
}
public List <Review > getReviews () {
return reviews ;
}
public void addReview (Review review ) {
this .reviews .add (review );
}
public void removeReview (Review review ) {
this .reviews .remove (review );
}
public List <Student > getStudents () {
return students ;
}
public void addStudent (Student student ) {
this .students .add (student );
}
public Long getId () {
return id ;
}
@ Override
public String toString () {
return String .format ("Course[%s]" , name );
}
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/entity/Employee.java
package com .in28minutes .jpa .hibernate .demo .entity ;
import javax .persistence .Column ;
import javax .persistence .GeneratedValue ;
import javax .persistence .Id ;
import javax .persistence .MappedSuperclass ;
@ MappedSuperclass
//@Entity
//@Inheritance(strategy=InheritanceType.JOINED)
public abstract class Employee {
@ Id
@ GeneratedValue
private Long id ;
@ Column (nullable = false )
private String name ;
protected Employee () {
}
public Employee (String name ) {
this .name = name ;
}
public String getName () {
return name ;
}
public void setName (String name ) {
this .name = name ;
}
public Long getId () {
return id ;
}
@ Override
public String toString () {
return String .format ("Employee[%s]" , name );
}
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/entity/FullTimeEmployee.java
package com .in28minutes .jpa .hibernate .demo .entity ;
import java .math .BigDecimal ;
import javax .persistence .Entity ;
@ Entity
public class FullTimeEmployee extends Employee {
protected FullTimeEmployee () {
}
public FullTimeEmployee (String name , BigDecimal salary ) {
super (name );
this .salary = salary ;
}
private BigDecimal salary ;
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/entity/PartTimeEmployee.java
package com .in28minutes .jpa .hibernate .demo .entity ;
import java .math .BigDecimal ;
import javax .persistence .Entity ;
@ Entity
public class PartTimeEmployee extends Employee {
protected PartTimeEmployee () {
}
public PartTimeEmployee (String name , BigDecimal hourlyWage ) {
super (name );
this .hourlyWage = hourlyWage ;
}
private BigDecimal hourlyWage ;
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/entity/Passport.java
package com .in28minutes .jpa .hibernate .demo .entity ;
import javax .persistence .Column ;
import javax .persistence .Entity ;
import javax .persistence .FetchType ;
import javax .persistence .GeneratedValue ;
import javax .persistence .Id ;
import javax .persistence .OneToOne ;
@ Entity
public class Passport {
@ Id
@ GeneratedValue
private Long id ;
@ Column (nullable = false )
private String number ;
@ OneToOne (fetch =FetchType .LAZY , mappedBy ="passport" )
private Student student ;
protected Passport () {
}
public Passport (String number ) {
this .number = number ;
}
public String getNumber () {
return number ;
}
public void setNumber (String number ) {
this .number = number ;
}
public Student getStudent () {
return student ;
}
public void setStudent (Student student ) {
this .student = student ;
}
public Long getId () {
return id ;
}
@ Override
public String toString () {
return String .format ("Passport[%s]" , number );
}
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/entity/Review.java
package com .in28minutes .jpa .hibernate .demo .entity ;
import javax .persistence .Entity ;
import javax .persistence .GeneratedValue ;
import javax .persistence .Id ;
import javax .persistence .ManyToOne ;
@ Entity
public class Review {
@ Id
@ GeneratedValue
private Long id ;
private String rating ;
private String description ;
@ ManyToOne
private Course course ;
protected Review () {
}
public Review (String rating , String description ) {
this .rating = rating ;
this .description = description ;
}
public String getDescription () {
return description ;
}
public void setDescription (String description ) {
this .description = description ;
}
public String getRating () {
return rating ;
}
public void setRating (String rating ) {
this .rating = rating ;
}
public Course getCourse () {
return course ;
}
public void setCourse (Course course ) {
this .course = course ;
}
public Long getId () {
return id ;
}
@ Override
public String toString () {
return String .format ("Review[%s %s]" , rating , description );
}
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/entity/Student.java
package com .in28minutes .jpa .hibernate .demo .entity ;
import java .util .ArrayList ;
import java .util .List ;
import javax .persistence .Column ;
import javax .persistence .Entity ;
import javax .persistence .FetchType ;
import javax .persistence .GeneratedValue ;
import javax .persistence .Id ;
import javax .persistence .JoinColumn ;
import javax .persistence .JoinTable ;
import javax .persistence .ManyToMany ;
import javax .persistence .OneToOne ;
@ Entity
public class Student {
@ Id
@ GeneratedValue
private Long id ;
@ Column (nullable = false )
private String name ;
@ OneToOne (fetch = FetchType .LAZY )
private Passport passport ;
@ ManyToMany
@ JoinTable (name = "STUDENT_COURSE" ,
joinColumns = @ JoinColumn (name = "STUDENT_ID" ),
inverseJoinColumns = @ JoinColumn (name = "COURSE_ID" ))
private List <Course > courses = new ArrayList <>();
protected Student () {
}
public Student (String name ) {
this .name = name ;
}
public String getName () {
return name ;
}
public void setName (String name ) {
this .name = name ;
}
public Passport getPassport () {
return passport ;
}
public void setPassport (Passport passport ) {
this .passport = passport ;
}
public List <Course > getCourses () {
return courses ;
}
public void addCourse (Course course ) {
this .courses .add (course );
}
public Long getId () {
return id ;
}
@ Override
public String toString () {
return String .format ("Student[%s]" , name );
}
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/repository/CourseRepository.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import java .util .List ;
import javax .persistence .EntityManager ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .stereotype .Repository ;
import org .springframework .transaction .annotation .Transactional ;
import com .in28minutes .jpa .hibernate .demo .entity .Course ;
import com .in28minutes .jpa .hibernate .demo .entity .Review ;
@ Repository
@ Transactional
public class CourseRepository {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
EntityManager em ;
public Course findById (Long id ) {
return em .find (Course .class , id );
}
public Course save (Course course ) {
if (course .getId () == null ) {
em .persist (course );
} else {
em .merge (course );
}
return course ;
}
public void deleteById (Long id ) {
Course course = findById (id );
em .remove (course );
}
public void playWithEntityManager () {
Course course1 = new Course ("Web Services in 100 Steps" );
em .persist (course1 );
Course course2 = findById (10001L );
course2 .setName ("JPA in 50 Steps - Updated" );
}
public void addHardcodedReviewsForCourse () {
//get the course 10003
Course course = findById (10003L );
logger .info ("course.getReviews() -> {}" , course .getReviews ());
//add 2 reviews to it
Review review1 = new Review ("5" , "Great Hands-on Stuff." );
Review review2 = new Review ("5" , "Hatsoff." );
//setting the relationship
course .addReview (review1 );
review1 .setCourse (course );
course .addReview (review2 );
review2 .setCourse (course );
//save it to the database
em .persist (review1 );
em .persist (review2 );
}
public void addReviewsForCourse (Long courseId , List <Review > reviews ) {
Course course = findById (courseId );
logger .info ("course.getReviews() -> {}" , course .getReviews ());
for (Review review :reviews )
{
//setting the relationship
course .addReview (review );
review .setCourse (course );
em .persist (review );
}
}
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/repository/CourseSpringDataRepository.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import org .springframework .data .jpa .repository .JpaRepository ;
import com .in28minutes .jpa .hibernate .demo .entity .Course ;
public interface CourseSpringDataRepository extends JpaRepository <Course , Long > {
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/repository/EmployeeRepository.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import java .util .List ;
import javax .persistence .EntityManager ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .stereotype .Repository ;
import org .springframework .transaction .annotation .Transactional ;
import com .in28minutes .jpa .hibernate .demo .entity .Employee ;
import com .in28minutes .jpa .hibernate .demo .entity .FullTimeEmployee ;
import com .in28minutes .jpa .hibernate .demo .entity .PartTimeEmployee ;
@ Repository
@ Transactional
public class EmployeeRepository {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
EntityManager em ;
public void insert (Employee employee ) {
em .persist (employee );
}
public List <PartTimeEmployee > retrieveAllPartTimeEmployees () {
return em .createQuery ("select e from PartTimeEmployee e" , PartTimeEmployee .class ).getResultList ();
}
public List <FullTimeEmployee > retrieveAllFullTimeEmployees () {
return em .createQuery ("select e from FullTimeEmployee e" , FullTimeEmployee .class ).getResultList ();
}
}
/02-jpa-advanced/src/main/java/com/in28minutes/jpa/hibernate/demo/repository/StudentRepository.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import javax .persistence .EntityManager ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .stereotype .Repository ;
import org .springframework .transaction .annotation .Transactional ;
import com .in28minutes .jpa .hibernate .demo .entity .Course ;
import com .in28minutes .jpa .hibernate .demo .entity .Passport ;
import com .in28minutes .jpa .hibernate .demo .entity .Student ;
@ Repository
@ Transactional
public class StudentRepository {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
EntityManager em ;
public Student findById (Long id ) {
return em .find (Student .class , id );
}
public Student save (Student student ) {
if (student .getId () == null ) {
em .persist (student );
} else {
em .merge (student );
}
return student ;
}
public void deleteById (Long id ) {
Student student = findById (id );
em .remove (student );
}
public void saveStudentWithPassport () {
Passport passport = new Passport ("Z123456" );
em .persist (passport );
Student student = new Student ("Mike" );
student .setPassport (passport );
em .persist (student );
}
public void someOperationToUnderstandPersistenceContext () {
//Database Operation 1 - Retrieve student
Student student = em .find (Student .class , 20001L );
//Persistence Context (student)
//Database Operation 2 - Retrieve passport
Passport passport = student .getPassport ();
//Persistence Context (student, passport)
//Database Operation 3 - update passport
passport .setNumber ("E123457" );
//Persistence Context (student, passport++)
//Database Operation 4 - update student
student .setName ("Ranga - updated" );
//Persistence Context (student++ , passport++)
}
public void insertHardcodedStudentAndCourse (){
Student student = new Student ("Jack" );
Course course = new Course ("Microservices in 100 Steps" );
em .persist (student );
em .persist (course );
student .addCourse (course );
course .addStudent (student );
em .persist (student );
}
public void insertStudentAndCourse (Student student , Course course ){
//Student student = new Student("Jack");
//Course course = new Course("Microservices in 100 Steps");
student .addCourse (course );
course .addStudent (student );
em .persist (student );
em .persist (course );
}
}
/02-jpa-advanced/src/main/resources/application.properties
# Enabling H2 Console
spring.h2.console.enabled =true
# Turn Statistics on
spring.jpa.properties.hibernate.generate_statistics =true
logging.level.org.hibernate.stat =debug
# Show all queries
spring.jpa.show-sql =true
spring.jpa.properties.hibernate.format_sql =true
logging.level.org.hibernate.type =trace
spring.jpa.properties.hibernate.connection.isolation =2
# Performance
spring.jpa.properties.hibernate.jdbc.batch_size =10
/02-jpa-advanced/src/main/resources/data.sql
insert into course(id, name, created_date, last_updated_date)
values(10001,'JPA in 50 Steps', sysdate(), sysdate());
insert into course(id, name, created_date, last_updated_date)
values(10002,'Spring in 50 Steps', sysdate(), sysdate());
insert into course(id, name, created_date, last_updated_date)
values(10003,'Spring Boot in 100 Steps', sysdate(), sysdate());
insert into course(id, name, created_date, last_updated_date)
values(10004,'Dummy1', sysdate(), sysdate());
insert into course(id, name, created_date, last_updated_date)
values(10005,'Dummy2', sysdate(), sysdate());
insert into course(id, name, created_date, last_updated_date)
values(10006,'Dummy3', sysdate(), sysdate());
insert into course(id, name, created_date, last_updated_date)
values(10007,'Dummy4', sysdate(), sysdate());
insert into course(id, name, created_date, last_updated_date)
values(10008,'Dummy5', sysdate(), sysdate());
insert into passport(id,number)
values(40001,'E123456');
insert into passport(id,number)
values(40002,'N123457');
insert into passport(id,number)
values(40003,'L123890');
insert into student(id,name,passport_id)
values(20001,'Ranga',40001);
insert into student(id,name,passport_id)
values(20002,'Adam',40002);
insert into student(id,name,passport_id)
values(20003,'Jane',40003);
insert into review(id,rating,description,course_id)
values(50001,'5', 'Great Course',10001);
insert into review(id,rating,description,course_id)
values(50002,'4', 'Wonderful Course',10001);
insert into review(id,rating,description,course_id)
values(50003,'5', 'Awesome Course',10003);
insert into student_course(student_id,course_id)
values(20001,10001);
insert into student_course(student_id,course_id)
values(20002,10001);
insert into student_course(student_id,course_id)
values(20003,10001);
insert into student_course(student_id,course_id)
values(20001,10003);
/02-jpa-advanced/src/test/java/com/in28minutes/jpa/hibernate/demo/DemoApplicationTests.java
package com .in28minutes .jpa .hibernate .demo ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .test .context .junit4 .SpringRunner ;
@ RunWith (SpringRunner .class )
@ SpringBootTest
public class DemoApplicationTests {
@ Test
public void contextLoads () {
}
}
/02-jpa-advanced/src/test/java/com/in28minutes/jpa/hibernate/demo/repository/CourseRepositoryTest.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import static org .junit .Assert .assertEquals ;
import static org .junit .Assert .assertNull ;
import java .util .List ;
import javax .persistence .EntityGraph ;
import javax .persistence .EntityManager ;
import javax .persistence .Subgraph ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .test .annotation .DirtiesContext ;
import org .springframework .test .context .junit4 .SpringRunner ;
import org .springframework .transaction .annotation .Transactional ;
import com .in28minutes .jpa .hibernate .demo .DemoApplication ;
import com .in28minutes .jpa .hibernate .demo .entity .Course ;
import com .in28minutes .jpa .hibernate .demo .entity .Review ;
import com .in28minutes .jpa .hibernate .demo .entity .Student ;
@ RunWith (SpringRunner .class )
@ SpringBootTest (classes = DemoApplication .class )
public class CourseRepositoryTest {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
CourseRepository repository ;
@ Autowired
EntityManager em ;
@ Test
public void findById_basic () {
Course course = repository .findById (10001L );
assertEquals ("JPA in 50 Steps" , course .getName ());
}
@ Test
@ DirtiesContext
public void deleteById_basic () {
repository .deleteById (10002L );
assertNull (repository .findById (10002L ));
}
@ Test
@ DirtiesContext
public void save_basic () {
// get a course
Course course = repository .findById (10001L );
assertEquals ("JPA in 50 Steps" , course .getName ());
// update details
course .setName ("JPA in 50 Steps - Updated" );
repository .save (course );
// check the value
Course course1 = repository .findById (10001L );
assertEquals ("JPA in 50 Steps - Updated" , course1 .getName ());
}
@ Test
@ DirtiesContext
public void playWithEntityManager () {
repository .playWithEntityManager ();
}
@ Test
@ Transactional
public void retrieveReviewsForCourse () {
Course course = repository .findById (10001L );
logger .info ("{}" , course .getReviews ());
}
@ Test
@ Transactional
public void retrieveCourseForReview () {
Review review = em .find (Review .class , 50001L );
logger .info ("{}" , review .getCourse ());
}
@ Test
@ Transactional
@ DirtiesContext
public void performance () {
//for (int i = 0; i < 20; i++)
//em.persist(new Course("Something" + i));
//em.flush();
//EntityGraph graph = em.getEntityGraph("graph.CourseAndStudents");
EntityGraph <Course > graph = em .createEntityGraph (Course .class );
Subgraph <List <Student >> bookSubGraph = graph .addSubgraph ("students" );
List <Course > courses = em .createQuery ("Select c from Course c" , Course .class )
.setHint ("javax.persistence.loadgraph" , graph )
.getResultList ();
for (Course course : courses ) {
System .out .println (course + " " + course .getStudents ());
}
}
@ Test
@ Transactional
@ DirtiesContext
public void performance_without_hint () {
List <Course > courses = em .createQuery ("Select c from Course c" , Course .class )
//.setHint("javax.persistence.loadgraph", graph)
.getResultList ();
for (Course course : courses ) {
System .out .println (course + " " + course .getStudents ());
}
}
}
/02-jpa-advanced/src/test/java/com/in28minutes/jpa/hibernate/demo/repository/CourseSpringDataRepositoryTest.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import static org .junit .Assert .assertFalse ;
import static org .junit .Assert .assertTrue ;
import java .util .Optional ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .data .domain .Page ;
import org .springframework .data .domain .PageRequest ;
import org .springframework .data .domain .Sort ;
import org .springframework .test .context .junit4 .SpringRunner ;
import com .in28minutes .jpa .hibernate .demo .DemoApplication ;
import com .in28minutes .jpa .hibernate .demo .entity .Course ;
@ RunWith (SpringRunner .class )
@ SpringBootTest (classes = DemoApplication .class )
public class CourseSpringDataRepositoryTest {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
CourseSpringDataRepository repository ;
@ Test
public void findById_CoursePresent () {
Optional <Course > courseOptional = repository .findById (10001L );
assertTrue (courseOptional .isPresent ());
}
@ Test
public void findById_CourseNotPresent () {
Optional <Course > courseOptional = repository .findById (20001L );
assertFalse (courseOptional .isPresent ());
}
@ Test
public void playingAroundWithSpringDataRepository () {
//Course course = new Course("Microservices in 100 Steps");
//repository.save(course);
//course.setName("Microservices in 100 Steps - Updated");
//repository.save(course);
logger .info ("Courses -> {} " , repository .findAll ());
logger .info ("Count -> {} " , repository .count ());
}
@ Test
public void sort () {
Sort sort = new Sort (Sort .Direction .ASC , "name" );
logger .info ("Sorted Courses -> {} " , repository .findAll (sort ));
//Courses -> [Course[JPA in 50 Steps], Course[Spring in 50 Steps], Course[Spring Boot in 100 Steps]]
}
@ Test
public void pagination () {
PageRequest pageRequest = PageRequest .of (0 , 3 );
Page <Course > firstPage = repository .findAll (pageRequest );
logger .info ("First Page -> {} " , firstPage );
}
}
/02-jpa-advanced/src/test/java/com/in28minutes/jpa/hibernate/demo/repository/CriteriaQueryTest.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import java .util .List ;
import javax .persistence .EntityManager ;
import javax .persistence .TypedQuery ;
import javax .persistence .criteria .CriteriaBuilder ;
import javax .persistence .criteria .CriteriaQuery ;
import javax .persistence .criteria .Join ;
import javax .persistence .criteria .JoinType ;
import javax .persistence .criteria .Predicate ;
import javax .persistence .criteria .Root ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .test .context .junit4 .SpringRunner ;
import com .in28minutes .jpa .hibernate .demo .DemoApplication ;
import com .in28minutes .jpa .hibernate .demo .entity .Course ;
@ RunWith (SpringRunner .class )
@ SpringBootTest (classes = DemoApplication .class )
public class CriteriaQueryTest {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
EntityManager em ;
@ Test
public void all_courses () {
// "Select c From Course c"
// 1. Use Criteria Builder to create a Criteria Query returning the
// expected result object
CriteriaBuilder cb = em .getCriteriaBuilder ();
CriteriaQuery <Course > cq = cb .createQuery (Course .class );
// 2. Define roots for tables which are involved in the query
Root <Course > courseRoot = cq .from (Course .class );
// 3. Define Predicates etc using Criteria Builder
// 4. Add Predicates etc to the Criteria Query
// 5. Build the TypedQuery using the entity manager and criteria query
TypedQuery <Course > query = em .createQuery (cq .select (courseRoot ));
List <Course > resultList = query .getResultList ();
logger .info ("Typed Query -> {}" , resultList );
// [Course[JPA in 50 Steps], Course[Spring in 50 Steps], Course[Spring
// Boot in 100 Steps]]
}
@ Test
public void all_courses_having_100Steps () {
// "Select c From Course c where name like '%100 Steps' "
// 1. Use Criteria Builder to create a Criteria Query returning the
// expected result object
CriteriaBuilder cb = em .getCriteriaBuilder ();
CriteriaQuery <Course > cq = cb .createQuery (Course .class );
// 2. Define roots for tables which are involved in the query
Root <Course > courseRoot = cq .from (Course .class );
// 3. Define Predicates etc using Criteria Builder
Predicate like100Steps = cb .like (courseRoot .get ("name" ), "%100 Steps" );
// 4. Add Predicates etc to the Criteria Query
cq .where (like100Steps );
// 5. Build the TypedQuery using the entity manager and criteria query
TypedQuery <Course > query = em .createQuery (cq .select (courseRoot ));
List <Course > resultList = query .getResultList ();
logger .info ("Typed Query -> {}" , resultList );
// [Course[Spring Boot in 100 Steps]]
}
@ Test
public void all_courses_without_students () {
// "Select c From Course c where c.students is empty"
// 1. Use Criteria Builder to create a Criteria Query returning the
// expected result object
CriteriaBuilder cb = em .getCriteriaBuilder ();
CriteriaQuery <Course > cq = cb .createQuery (Course .class );
// 2. Define roots for tables which are involved in the query
Root <Course > courseRoot = cq .from (Course .class );
// 3. Define Predicates etc using Criteria Builder
Predicate studentsIsEmpty = cb .isEmpty (courseRoot .get ("students" ));
// 4. Add Predicates etc to the Criteria Query
cq .where (studentsIsEmpty );
// 5. Build the TypedQuery using the entity manager and criteria query
TypedQuery <Course > query = em .createQuery (cq .select (courseRoot ));
List <Course > resultList = query .getResultList ();
logger .info ("Typed Query -> {}" , resultList );
// [Course[Spring in 50 Steps]]
}
@ Test
public void join () {
// "Select c From Course c join c.students s"
// 1. Use Criteria Builder to create a Criteria Query returning the
// expected result object
CriteriaBuilder cb = em .getCriteriaBuilder ();
CriteriaQuery <Course > cq = cb .createQuery (Course .class );
// 2. Define roots for tables which are involved in the query
Root <Course > courseRoot = cq .from (Course .class );
// 3. Define Predicates etc using Criteria Builder
Join <Object , Object > join = courseRoot .join ("students" );
// 4. Add Predicates etc to the Criteria Query
// 5. Build the TypedQuery using the entity manager and criteria query
TypedQuery <Course > query = em .createQuery (cq .select (courseRoot ));
List <Course > resultList = query .getResultList ();
logger .info ("Typed Query -> {}" , resultList );
// [Course[JPA in 50 Steps], Course[JPA in 50 Steps], Course[JPA in 50
// Steps], Course[Spring Boot in 100 Steps]]
}
@ Test
public void left_join () {
// "Select c From Course c left join c.students s"
// 1. Use Criteria Builder to create a Criteria Query returning the
// expected result object
CriteriaBuilder cb = em .getCriteriaBuilder ();
CriteriaQuery <Course > cq = cb .createQuery (Course .class );
// 2. Define roots for tables which are involved in the query
Root <Course > courseRoot = cq .from (Course .class );
// 3. Define Predicates etc using Criteria Builder
Join <Object , Object > join = courseRoot .join ("students" , JoinType .LEFT );
// 4. Add Predicates etc to the Criteria Query
// 5. Build the TypedQuery using the entity manager and criteria query
TypedQuery <Course > query = em .createQuery (cq .select (courseRoot ));
List <Course > resultList = query .getResultList ();
logger .info ("Typed Query -> {}" , resultList );
// [Course[JPA in 50 Steps], Course[JPA in 50 Steps], Course[JPA in 50
// Steps], Course[Spring in 50 Steps], Course[Spring Boot in 100 Steps]]
}
}
/02-jpa-advanced/src/test/java/com/in28minutes/jpa/hibernate/demo/repository/JPQLTest.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import java .util .List ;
import javax .persistence .EntityManager ;
import javax .persistence .Query ;
import javax .persistence .TypedQuery ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .test .context .junit4 .SpringRunner ;
import com .in28minutes .jpa .hibernate .demo .DemoApplication ;
import com .in28minutes .jpa .hibernate .demo .entity .Course ;
import com .in28minutes .jpa .hibernate .demo .entity .Student ;
@ RunWith (SpringRunner .class )
@ SpringBootTest (classes = DemoApplication .class )
public class JPQLTest {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
EntityManager em ;
@ Test
public void jpql_basic () {
Query query = em .createNamedQuery ("query_get_all_courses" );
List resultList = query .getResultList ();
logger .info ("Select c From Course c -> {}" , resultList );
}
@ Test
public void jpql_typed () {
TypedQuery <Course > query = em .createNamedQuery ("query_get_all_courses" , Course .class );
List <Course > resultList = query .getResultList ();
logger .info ("Select c From Course c -> {}" , resultList );
}
@ Test
public void jpql_where () {
TypedQuery <Course > query = em .createNamedQuery ("query_get_100_Step_courses" , Course .class );
List <Course > resultList = query .getResultList ();
logger .info ("Select c From Course c where name like '%100 Steps'-> {}" , resultList );
// [Course[Web Services in 100 Steps], Course[Spring Boot in 100 Steps]]
}
@ Test
public void jpql_courses_without_students () {
TypedQuery <Course > query = em .createQuery ("Select c from Course c where c.students is empty" , Course .class );
List <Course > resultList = query .getResultList ();
logger .info ("Results -> {}" , resultList );
// [Course[Spring in 50 Steps]]
}
@ Test
public void jpql_courses_with_atleast_2_students () {
TypedQuery <Course > query = em .createQuery ("Select c from Course c where size(c.students) >= 2" , Course .class );
List <Course > resultList = query .getResultList ();
logger .info ("Results -> {}" , resultList );
//[Course[JPA in 50 Steps]]
}
@ Test
public void jpql_courses_ordered_by_students () {
TypedQuery <Course > query = em .createQuery ("Select c from Course c order by size(c.students) desc" , Course .class );
List <Course > resultList = query .getResultList ();
logger .info ("Results -> {}" , resultList );
}
@ Test
public void jpql_students_with_passports_in_a_certain_pattern () {
TypedQuery <Student > query = em .createQuery ("Select s from Student s where s.passport.number like '%1234%'" , Student .class );
List <Student > resultList = query .getResultList ();
logger .info ("Results -> {}" , resultList );
}
//like
//BETWEEN 100 and 1000
//IS NULL
//upper, lower, trim, length
//JOIN => Select c, s from Course c JOIN c.students s
//LEFT JOIN => Select c, s from Course c LEFT JOIN c.students s
//CROSS JOIN => Select c, s from Course c, Student s
//3 and 4 =>3 * 4 = 12 Rows
@ Test
public void join (){
Query query = em .createQuery ("Select c, s from Course c JOIN c.students s" );
List <Object []> resultList = query .getResultList ();
logger .info ("Results Size -> {}" , resultList .size ());
for (Object [] result :resultList ){
logger .info ("Course{} Student{}" , result [0 ], result [1 ]);
}
}
@ Test
public void left_join (){
Query query = em .createQuery ("Select c, s from Course c LEFT JOIN c.students s" );
List <Object []> resultList = query .getResultList ();
logger .info ("Results Size -> {}" , resultList .size ());
for (Object [] result :resultList ){
logger .info ("Course{} Student{}" , result [0 ], result [1 ]);
}
}
@ Test
public void cross_join (){
Query query = em .createQuery ("Select c, s from Course c, Student s" );
List <Object []> resultList = query .getResultList ();
logger .info ("Results Size -> {}" , resultList .size ());
for (Object [] result :resultList ){
logger .info ("Course{} Student{}" , result [0 ], result [1 ]);
}
}
}
/02-jpa-advanced/src/test/java/com/in28minutes/jpa/hibernate/demo/repository/NativeQueriesTest.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import java .util .List ;
import javax .persistence .EntityManager ;
import javax .persistence .Query ;
import javax .persistence .TypedQuery ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .test .context .junit4 .SpringRunner ;
import org .springframework .transaction .annotation .Transactional ;
import com .in28minutes .jpa .hibernate .demo .DemoApplication ;
import com .in28minutes .jpa .hibernate .demo .entity .Course ;
@ RunWith (SpringRunner .class )
@ SpringBootTest (classes = DemoApplication .class )
public class NativeQueriesTest {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
EntityManager em ;
@ Test
public void native_queries_basic () {
Query query = em .createNativeQuery ("SELECT * FROM COURSE" , Course .class );
List resultList = query .getResultList ();
logger .info ("SELECT * FROM COURSE -> {}" , resultList );
//SELECT * FROM COURSE -> [Course[Web Services in 100 Steps], Course[JPA in 50 Steps - Updated], Course[Spring in 50 Steps], Course[Spring Boot in 100 Steps]]
}
@ Test
public void native_queries_with_parameter () {
Query query = em .createNativeQuery ("SELECT * FROM COURSE where id = ?" , Course .class );
query .setParameter (1 , 10001L );
List resultList = query .getResultList ();
logger .info ("SELECT * FROM COURSE where id = ? -> {}" , resultList );
//[Course[JPA in 50 Steps - Updated]]
}
@ Test
public void native_queries_with_named_parameter () {
Query query = em .createNativeQuery ("SELECT * FROM COURSE where id = :id" , Course .class );
query .setParameter ("id" , 10001L );
List resultList = query .getResultList ();
logger .info ("SELECT * FROM COURSE where id = :id -> {}" , resultList );
//[Course[JPA in 50 Steps - Updated]]
}
@ Test
@ Transactional
public void native_queries_to_update () {
Query query = em .createNativeQuery ("Update COURSE set last_updated_date=sysdate()" );
int noOfRowsUpdated = query .executeUpdate ();
logger .info ("noOfRowsUpdated -> {}" , noOfRowsUpdated );
//SELECT * FROM COURSE -> [Course[Web Services in 100 Steps], Course[JPA in 50 Steps - Updated], Course[Spring in 50 Steps], Course[Spring Boot in 100 Steps]]
}
}
/02-jpa-advanced/src/test/java/com/in28minutes/jpa/hibernate/demo/repository/StudentRepositoryTest.java
package com .in28minutes .jpa .hibernate .demo .repository ;
import javax .persistence .EntityManager ;
import org .junit .Test ;
import org .junit .runner .RunWith ;
import org .slf4j .Logger ;
import org .slf4j .LoggerFactory ;
import org .springframework .beans .factory .annotation .Autowired ;
import org .springframework .boot .test .context .SpringBootTest ;
import org .springframework .test .context .junit4 .SpringRunner ;
import org .springframework .transaction .annotation .Transactional ;
import com .in28minutes .jpa .hibernate .demo .DemoApplication ;
import com .in28minutes .jpa .hibernate .demo .entity .Passport ;
import com .in28minutes .jpa .hibernate .demo .entity .Student ;
@ RunWith (SpringRunner .class )
@ SpringBootTest (classes = DemoApplication .class )
public class StudentRepositoryTest {
private Logger logger = LoggerFactory .getLogger (this .getClass ());
@ Autowired
StudentRepository repository ;
@ Autowired
EntityManager em ;
// Session & Session Factory
// EntityManager & Persistence Context
// Transaction
@ Test
public void someTest () {
repository .someOperationToUnderstandPersistenceContext ();
}
@ Test
@ Transactional
public void retrieveStudentAndPassportDetails () {
Student student = em .find (Student .class , 20001L );
logger .info ("student -> {}" , student );
logger .info ("passport -> {}" , student .getPassport ());
}
@ Test
@ Transactional
public void retrievePassportAndAssociatedStudent () {
Passport passport = em .find (Passport .class , 40001L );
logger .info ("passport -> {}" , passport );
logger .info ("student -> {}" , passport .getStudent ());
}
@ Test
@ Transactional
public void retrieveStudentAndCourses () {
Student student = em .find (Student .class , 20001L );
logger .info ("student -> {}" , student );
logger .info ("courses -> {}" , student .getCourses ());
}
}