删除班级时产生谬误
新增班级后删除班级时产生报错,然而单元测试时没有报错,可失常通过。
报错信息为
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null!] with root cause
其中比拟要害的一句为 The given id must not be null!
。
再到网页控制台中查看报错信息为500,确认时后盾产生的谬误。
之后再到C层用logger.info()打印之后发现从前台传过来的id却是为null,之后再查看了一下单元测试中的内容
@Test public void delete() { Teacher teacher = new Teacher(); Klass klass = new Klass(); klass.setName("测试123123班级"); klassRepository.save(klass); klassService.delete(klass.getId()); Optional<Klass> klassOptional = klassRepository.findById(klass.getId()); Assertions.assertThat(klassOptional.isPresent()).isFalse(); }
发现单元测试时的班级ID是间接调用klass.getId()取得的id,再回到C层查看发现在delete
办法中的参数没有增加@PathVariable
注解。单元测试并没有检测到前台数据是否传到了后盾。
这也就是说在写完后盾后要优先测试前台数据是否传送到后盾。
删除与班级绑定的老师时产生谬误
老师与班级绑定时理当不容许被删除,然而删除时前台应该做相应提醒或是连带与之绑定的班级一并删除(或者是解除绑定,即把teacher_id设为空),而不是报500谬误。
报错信息为:
Cannot delete or update a parent row: a foreign key constraint fails
在此,先尝试第二种解决办法
呈现这个报错的起因是:想要删除的数据或表与其余数据或表领有主外键关系,Mysql规定,为了保护表构造的稳固,禁止执行该操作,即外键束缚失败。
如果咱们想强制删除能够执行以下语句:
String sql = String.format("delete from `teacher` where id = %s", id);this.jdbcTemplate.update("SET foreign_key_checks = 0");this.jdbcTemplate.update(sql);this.jdbcTemplate.update("SET foreign_key_checks = 1");
进行操作后能够删除老师,然而相应班级没有被删除,在查看班级时也会产生报错。
咱们能够执行以下语句来操作该老师所属的班级
Teacher teacher = new Teacher();teacher = this.teacherService.getById(id);RowCallbackHandler rowCallbackHandler = new RowCallbackHandler() { @Override public void processRow(ResultSet resultSet) throws SQLException { Klass klass = new Klass(); klass.setTeacher(null); klass.setName(resultSet.getString("name")); klass.setId(resultSet.getLong("id")); klassService.update(klass.getId(), klass); }};String newSql = String.format("select id, name, teacher_id from klass where teacher_id = %d", teacher.getId());jdbcTemplate.query(newSql, rowCallbackHandler);
此时咱们再进行删除老师就会将其所属班级的老师设为空,实现老师的失常删除。
除此之外咱们还能够当咱们要删除老师时如果该老师有所属班级,咱们间接给出提醒——该老师已绑定班级,无奈进行删除来解决问题。
咱们能够在前台先查问后盾中是否存在班级与要删除的老师绑定,若存在则提醒——删除失败,存在班级与该老师绑定。
前台代码
onDelete(teacher: Teacher): void { const index = this.teachers.indexOf(teacher); this.httpClient.get(`${this.url}haveKlass/${teacher.id}`) .subscribe((flag) => { console.log(flag); if (flag) { console.log('删除失败,存在班级与该老师绑定'); } else { this.httpClient.delete(`${this.url}/${teacher.id}`) .subscribe(() => { this.teachers.splice(index, 1); console.log('delete success'); }, error => console.log('delete error', error)); } }); }
后盾haveKlass接口对应代码:
public Boolean haveKlass(Long id) { final Boolean[] flag = new Boolean[1]; flag[0] = false; RowCallbackHandler rowCallbackHandler = new RowCallbackHandler() { @Override public void processRow(ResultSet resultSet) throws SQLException { flag[0] = true; } }; String newSql = String.format("select id, name, teacher_id from klass where teacher_id = %d", id); jdbcTemplate.query(newSql,rowCallbackHandler); return flag[0]; }
JAVA中 String/Boolean...与string/boolean的区别
以boolean为例
boolean 是java中最根本8种类型中的一种,java为8中根本类型提供了封装类,用来示意一个对象。
不过在有些框架中,例如参数和值要求是对象类型,所以不能用根本类型。
boolean是根本数据类型Boolean是它的封装类,和其余类一样,有属性有办法,能够new,例如:Boolean flag = new Boolean("true"); // boolean 则不能够!