From 56c0801502786a966562b233b859c4c86c410cb1 Mon Sep 17 00:00:00 2001 From: Igor Kashin Date: Sat, 19 Jun 2021 23:26:58 +0300 Subject: [PATCH] chapter 03 jdbc --- .../components/IngredientByIdConverter.java | 25 +++++++ .../java/tacos/data/IngredientRepository.java | 11 +++ .../tacos/data/JdbcIngredientRepository.java | 51 ++++++++++++++ .../java/tacos/data/JdbcTacoRepository.java | 68 +++++++++++++++++++ .../main/java/tacos/data/OrderRepository.java | 7 ++ .../main/java/tacos/data/TacoRepository.java | 7 ++ taco-cloud/src/main/resources/data.sql | 15 ++++ taco-cloud/src/main/resources/schema.sql | 38 +++++++++++ 8 files changed, 222 insertions(+) create mode 100644 taco-cloud/src/main/java/tacos/components/IngredientByIdConverter.java create mode 100644 taco-cloud/src/main/java/tacos/data/IngredientRepository.java create mode 100644 taco-cloud/src/main/java/tacos/data/JdbcIngredientRepository.java create mode 100644 taco-cloud/src/main/java/tacos/data/JdbcTacoRepository.java create mode 100644 taco-cloud/src/main/java/tacos/data/OrderRepository.java create mode 100644 taco-cloud/src/main/java/tacos/data/TacoRepository.java create mode 100644 taco-cloud/src/main/resources/data.sql create mode 100644 taco-cloud/src/main/resources/schema.sql diff --git a/taco-cloud/src/main/java/tacos/components/IngredientByIdConverter.java b/taco-cloud/src/main/java/tacos/components/IngredientByIdConverter.java new file mode 100644 index 0000000..9ad0bb5 --- /dev/null +++ b/taco-cloud/src/main/java/tacos/components/IngredientByIdConverter.java @@ -0,0 +1,25 @@ +package tacos.components; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.convert.converter.Converter; +import org.springframework.stereotype.Component; + +import tacos.Ingredient; +import tacos.data.IngredientRepository; + +@Component +public class IngredientByIdConverter + implements Converter { + + private IngredientRepository ingredientRepo; + + @Autowired + public IngredientByIdConverter(IngredientRepository ingredientRepo) { + this.ingredientRepo = ingredientRepo; + } + + @Override + public Ingredient convert(String id) { + return ingredientRepo.findOne(id); + } +} \ No newline at end of file diff --git a/taco-cloud/src/main/java/tacos/data/IngredientRepository.java b/taco-cloud/src/main/java/tacos/data/IngredientRepository.java new file mode 100644 index 0000000..6d2c2d1 --- /dev/null +++ b/taco-cloud/src/main/java/tacos/data/IngredientRepository.java @@ -0,0 +1,11 @@ +package tacos.data; + +import tacos.Ingredient; + +public interface IngredientRepository { + Iterable findAll(); + + Ingredient findOne(String id); + + Ingredient save(Ingredient ingredient); +} diff --git a/taco-cloud/src/main/java/tacos/data/JdbcIngredientRepository.java b/taco-cloud/src/main/java/tacos/data/JdbcIngredientRepository.java new file mode 100644 index 0000000..f9173d4 --- /dev/null +++ b/taco-cloud/src/main/java/tacos/data/JdbcIngredientRepository.java @@ -0,0 +1,51 @@ +package tacos.data; + +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import tacos.Ingredient; + +@Repository +public class JdbcIngredientRepository implements IngredientRepository { + private JdbcTemplate jdbc; + + @Autowired + public JdbcIngredientRepository(JdbcTemplate jdbc) { + this.jdbc = jdbc; + } + + @Override + public Iterable findAll() { + return jdbc.query("select id, name, type from Ingredient", + this::mapRowToIngredient); + } + + @Override + public Ingredient findOne(String id) { + return jdbc.queryForObject( + "select id, name, type from Ingredient where id=?", + this::mapRowToIngredient, id); + } + + private Ingredient mapRowToIngredient(ResultSet rs, int rowNum) + throws SQLException { + return new Ingredient( + rs.getString("id"), + rs.getString("name"), + Ingredient.Type.valueOf(rs.getString("type"))); + } + + @Override + public Ingredient save(Ingredient ingredient) { + jdbc.update( + "insert into Ingredient (id, name, type) values (?, ?, ?)", + ingredient.getId(), + ingredient.getName(), + ingredient.getType().toString()); + return ingredient; + } +} diff --git a/taco-cloud/src/main/java/tacos/data/JdbcTacoRepository.java b/taco-cloud/src/main/java/tacos/data/JdbcTacoRepository.java new file mode 100644 index 0000000..44c4f41 --- /dev/null +++ b/taco-cloud/src/main/java/tacos/data/JdbcTacoRepository.java @@ -0,0 +1,68 @@ +package tacos.data; + +import java.sql.Timestamp; +import java.sql.Types; +import java.util.Arrays; +import java.util.Date; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.jdbc.core.PreparedStatementCreator; +import org.springframework.jdbc.core.PreparedStatementCreatorFactory; +import org.springframework.jdbc.support.GeneratedKeyHolder; +import org.springframework.jdbc.support.KeyHolder; +import org.springframework.stereotype.Repository; + +import tacos.Ingredient; +import tacos.Taco; + +@Repository +public class JdbcTacoRepository implements TacoRepository { + private JdbcTemplate jdbc; + + @Autowired + public JdbcTacoRepository(JdbcTemplate jdbc) { + this.jdbc = jdbc; + } + + @Override + public Taco save(Taco taco) { + long tacoId = saveTacoInfo(taco); + taco.setId(tacoId); + for (Ingredient ingredient : taco.getIngredients()) { + saveIngredientToTaco(ingredient, tacoId); + } + + return taco; + } + + private void saveIngredientToTaco(Ingredient ingredient, long tacoId) { + jdbc.update( + "insert into Taco_Ingredients (taco, ingredient) " + + "values (?, ?)", + tacoId, ingredient.getId()); + } + + private long saveTacoInfo(Taco taco) { + taco.setCreatedAt(new Date()); + + PreparedStatementCreatorFactory pscf = + new PreparedStatementCreatorFactory( + "insert into Taco (name, createdAt) values (?, ?)", + Types.VARCHAR, Types.TIMESTAMP + ); + pscf.setReturnGeneratedKeys(true); + + PreparedStatementCreator psc = pscf.newPreparedStatementCreator( + Arrays.asList( + taco.getName(), + new Timestamp(taco.getCreatedAt().getTime()))); + + + KeyHolder keyHolder = new GeneratedKeyHolder(); + jdbc.update(psc, keyHolder); + + return keyHolder.getKey().longValue(); + } + +} diff --git a/taco-cloud/src/main/java/tacos/data/OrderRepository.java b/taco-cloud/src/main/java/tacos/data/OrderRepository.java new file mode 100644 index 0000000..265d756 --- /dev/null +++ b/taco-cloud/src/main/java/tacos/data/OrderRepository.java @@ -0,0 +1,7 @@ +package tacos.data; + +import tacos.Order; + +public interface OrderRepository { + Order save(Order order); +} diff --git a/taco-cloud/src/main/java/tacos/data/TacoRepository.java b/taco-cloud/src/main/java/tacos/data/TacoRepository.java new file mode 100644 index 0000000..e01fb4a --- /dev/null +++ b/taco-cloud/src/main/java/tacos/data/TacoRepository.java @@ -0,0 +1,7 @@ +package tacos.data; + +import tacos.Taco; + +public interface TacoRepository { + Taco save(Taco taco); +} diff --git a/taco-cloud/src/main/resources/data.sql b/taco-cloud/src/main/resources/data.sql new file mode 100644 index 0000000..69e9a41 --- /dev/null +++ b/taco-cloud/src/main/resources/data.sql @@ -0,0 +1,15 @@ +delete from Taco_Order_Tacos; +delete from Taco_Ingredients; +delete from Taco; +delete from Taco_Order; +delete from Ingredient; +insert into Ingredient (id, name, type) values ('FLTO', 'Flour Tortilla', 'WRAP'); +insert into Ingredient (id, name, type) values ('COTO', 'Corn Tortilla', 'WRAP'); +insert into Ingredient (id, name, type) values ('GRBF', 'Ground Beef', 'PROTEIN'); +insert into Ingredient (id, name, type) values ('CARN', 'Carnitas', 'PROTEIN'); +insert into Ingredient (id, name, type) values ('TMTO', 'Diced Tomatoes', 'VEGGIES'); +insert into Ingredient (id, name, type) values ('LETC', 'Lettuce', 'VEGGIES'); +insert into Ingredient (id, name, type) values ('CHED', 'Cheddar', 'CHEESE'); +insert into Ingredient (id, name, type) values ('JACK', 'Monterrey Jack', 'CHEESE'); +insert into Ingredient (id, name, type) values ('SLSA', 'Salsa', 'SAUCE'); +insert into Ingredient (id, name, type) values ('SRCR', 'Sour Cream', 'SAUCE'); diff --git a/taco-cloud/src/main/resources/schema.sql b/taco-cloud/src/main/resources/schema.sql new file mode 100644 index 0000000..2a103dd --- /dev/null +++ b/taco-cloud/src/main/resources/schema.sql @@ -0,0 +1,38 @@ +create table if not exists Ingredient ( + id varchar(4) not null, + name varchar(25) not null, + type varchar(10) not null +); +create table if not exists Taco ( + id identity, + name varchar(50) not null, + createdAt timestamp not null +); +create table if not exists Taco_Ingredients ( + taco bigint not null, + ingredient varchar(4) not null +); +alter table Taco_Ingredients + add foreign key (taco) references Taco(id); +alter table Taco_Ingredients + add foreign key (ingredient) references Ingredient(id); +create table if not exists Taco_Order ( + id identity, + deliveryName varchar(50) not null, + deliveryStreet varchar(50) not null, + deliveryCity varchar(50) not null, + deliveryState varchar(2) not null, + deliveryZip varchar(10) not null, + ccNumber varchar(16) not null, + ccExpiration varchar(5) not null, + ccCVV varchar(3) not null, + placedAt timestamp not null +); +create table if not exists Taco_Order_Tacos ( + tacoOrder bigint not null, + taco bigint not null +); +alter table Taco_Order_Tacos + add foreign key (tacoOrder) references Taco_Order(id); +alter table Taco_Order_Tacos + add foreign key (taco) references Taco(id); \ No newline at end of file