美文网首页
Spring实战(第5版)第三章代码问题

Spring实战(第5版)第三章代码问题

作者: yuq329 | 来源:发表于2020-06-06 22:08 被阅读0次

Spring实战(第5版)第三章代码问题

先吐槽。。。这本书代码问题是真的多!

  • application.properties

    spring.thymeleaf.cache=false
    spring.datasource.url=jdbc:h2:mem:db;database_to_upper=false
    spring.datasource.driverClassName=org.h2.Driver
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.schema=classpath:db/schema.sql
    spring.datasource.data=classpath:db/data.sql
    spring.h2.console.enabled=true
    
    • 数据库初始化文件放在resources/db/文件夹下
  • DesignTacoController问题

    • 主要问题出在表单中的字符串如何转Ingredient
    • design.html
    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8">
        <title>Taco Cloud</title>
        <link rel="stylesheet" th:href="@{./styles.css}">
    </head>
    
    <body>
    <h1>Design your taco!</h1>
    <img th:src="@{/images/TacoCloud.png}"/>
    
    <form method="POST" th:object="${taco}">
    
        <span class="validationError"
              th:if="${#fields.hasErrors('ingredients')}"
              th:errors="*{ingredients}">Ingredient Error</span>
    
        <div class="grid">
            <div class="ingredient-group" id="wraps">
                <h3>Designate your wrap:</h3>
                <div th:each="ingredient : ${wrap}">
                    <input name="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                    <span th:text="${ingredient.name}">INGREDIENT</span><br/>
                </div>
            </div>
    
            <div class="ingredient-group" id="proteins">
                <h3>Pick your protein:</h3>
                <div th:each="ingredient : ${protein}">
                    <input name="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                    <span th:text="${ingredient.name}">INGREDIENT</span><br/>
                </div>
            </div>
    
            <div class="ingredient-group" id="cheeses">
                <h3>Choose your cheese:</h3>
                <div th:each="ingredient : ${cheese}">
                    <input name="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                    <span th:text="${ingredient.name}">INGREDIENT</span><br/>
                </div>
            </div>
    
            <div class="ingredient-group" id="veggies">
                <h3>Determine your veggies:</h3>
                <div th:each="ingredient : ${veggies}">
                    <input name="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                    <span th:text="${ingredient.name}">INGREDIENT</span><br/>
                </div>
            </div>
    
            <div class="ingredient-group" id="sauces">
                <h3>Select your sauce:</h3>
                <div th:each="ingredient : ${sauce}">
                    <input name="ingredientsString" type="checkbox" th:value="${ingredient}"/>
                    <span th:text="${ingredient.name}">INGREDIENT</span>
                </div>
            </div>
    
            <h3>Name your taco creation:</h3>
            <input type="text" th:field="*{name}"/>
            <br/>
            <button>Submit your taco</button>
        </div>
    </form>
    </body>
    </html>
    
    • DesignController.java
    package com.yuq.taco;
    
    import com.google.gson.Gson;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.validation.Errors;
    import org.springframework.web.bind.annotation.*;
    
    import javax.validation.Valid;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Date;
    import java.util.List;
    import java.util.stream.Collectors;
    
    @Controller
    @RequestMapping("/design")
    @SessionAttributes("order")
    public class DesignTacoController {
    
        private final IngredientRepository ingredientRepo;
        private TacoRepository designRepo;
    
        @Autowired
        public DesignTacoController(IngredientRepository ingredientRepo, TacoRepository designRepo) {
            this.ingredientRepo = ingredientRepo;
            this.designRepo = designRepo;
        }
    
        @ModelAttribute
        public void addIngredientsToModel(Model model) {
            List<Ingredient> ingredients = new ArrayList<>();
            ingredientRepo.findAll().forEach(i -> ingredients.add(i));
            Ingredient.Type[] types = Ingredient.Type.values();
            for (Ingredient.Type type : types) {
                model.addAttribute(type.toString().toLowerCase(), filterByType(ingredients, type));
            }
        }
    
    
        @ModelAttribute(name = "order")
        public Order order() {
            return new Order();
        }
    
        @ModelAttribute(name = "taco")
        public Taco taco() {
            return new Taco();
        }
    
        @GetMapping
        public String showDesignForm(Model model) {
            return "design";
        }
    
    
        @PostMapping
        public String processDesign(@Valid Taco design, Errors errors, @ModelAttribute Order order) {
            if (errors.hasErrors())
                return "design";
            Gson gson = new Gson();
            for (String info : design.getIngredientsString()) {
                Ingredient x=gson.fromJson(info, Ingredient.class);
                design.addIngredients(x);
            }
            design.setCreatedAt(new Date());
            Taco saved = designRepo.save(design);
            order.addDesign(saved);
            return "redirect:/orders/current";
        }
    
        private List<Ingredient> filterByType(List<Ingredient> ingredients, Ingredient.Type type) {
            return ingredients.stream().filter(x -> x.getType().equals(type)).collect(Collectors.toList());
        }
    }
    
    
    • Ingredient.java
    package com.yuq.taco;
    
    import lombok.Data;
    import lombok.RequiredArgsConstructor;
    
    @Data
    @RequiredArgsConstructor
    public class Ingredient {
        private final String id;
        private final String name;
        private final Type type;
    
        public static enum Type {
            WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
        }
    
        @Override
        public String toString() {
            return "{'id':'" + id + "\'" + ", 'name':'" + name + "\'" + ", 'type':'" + type + "\'}";
        }
    }
    
    
    • 添加Gson依赖
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.1</version>
        </dependency>
    
    
    package com.yuq.taco;
    
    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 java.sql.*;
    import java.util.Arrays;
    import java.util.Date;
    
    @Repository
    public class JdbcTacoRepository implements TacoRepository{
    
        private JdbcTemplate jdbc;
    
        @Autowired
        public JdbcTacoRepository(JdbcTemplate jdbc){
            this.jdbc=jdbc;
        }
    
        @Override
        public Taco save(Taco design) {
            long tacoId=saveTacoInfo(design);
            design.setId(tacoId);
            for(Ingredient ingredient:design.getIngredients()){
                saveIngredientToTaco(ingredient,tacoId);
            }
            return design;
        }
    
        private long saveTacoInfo(Taco taco){
    //        PreparedStatementCreator psc = new PreparedStatementCreatorFactory(
    //                "insert into Taco (name,createdAt) values (?,?);",
    //                Types.VARCHAR,Types.TIMESTAMP
    //        ).newPreparedStatementCreator(Arrays.asList(taco.getName(),new Timestamp(taco.getCreatedAt().getTime())));
    //
    //        KeyHolder keyHolder=new GeneratedKeyHolder();
    //        jdbc.update(psc,keyHolder);
    
            String sql = "insert into Taco (name,createdAt) values (?,?);";
            KeyHolder keyHolder = new GeneratedKeyHolder();
            jdbc.update(new PreparedStatementCreator() {
                @Override
                public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
                    // 指定主键
                    PreparedStatement preparedStatement = connection.prepareStatement(sql, new String[]{"id"});
                    preparedStatement.setString(1, taco.getName());
                    preparedStatement.setTimestamp(2, new Timestamp(taco.getCreatedAt().getTime()));
                    return preparedStatement;
                }
            }, keyHolder);
            return keyHolder.getKey().longValue();
        }
    
        private void saveIngredientToTaco(Ingredient ingredient,long tacoId){
            jdbc.update("insert into Taco_Ingredients (taco,ingredient) values(?,?)",tacoId,ingredient.getId());
        }
    
    
    }
    
  • OrderController

    • 没什么问题,主要是表单中的数据名字与数据库中的不一致,改下数据库就可以
    create table if not exists Taco_Order(
        id identity,
        name varchar(50) not null,
        street varchar(50) not null,
        city varchar(50) not null,
        state varchar(2) not null,
        zip varchar(10) not null,
        ccNumber varchar(16) not null,
        ccExpiration varchar(5) not null,
        ccCVV varchar(3) not null,
        placedAt timestamp not null
    );
    

代码链接

百度云链接:https://pan.baidu.com/s/1GPXLeZ1SfJ1qyfQuNlaA_Q 密码:7up3

相关文章

网友评论

      本文标题:Spring实战(第5版)第三章代码问题

      本文链接:https://www.haomeiwen.com/subject/tgyozhtx.html