前两天在学spring boot的时候,出现了一个很奇怪的错误,因为是第一次使用spring boot,所以没想到会遇到这种莫名其妙的bug,即调用接口删除数据库中一条记录的时候,数据库中记录事实上以及被删除了,但是却返回一个null,这就令我百思不得其解了,理论上,删除的话,会返回受影响的记录的条数。
最后排查了一圈,结果却十分令我大跌眼镜,真的很简单!下面写的代码:
- controller类,这里由于后来数据库sql改了,为了测试like的搜索功能,所以前面的index方法参数并未进行及时修改,由于本文不涉及该方法,所以请忽略!
package site.wangxin520.springboot.web; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.http.HttpServletRequest; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import site.wangxin520.springboot.service.IndexService; @RequestMapping("/") @RestController public class Index { @Autowired private IndexService indexService; /** * resful的风格,从path里面获取到id,读取数据库展示数据 * @param request * @param id * @return */ @RequestMapping("/{id}") public String index(HttpServletRequest request,@PathVariable("id") String id){ Map<String, String[]> parameterMap = request.getParameterMap(); Set<Entry<String, String[]>> entrySet = parameterMap.entrySet(); for (Entry<String, String[]> entry : entrySet) { System.out.println(entry.getKey()+" : "+entry.getValue()); } String name = indexService.getName(id); return name; } /** * 通过id,去删除数据 * @param request * @param id * @return */ @RequestMapping(value="/",method={RequestMethod.DELETE}) public String deleteById(HttpServletRequest request,Integer id){ int deleteById = indexService.deleteById(id); return deleteById+""; } }
- service接口
package site.wangxin520.springboot.service; public interface IndexService { /** * 通过id,获取名字 * @param id * @return */ public String getName(String id); /** * 通过id,删除元素 * @param id * @return */ public int deleteById(Integer id); }
- service实现类
package site.wangxin520.springboot.service.impl; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import site.wangxin520.springboot.dao.IndexMapper; import site.wangxin520.springboot.service.IndexService; @Service public class IndexServiceImpl implements IndexService{ @Autowired private IndexMapper mapper; @Override public String getName(String id) { return mapper.getName(id+"%"); } @Override public int deleteById(Integer id) { return mapper.deleteById(id); } }
- dao层接口,在dao层,使用的是注解的方式进行mapper的自动实现。
package site.wangxin520.springboot.dao; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; @Mapper public interface IndexMapper { // @Select("SELECT username FROM `user` WHERE id=#{id};") @Select("SELECT username from user where username LIKE #{id};") public String getName(String id); @Select("DELETE FROM `user` where id =#{id};") public Integer deleteById(int id); }
- 源数据库记录
- 启动项目,使用httprequest调用controller调用网络接口
结果却令我大跌眼镜,竟然报服务器异常,并且空指针了
- 查看数据库
没想到数据库竟然成功的删除了id为3的这条记录。
- 查看控制台
在控制台上打印出了空指针,根据错误信息,定位到了site.wangxin520.springboot.dao.IndexMapper.deleteById(int)这个方法,因为返回的是null。
这时候我就有疑惑了,理论上删除返回的并不是null啊,而是影响的行数,这次这是什么情况。后来我自习的查看了一下,发现了错误的信息原来真的是很狗血的!
@Select("DELETE FROM `user` where id =#{id};")
顿时我就无语了,把这个dao接口重新修改以后,再次运行。
- dao接口
package site.wangxin520.springboot.dao; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Select; @Mapper public interface IndexMapper { // @Select("SELECT username FROM `user` WHERE id=#{id};") @Select("SELECT username from user where username LIKE #{id};") public String getName(String id); // @Select("DELETE FROM `user` where id =#{id};") @Delete("DELETE FROM `user` where id =#{id};") public Integer deleteById(int id); }
- 启动项目,使用httprequest调用接口
- 查看数据库
id为2的记录成功删除,并且返回一个1,即所影响的记录数!
一切正常,这个小错误真的可以说是人为的,以后得多注意!