Выбрать главу

ВСТАВКА СТРОКИ

Метод update() JdbcTemplate может использоваться для любого запроса, который записывает или обновляет данные в базе данных. И, как показано в следующем листинге, его можно использовать для вставки данные в базу данных.

Листинг 3.6 вставка данных с использованием JdbcTemplate

@Override

public Ingredient save(Ingredient ingredient) {

 jdbc.update(

   "insert into Ingredient (id, name, type) values (?, ?, ?)",

   ingredient.getId(),

   ingredient.getName(),

   ingredient.getType().toString());

 return ingredient;

}

Поскольку нет необходимости сопоставлять данные ResultSet с объектом, метод update() намного проще, чем query() или queryForObject (). Для него требуется только String, содержащий SQL, а также значения, для параметров запроса. В данном случае запрос имеет три параметра, которые соответствуют последним трем параметрам запроса метода save() - ID ингредиента, name и type.

С JdbcIngredientRepository закончили, теперь вы можете внедрить его в DesignTacoController и использовать его для предоставления списка объектов Ingredient  вместо использования жестко закодированных значений (как вы сделали в главе 2). Изменения в DesignTacoController показаны далее.

Листинг 3.7 Внедрение и использование репозитория в контроллере

@Controller

@RequestMapping("/design")

@SessionAttributes("order")

public class DesignTacoController {

 private final IngredientRepository ingredientRepo;

 @Autowired

 public DesignTacoController(IngredientRepository ingredientRepo) {

   this.ingredientRepo = ingredientRepo;

 }

 @GetMapping

 public String showDesignForm(Model model) {

   List<Ingredient> ingredients = new ArrayList<>();

   ingredientRepo.findAll().forEach(i -> ingredients.add(i));

   Type[] types = Ingredient.Type.values();

   for (Type type : types) {

     model.addAttribute(type.toString().toLowerCase(),

     filterByType(ingredients, type));

   }

   return "design";

 }

 ...

}

Обратите внимание, что вторая строка метода showDesignForm() теперь вызывает метод findAll() внедренного IngredientRepository. Метод findAll() извлекает все ингредиенты из базы данных перед их фильтрацией в различные типы в модели.

Вы почти готовы запустить приложение и попробовать эти изменения. Но прежде чем начать чтение данных из таблицы Ingredient, которая используется в запросе, вероятно, следует создать эту таблицу и заполнить ее хоть какими-то данными ингредиентов.

3.1.3 Создание схемы и предварительная загрузка данных

Помимо таблицы Ingredient, вам также понадобятся некоторые таблицы, содержащие информацию о заказах и составе тако. На рисунке 3.1 показаны необходимые таблицы, а также связи между ними.

Рисунок 3.1 таблицы схемы Taco Cloud

 

Таблицы на рис. 3.1 служат следующим целям:

Ingredient - содержит информацию об ингредиенте

Taco - содержит важную информацию о составе taco

Taco_Ingredients - содержит одну или несколько строк для каждой строки в Taco, сопоставляя taco с ингредиентами для этого taco

Taco_Order-содержит важные данные order

Taco_Order_Tacos - содержит одну или несколько строк для каждой строки в Taco_Order, сопоставляя order с taco-ми в заказе

Следующий листинг показывает SQL, который создает таблицы.

Листинг 3.8 Схема Taco Cloud

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);

Большой вопрос заключается в том, куда поместить это определение схемы. Как оказалось, Spring Boot содержит ответ на этот вопрос.

Если есть файл с именем schema.sql в корне classpath приложения, а затем SQL в этом файле будет выполняться в базе данных при запуске приложения. Поэтому содержимое листинга 3.8 следует поместить в проект в виде файла с именем schema.sql в папке src/main/resources.