spring boot继承web和mybatis时,调用接口删除记录出现的空指针以及解决办法

Posted 博客王大锤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot继承web和mybatis时,调用接口删除记录出现的空指针以及解决办法相关的知识,希望对你有一定的参考价值。

前两天在学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()+"\\t:\\t"+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);
}
  • 源数据库记录

image

  • 启动项目,使用httprequest调用controller调用网络接口

image

结果却令我大跌眼镜,竟然报服务器异常,并且空指针了

  • 查看数据库

image

没想到数据库竟然成功的删除了id为3的这条记录。

  • 查看控制台

image在控制台上打印出了空指针,根据错误信息,定位到了site.wangxin520.springboot.dao.IndexMapper.deleteById(int)这个方法,因为返回的是null。

这时候我就有疑惑了,理论上删除返回的并不是null啊,而是影响的行数,这次这是什么情况。后来我自习的查看了一下,发现了错误的信息原来真的是很狗血的!

@Select("DELETE FROM `user` where id =#{id};")
错误就错在这个注解上,删除应该是使用注解@Delete,而不是Select。

顿时我就无语了,把这个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调用接口

image

  • 查看数据库

image

id为2的记录成功删除,并且返回一个1,即所影响的记录数!

一切正常,这个小错误真的可以说是人为的,以后得多注意!

以上是关于spring boot继承web和mybatis时,调用接口删除记录出现的空指针以及解决办法的主要内容,如果未能解决你的问题,请参考以下文章

Spring Boot启动时出现WARN:No MyBatis mapper was found in

使用Spring Boot+MyBatis框架做查询操作

[web] spring boot 整合MyBatis

Spring Boot-整合MyBatis

Spring Cloud Spring Boot mybatis分布式微服务云架构 开发Web应用

如何在不从 spring-boot-starter-web 继承的情况下在 Spring Boot 中获取 ObjectMapper 实例?