Spring Boot+Thymeleaf应用表单无法保存至MySQL数据库求助
Spring Boot + Thymeleaf CRUD表单无法保存数据到MySQL问题排查
我用Spring Boot和Thymeleaf搭建了一个简易CRUD应用,但提交表单时数据无法保存到MySQL数据库,相关代码如下:
Controller代码
@Controller public class ClientController { private static final Logger LOG = LoggerFactory.getLogger(ClientController.class); @Autowired private ClientRepository clientRepository; @GetMapping("/patients") public String getAllClients(Model model) { List<Client> clients = clientRepository.findAll(); model.addAttribute("clients", clients); return "patient/list-patients"; } @GetMapping("/add-patient") public String addClient(Model model) { model.addAttribute("client", new Client()); return "patient/add-patient"; } @PostMapping("/add-patient") public String addClient(@Valid @ModelAttribute Client client, BindingResult bindingResult) { LOG.info("Saving client: {}", client); if (bindingResult.hasErrors()) { return "patient/add-patient"; } clientRepository.save(client); return "redirect:/add-patient"; } @GetMapping("/edit/{id}") public String editClient(@PathVariable("id") Long id, Model model) { model.addAttribute("client", clientRepository.findById(id).orElse(null)); return "patient-edit"; } @GetMapping("/delete/{id}") public String deleteClient(@PathVariable("id") Long id) { clientRepository.deleteById(id); return "redirect:/patients"; } }
Model代码
@Entity @Data public class Client { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String patientId; @Size(min=2, max=30) private String firstName; @Size(min=2, max=30) private String lastName; private String otherName; private String gender; private String email; private Date dateOfBirth; private String ageGroup; private String phoneNumber; private String address; // Identity private String cardType; private String cardNumber; private String iDCardNumber; //getters and setters }
表单代码
<div> <form action="#" th:action="@{/add-patient}" method="post"> <p> <label for="firstName">First Name:</label> <input type="text" id="firstName" name="firstName" /> </p> <p> <label for="lastName">Last Name:</label> <input type="text" id="lastName" name="lastName" /> </p> <p> <label for="otherName">Other Name(s):</label> <input type="text" id="otherName" name="otherName" /> </p> <p> <label for="dateOfBirth">Date of Birth:</label> <input type="date" id="dateOfBirth" name="dateOfBirth" /> </p> <p> <label for="address">Address:</label> <input type="text" id="address" name="address" /> </p> <p> <label for="email">Email:</label> <input type="email" id="email" name="email" /> </p> <p> <label for="phoneNumber">Phone Number:</label> <input type="tel" id="phoneNumber" name="phoneNumber" /> </p> <p> <label for="gender">Gender:</label> <select id="gender" name="gender"> <option value="Male">Male</option> <option value="Female">Female</option> <option value="Other">Other</option> </select> </p> <p> <label for="ageGroup">Age Group:</label> <select id="ageGroup" name="ageGroup"> <option value="Under 18">Under 18</option> <option value="18-25">18 - 25</option> <option value="26-35">26 - 35</option> <option value="36-45">36 - 45</option> <option value="46-55">46 - 55</option> <option value="Over 55">Over 55</option> </select> </p> <p> <label for="cardType">Card Type:</label> <select id="cardType" name="cardType"> <option value="passport">Passport</option> <option value="Ghana Card">Ghana Card</option> </select> </p> <p> <label for="cardNumber">Card Number:</label> <input type="text" id="cardNumber" name="cardNumber" /> </p> <input type="submit" value="Save" /> </form> </div>
排查与解决步骤
校验错误排查
- 当前Controller仅判断BindingResult有错误就返回表单,但未打印具体错误信息。在
if (bindingResult.hasErrors())块中添加日志打印,查看是否是校验规则触发导致未执行保存:bindingResult.getAllErrors().forEach(error -> LOG.error("校验失败: {}", error.getDefaultMessage())); - 注意
firstName和lastName有@Size(min=2)校验,若输入字符数不足2位,会直接触发校验失败,中断保存流程。
- 当前Controller仅判断BindingResult有错误就返回表单,但未打印具体错误信息。在
日期类型绑定修复
- Model中
dateOfBirth使用java.util.Date,与表单的type="date"返回的日期格式存在绑定兼容性问题。建议替换为java.time.LocalDate并添加格式化注解:@DateTimeFormat(pattern = "yyyy-MM-dd") private LocalDate dateOfBirth;
- Model中
Repository层确认
- 确保
ClientRepository正确继承JpaRepository<Client, Long>,否则save()方法无法生效:public interface ClientRepository extends JpaRepository<Client, Long> { }
- 确保
数据库配置与日志验证
- 检查
application.properties/application.yml中的MySQL配置是否正确,开启SQL日志查看是否有插入语句执行:spring.datasource.url=jdbc:mysql://localhost:3306/你的数据库名?useSSL=false&serverTimezone=UTC spring.datasource.username=数据库用户名 spring.datasource.password=数据库密码 spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true - 若
show-sql未输出INSERT语句,说明代码未走到clientRepository.save()步骤。
- 检查
表单字段完整性检查
- Model中
patientId和iDCardNumber字段在表单中没有对应输入项,若数据库中这两个字段被设置为NOT NULL,会导致插入失败。可通过以下方式处理:- 在数据库中将这两个字段设置为允许为空;
- 在表单中添加对应输入框;
- 在Model字段上添加
@Nullable注解(需引入Spring相关依赖)。
- Model中
重定向路径优化
- 当前保存成功后重定向到
/add-patient,无法直观看到保存结果。建议改为重定向到列表页/patients:return "redirect:/patients";
- 当前保存成功后重定向到
视图路径修正
editClient方法返回的视图名是patient-edit,与其他视图的路径格式(patient/xxx)不一致,需确认视图文件实际路径是否为patient/patient-edit.html,若不是则修正返回值:return "patient/patient-edit";
内容的提问来源于stack exchange,提问作者J Maine
相关产品推荐
相关产品推荐

