diff --git a/data-h2.sql b/data-h2.sql index f6f18b5..5bc94b8 100644 --- a/data-h2.sql +++ b/data-h2.sql @@ -12,4 +12,17 @@ INSERT INTO PERSON ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID)VALUES ('S INSERT INTO PERSON ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID)VALUES ('Smith', 'Jane', '393-6181', '1987-12-06', 3); INSERT INTO PERSON ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID)VALUES ('Brown', 'Doug', '466-6241', '1954-12-07', 3); +INSERT INTO movies (title, runtime, genre, imdb_score, rating) VALUES +('Howard the Duck', 110, 'Sci-Fi', 4.6, 'PG'), +('Lavalantula', 83, 'Horror', 4.7, 'TV-14'), +('Starship Troopers', 129, 'Sci-Fi', 7.2, 'PG-13'), +('Waltz With Bashir',90,'Documentary',8.0,'R'), +('Spaceballs', 96, 'Comedy', 7.1,'PG'), +('Monsters Inc.', 92, 'Animation', 8.1, 'G'); + +INSERT INTO movies (title, runtime, genre, imdb_score, rating) VALUES +('Zardoz', 105, 'Sci-Fi', 5.8, 'R'), +('The Room', 99, 'Comedy', 3.6, 'R'), +('Mad Max: Fury Road', 120, 'Action', 8.1, 'R'); + diff --git a/pom.xml b/pom.xml index 274f418..ecf5bde 100644 --- a/pom.xml +++ b/pom.xml @@ -48,6 +48,11 @@ spring-boot-starter-test test + + org.springframework + spring-context + 4.3.4.RELEASE + diff --git a/src/main/java/io/zipcoder/persistenceapp/cache/PersonSurnameSearchCache.java b/src/main/java/io/zipcoder/persistenceapp/cache/PersonSurnameSearchCache.java new file mode 100644 index 0000000..ad33f39 --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/cache/PersonSurnameSearchCache.java @@ -0,0 +1,13 @@ +package io.zipcoder.persistenceapp.cache; + +import io.zipcoder.persistenceapp.domain.Person; +import org.springframework.context.annotation.Bean; + +import java.util.List; + + +public interface PersonSurnameSearchCache { + + public List getCache(); + public void setCache(List cache); +} diff --git a/src/main/java/io/zipcoder/persistenceapp/cache/PersonSurnameSearchCacheImp.java b/src/main/java/io/zipcoder/persistenceapp/cache/PersonSurnameSearchCacheImp.java new file mode 100644 index 0000000..ee679bd --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/cache/PersonSurnameSearchCacheImp.java @@ -0,0 +1,21 @@ +package io.zipcoder.persistenceapp.cache; + +import io.zipcoder.persistenceapp.domain.Person; +import org.hibernate.annotations.Cache; +import org.springframework.context.annotation.Bean; + +import java.util.ArrayList; +import java.util.List; + + +public class PersonSurnameSearchCacheImp implements PersonSurnameSearchCache { + private List cache = new ArrayList<>(); + + public List getCache() { + return cache; + } + + public void setCache(List cache) { + this.cache = cache; + } +} diff --git a/src/main/java/io/zipcoder/persistenceapp/config/AppConfig.java b/src/main/java/io/zipcoder/persistenceapp/config/AppConfig.java new file mode 100644 index 0000000..7d804fa --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/config/AppConfig.java @@ -0,0 +1,15 @@ +package io.zipcoder.persistenceapp.config; + +import io.zipcoder.persistenceapp.cache.PersonSurnameSearchCache; +import io.zipcoder.persistenceapp.cache.PersonSurnameSearchCacheImp; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AppConfig { + + @Bean + public PersonSurnameSearchCache personSurnameSearchCache(){ + return new PersonSurnameSearchCacheImp(); + } +} diff --git a/src/main/java/io/zipcoder/persistenceapp/controller/HomeController.java b/src/main/java/io/zipcoder/persistenceapp/controller/HomeController.java new file mode 100644 index 0000000..3488034 --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/controller/HomeController.java @@ -0,0 +1,32 @@ +package io.zipcoder.persistenceapp.controller; + + +import io.zipcoder.persistenceapp.domain.Home; +import io.zipcoder.persistenceapp.service.HomeService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HomeController { + + @Autowired + HomeService service; + + @RequestMapping(value = "/home/{id}", method = RequestMethod.GET) + public ResponseEntity getHomeById(@PathVariable int id){ + try { + Home home = service.getHomeById(id); + return new ResponseEntity<>(home, HttpStatus.OK); + } + catch(EmptyResultDataAccessException e){ + return new ResponseEntity<>("Home Not Found In Database",HttpStatus.NOT_FOUND); + } + } + +} diff --git a/src/main/java/io/zipcoder/persistenceapp/controller/PersonController.java b/src/main/java/io/zipcoder/persistenceapp/controller/PersonController.java new file mode 100644 index 0000000..5980743 --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/controller/PersonController.java @@ -0,0 +1,118 @@ +package io.zipcoder.persistenceapp.controller; + +import io.zipcoder.persistenceapp.domain.Person; +import io.zipcoder.persistenceapp.service.PersonService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpRequest; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; +import java.util.Map; + +@RestController +public class PersonController { + + @Autowired + PersonService service; + + @RequestMapping(value = "/person/{id}", method = RequestMethod.GET) + public ResponseEntity getPersonById(@PathVariable int id){ + try { + Person person = service.getPersonById(id); + return new ResponseEntity<>(person, HttpStatus.OK); + } + catch(EmptyResultDataAccessException e){ + return new ResponseEntity<>("Person Not Found In Database",HttpStatus.NOT_FOUND); + } + } + + @RequestMapping(value = "/person", method = RequestMethod.GET) + public ResponseEntity getAllPersons () { + try{ + List people = service.getAllPerson(); + return new ResponseEntity<>(people, HttpStatus.OK); + } + catch(EmptyResultDataAccessException e){ + return new ResponseEntity<>("No People Currently In Database", HttpStatus.NOT_FOUND); + } + } + + @RequestMapping(value = "/person/{id}", method = RequestMethod.DELETE) + public ResponseEntity deletePerson(@PathVariable int id) { + try { + service.deletePerson(id); + return new ResponseEntity<>(HttpStatus.OK); + } + catch(EmptyResultDataAccessException e){ + return new ResponseEntity<>("Person Not Found In Database",HttpStatus.NOT_FOUND); + } + } + + @RequestMapping(value = "/person/reverselookup/{mobile}", method = RequestMethod.GET) + public ResponseEntity getPersonByMobile(@PathVariable String mobile){ + try { + Person person = service.getPersonByMobile(mobile); + return new ResponseEntity<>(person, HttpStatus.OK); + } + catch(EmptyResultDataAccessException e){ + return new ResponseEntity<>("Person Not Found In Database",HttpStatus.NOT_FOUND); + } + } + + @RequestMapping(value = "/person/surname/{lastName}", method = RequestMethod.GET) + public ResponseEntity getAllPersonsWithSurname (@PathVariable String lastName) { + + List people = service.getAllPersonWithSurname(lastName); + if (people.size() == 0){ + return new ResponseEntity<>("No People With That Surname In Database", HttpStatus.NOT_FOUND); + } + else { + return new ResponseEntity<>(people, HttpStatus.OK); + } + } + + @RequestMapping(value = "/person/surname", method = RequestMethod.GET) + public ResponseEntity getSurnameCache(){ + List people = service.getSurnameCache(); + if (people.size() == 0){ + return new ResponseEntity<>("No Previous Search To Reference", HttpStatus.NOT_FOUND); + } + else { + return new ResponseEntity<>(people, HttpStatus.OK); + } + } + + @RequestMapping(value = "/person/firstname/stats", method = RequestMethod.GET) + public ResponseEntity getFirstNameStats () { + Map results = service.getFirstNameStats(); + if(results.keySet().size() == 0){ + return new ResponseEntity<>("No People In Database", HttpStatus.NOT_FOUND); + } + else{ + return new ResponseEntity<>(results, HttpStatus.OK); + } + } + + @RequestMapping(value = "/person", method = RequestMethod.POST) + public ResponseEntity addPerson(@RequestBody Person person){ + service.addPerson(person); + return new ResponseEntity<>(HttpStatus.CREATED); + } + + @RequestMapping(value = "/person/{id}", method = RequestMethod.PUT) + public ResponseEntity updatePerson(@PathVariable int id, @RequestBody Person person){ + try { + service.getPersonById(id); + } + catch(EmptyResultDataAccessException e){ + return new ResponseEntity<>("Person Not Found In Database",HttpStatus.NOT_FOUND); + } + service.updatePerson(person, id); + return new ResponseEntity<>(HttpStatus.OK); + } + +} diff --git a/src/main/java/io/zipcoder/persistenceapp/domain/Home.java b/src/main/java/io/zipcoder/persistenceapp/domain/Home.java new file mode 100644 index 0000000..15984ed --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/domain/Home.java @@ -0,0 +1,31 @@ +package io.zipcoder.persistenceapp.domain; + +public class Home { + private int id; + private String address; + private String homeNumber; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getHomeNumber() { + return homeNumber; + } + + public void setHomeNumber(String homeNumber) { + this.homeNumber = homeNumber; + } +} diff --git a/src/main/java/io/zipcoder/persistenceapp/domain/Person.java b/src/main/java/io/zipcoder/persistenceapp/domain/Person.java new file mode 100644 index 0000000..30d7afb --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/domain/Person.java @@ -0,0 +1,65 @@ +package io.zipcoder.persistenceapp.domain; + +import javax.persistence.Entity; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + + +public class Person { + private int id; + private String firstName; + private String lastName; + private String mobile; + private Date birthday; + private int homeId; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + + this.birthday = birthday; + } + + public int getHomeId() { + return homeId; + } + + public void setHomeId(int homeId) { + this.homeId = homeId; + } +} diff --git a/src/main/java/io/zipcoder/persistenceapp/rowmapper/HomeRowMapper.java b/src/main/java/io/zipcoder/persistenceapp/rowmapper/HomeRowMapper.java new file mode 100644 index 0000000..a36982a --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/rowmapper/HomeRowMapper.java @@ -0,0 +1,19 @@ +package io.zipcoder.persistenceapp.rowmapper; + +import io.zipcoder.persistenceapp.domain.Home; +import org.springframework.jdbc.core.RowMapper; + +import java.sql.ResultSet; +import java.sql.SQLException; + +public class HomeRowMapper implements RowMapper { + @Override + public Object mapRow(ResultSet rs, int rowNum) throws SQLException { + Home home = new Home(); + home.setId(rs.getInt("ID")); + home.setAddress(rs.getString("ADDRESS")); + home.setHomeNumber(rs.getString("HOMENUMBER")); + + return home; + } +} diff --git a/src/main/java/io/zipcoder/persistenceapp/rowmapper/PersonRowMapper.java b/src/main/java/io/zipcoder/persistenceapp/rowmapper/PersonRowMapper.java new file mode 100644 index 0000000..5c47373 --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/rowmapper/PersonRowMapper.java @@ -0,0 +1,25 @@ +package io.zipcoder.persistenceapp.rowmapper; + + +import io.zipcoder.persistenceapp.domain.Person; +import org.springframework.jdbc.core.RowMapper; + +import javax.swing.tree.TreePath; +import java.sql.ResultSet; +import java.sql.SQLException; + +public class PersonRowMapper implements RowMapper { + + @Override + public Object mapRow(ResultSet rs, int rowNum) throws SQLException { + Person person = new Person(); + person.setId(rs.getInt("ID")); + person.setFirstName(rs.getString("FIRST_NAME")); + person.setLastName(rs.getString("LAST_NAME")); + person.setMobile(rs.getString("MOBILE")); + person.setBirthday(rs.getDate("BIRTHDAY")); + person.setHomeId(rs.getInt("HOME_ID")); + + return person; + } +} diff --git a/src/main/java/io/zipcoder/persistenceapp/service/HomeService.java b/src/main/java/io/zipcoder/persistenceapp/service/HomeService.java new file mode 100644 index 0000000..f469e05 --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/service/HomeService.java @@ -0,0 +1,23 @@ +package io.zipcoder.persistenceapp.service; + +import io.zipcoder.persistenceapp.domain.Home; +import io.zipcoder.persistenceapp.domain.Person; +import io.zipcoder.persistenceapp.rowmapper.HomeRowMapper; +import io.zipcoder.persistenceapp.rowmapper.PersonRowMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +@Service +public class HomeService { + + @Autowired + JdbcTemplate jdbc; + + public Home getHomeById(int homeId) throws EmptyResultDataAccessException { + String sql = "SELECT * FROM HOME WHERE ID = ?"; + return (Home) jdbc.queryForObject(sql, new Object[]{homeId}, new HomeRowMapper()); + } + +} diff --git a/src/main/java/io/zipcoder/persistenceapp/service/PersonService.java b/src/main/java/io/zipcoder/persistenceapp/service/PersonService.java new file mode 100644 index 0000000..76a19f1 --- /dev/null +++ b/src/main/java/io/zipcoder/persistenceapp/service/PersonService.java @@ -0,0 +1,104 @@ +package io.zipcoder.persistenceapp.service; + +import io.zipcoder.persistenceapp.cache.PersonSurnameSearchCache; +import io.zipcoder.persistenceapp.domain.Person; +import io.zipcoder.persistenceapp.rowmapper.PersonRowMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.dao.EmptyResultDataAccessException; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Service; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.*; + +@Service +public class PersonService { + + @Autowired + JdbcTemplate jdbc; + + @Autowired + PersonSurnameSearchCache surnameCache; + + + public Person getPersonById(int personId) throws EmptyResultDataAccessException { + String sql = "SELECT * FROM PERSON WHERE ID = ?"; + return (Person) jdbc.queryForObject(sql, new Object[]{personId}, new PersonRowMapper()); + + } + + public List getAllPerson() throws EmptyResultDataAccessException { + String sql = "SELECT * FROM PERSON"; + List people = new ArrayList<>(); + List> rows = jdbc.queryForList(sql); + buildPersonList(people, rows); + return people; + } + + public void deletePerson(int personId) throws EmptyResultDataAccessException { + String sql = "DELETE FROM PERSON WHERE ID = " + personId; + jdbc.execute(sql); + } + + public Person getPersonByMobile(String mobile) throws EmptyResultDataAccessException { + String sql = "SELECT * FROM PERSON WHERE MOBILE = ?"; + return (Person) jdbc.queryForObject(sql, new Object[]{mobile}, new PersonRowMapper()); + } + + public List getAllPersonWithSurname(String lastName) throws EmptyResultDataAccessException { + String sql = "SELECT * FROM PERSON WHERE LAST_NAME = ?"; + List people = new ArrayList<>(); + List> rows = jdbc.queryForList(sql, new Object[]{lastName}); + buildPersonList(people, rows); + surnameCache.setCache(people); + return people; + } + + public List getSurnameCache() { + return surnameCache.getCache(); + } + + public Map getFirstNameStats () { + Map outputMap = new HashMap<>(); + String sql = "SELECT first_name, COUNT(first_name) FROM person GROUP BY first_name"; + List> rows = jdbc.queryForList(sql); + for(Map row : rows){ + String name = (String) row.get("FIRST_NAME"); + Number frequency = (Number) row.get("COUNT(FIRST_NAME)"); + outputMap.put(name, frequency); + } + return outputMap; + } + + public void addPerson(Person person) { + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + String sql = "INSERT INTO person ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID ) VALUES ('" + person.getLastName() + + "','" + person.getFirstName() + "','" + person.getMobile() + "','" + format.format(person.getBirthday()) + "','" + person.getHomeId() + "')"; + jdbc.execute(sql); + } + + public void updatePerson(Person person, int id) throws EmptyResultDataAccessException { + DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + String sql = "UPDATE person SET FIRST_NAME = '" + person.getFirstName() +"', LAST_NAME = '" + person.getLastName() + + "', MOBILE = '" + person.getMobile() + "', BIRTHDAY = '" + format.format(person.getBirthday()) + "', HOME_ID = '" + + person.getHomeId() + "' WHERE ID = " + id; + jdbc.execute(sql); + } + + private void buildPersonList(List listToBuild, List> results) { + for (Map row : results) { + Person person = new Person(); + person.setId((int) row.get("ID")); + person.setFirstName((String) row.get("FIRST_NAME")); + person.setLastName((String) row.get("LAST_NAME")); + person.setMobile((String) row.get("MOBILE")); + person.setBirthday((Date) row.get("BIRTHDAY")); + person.setHomeId((short) row.get("HOME_ID")); + listToBuild.add(person); + } + + } + + +} diff --git a/src/main/resources/schema-h2.sql b/src/main/resources/schema-h2.sql index 39c2c27..b23bed0 100644 --- a/src/main/resources/schema-h2.sql +++ b/src/main/resources/schema-h2.sql @@ -61,6 +61,33 @@ CREATE TABLE auto_prices ( ); +INSERT INTO HOME (ADDRESS, HOMENUMBER) VALUES ('36 E. Bayberry Rd.Savannah, GA 31404', '565-6895'); +INSERT INTO HOME (ADDRESS, HOMENUMBER) VALUES ('11 Essex Dr.Farmingdale, NY 11735', '454-4544'); +INSERT INTO HOME (ADDRESS, HOMENUMBER) VALUES ('920 Arlington Street Clifton, NJ 07011', '985-4515'); +INSERT INTO HOME (ADDRESS, HOMENUMBER) VALUES ('234 High Street, PA 19159 ', '267-3940'); + + +INSERT INTO PERSON ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID ) VALUES ('Carbral', 'Sheeri', '230-4233', '1970-02-23', 2); +INSERT INTO PERSON ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID) VALUES ( 'Sharam', 'Raj', '186-5223', '1980-08-31', 3); +INSERT INTO PERSON ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID)VALUES ('Durand', 'Noelle', '395-6161', '1960-07-06', 1); +INSERT INTO PERSON ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID)VALUES ('Smith', 'Thomas', '395-6181', '1987-07-06', 1); +INSERT INTO PERSON ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID)VALUES ('Smith', 'Jane', '393-6181', '1987-12-06', 3); +INSERT INTO PERSON ( LAST_NAME, FIRST_NAME, MOBILE, BIRTHDAY, HOME_ID)VALUES ('Brown', 'Doug', '466-6241', '1954-12-07', 3); + +INSERT INTO movies (title, runtime, genre, imdb_score, rating) VALUES +('Howard the Duck', 110, 'Sci-Fi', 4.6, 'PG'), +('Lavalantula', 83, 'Horror', 4.7, 'TV-14'), +('Starship Troopers', 129, 'Sci-Fi', 7.2, 'PG-13'), +('Waltz With Bashir',90,'Documentary',8.0,'R'), +('Spaceballs', 96, 'Comedy', 7.1,'PG'), +('Monsters Inc.', 92, 'Animation', 8.1, 'G'); + +INSERT INTO movies (title, runtime, genre, imdb_score, rating) VALUES +('Zardoz', 105, 'Sci-Fi', 5.8, 'R'), +('The Room', 99, 'Comedy', 3.6, 'R'), +('Mad Max: Fury Road', 120, 'Action', 8.1, 'R'); + + DROP SEQUENCE hibernate_sequence; CREATE SEQUENCE hibernate_sequence;