SpringBoot+Thymeleaf插入MSSQL遇非空字段NULL插入失败求助
问题分析与修复方案
核心错误原因
你遇到的插入报错,本质是插入操作使用了空的InsertModel对象:在InsertRepository的insertOp方法里,你新建了一个未赋值的InsertModel实例,导致所有属性值为null(int类型的access默认值为0,但数据库字段约束不允许null),触发了MSSQL的非空字段校验。
具体修复步骤
1. 修正InsertRepository,使用传入的业务对象
不要在方法内部新建空对象,改为接收外部传入的、带用户输入数据的InsertModel,同时规范数据库连接的获取方式:
@Component public class InsertRepository { private final DataSource dataSource; // 通过构造注入获取DataSource,符合Spring规范 @Autowired public InsertRepository(DataSource dataSource) { this.dataSource = dataSource; } public void insertOp(InsertModel insertModel){ // 直接使用传入的参数对象,而非新建空对象 try (Connection con = dataSource.getConnection(); PreparedStatement pst = con.prepareStatement( "INSERT INTO dbo.contacts (FullName, PhoneNumber, ownerId, auth) VALUES (?, ?, ?, ?)" )) { pst.setString(1, insertModel.getFirstName()); pst.setString(2, insertModel.getPhoneNumber()); pst.setInt(3, LoginModel.getUserId()); pst.setInt(4, insertModel.getAccess()); pst.executeUpdate(); } catch (SQLException ex) { throw new RuntimeException(ex); } } }
注意:
- 不要直接继承
DataSource,通过依赖注入获取连接更安全,同时用try-with-resources自动关闭数据库资源,避免泄漏。- 移除SQL中的
Use PhoneBook,建议在application.properties中配置默认数据库。
2. 修正Controller,传递用户提交的数据
不要手动新建InsertRepository实例,通过Spring依赖注入获取Bean,并将表单提交的InsertModel传递给insertOp方法:
@Controller public class YourController { private final InsertRepository insertRepository; @Autowired public YourController(InsertRepository insertRepository) { this.insertRepository = insertRepository; } @RequestMapping(value = "/home") public String showContacts(Model model) throws SQLException { // --------some stuff------------- model.addAttribute("insertData", new InsertModel()); // 初始化空对象用于表单绑定 return "main/Main"; } @PostMapping("/insert") public String insertData(@ModelAttribute("insertData") InsertModel insertModel){ // 将表单提交的对象传入Repository执行插入 insertRepository.insertOp(insertModel); return "redirect:/home"; } }
注意:确保控制器类上标记了
@Controller注解,让Spring能扫描并管理该Bean。
3. 验证数据库字段映射一致性
确认SQL字段与InsertModel属性、数据库表结构的对应关系:
- SQL中的
FullName对应insertModel.firstName,确保数据库FullName字段为非空约束,且表单的required属性正常生效。 - SQL中的
auth对应insertModel.access,确保数据库auth字段为int类型,且允许值与表单选项(1/2)匹配。
额外优化建议
- 在
application.properties中配置数据库连接信息,避免硬编码:
spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=PhoneBook;encrypt=true;trustServerCertificate=true spring.datasource.username=你的用户名 spring.datasource.password=你的密码 spring.datasource.driver-class-name=com.microsoft.sqlserver.jdbc.SQLServerDriver
- 可以使用Spring
JdbcTemplate简化数据库操作,减少手动管理连接和语句的代码。
内容的提问来源于stack exchange,提问作者user19577108
相关产品推荐
相关产品推荐

