在进行Java开发时,NullPointerException是一个很常见的异常,在Java8中提供了Optional来避免此问题,而在MyBatis 3.5.0中也提供了对Optional的支持,本文简要叙述如何在MyBatis中使用Optional

完整代码参见spring-mybatis-example

查询单条记录

由于在查询单条记录时,若数据库中不存在该记录,则会默认返回null,此时可用Optional进行避免。

首先确保MyBatis的版本不低于3.5.0,在mapper中可以仿照如下定义接口

1
2
3
4
public interface BookMapper {

    Optional<BookModel> findById(Integer id);
}

之后在对应的service类中可以按照如下方式使用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
@Service
public class BookService {

    @Autowired
    private BookMapper bookMapper;

    public BookModel getBook(Integer id) {
        Optional<BookModel> result = bookMapper.findById(id);
        BookModel book = result.orElse(new BookModel());
        return book;
    }
}

执行下述单元测试代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@SpringBootTest
public class TestBookService {

    @Autowired
    private BookService bookService;

    @Test
    public void testGetBook() {
        BookModel book = bookService.getBook(3);
        Assertions.assertNotNull(book);
        System.out.println(book);
    }
}

其执行结果如下,可见Optional在Mapper接口中生效。

Optional执行结果

查询多条记录

当查询的结果为List时,即使没有数据MyBatis也会返回一个空的List,其size为0但不为null,此时不需要我们进行非空判断。

定义如下接口

1
2
3
4
public interface BookMapper {
    
    List<BookModel> selectByType(Integer type);
}

mapper文件如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lucumt.mapper.BookMapper">

    <select id="findById" parameterType="Integer" resultType="bookModel">
        SELECT id,name,price,type FROM book WHERE id=#{id}
    </select>

    <select id="selectByType" parameterType="integer" resultType="bookModel">
        SELECT id,name,price FROM book WHERE type=#{type}
    </select>

</mapper>

业务类代码

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
@Service
public class BookService {

    @Autowired
    private BookMapper bookMapper;

    public List<BookModel> selectByType(Integer type){
        List<BookModel> bookList = bookMapper.selectByType(type);
        return bookList;
    }
}

执行下述单元测试代码时能测试通过,可见在查询集合列表是不需要判断是否为空。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
@SpringBootTest
public class TestBookService {

    @Autowired
    private BookService bookService;

    @Test
    public void testSelectByType() {
        List<BookModel> bookList = bookService.selectByType(3);
        Assertions.assertTrue(bookList != null);
        Assertions.assertTrue(bookList.size() == 0);
    }
}

List执行结果

从上述试验可知,当获取的结果为List时,不使用Optinal关键字也能避免空指针问题。