myBatis中的莫名其妙的java.lang.NullPointerException,求指教
在使用MyBatis时,出现java.lang.NullPointerException
可能由多种原因引起。要解决这个问题,可以从以下几个方面进行排查和调试:
常见原因及解决方法
Mapper接口未正确注入
- 确保Mapper接口正确地被Spring或者MyBatis注入。如果使用Spring,请检查是否正确配置了Mapper扫描。
- 配置示例:
或者使用注解:xml<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath*:mappers/*.xml"/> </bean> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.mapper"/> </bean>
java@MapperScan("com.example.mapper") @SpringBootApplication public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
SQL映射文件未正确加载
- 确保Mapper XML文件路径配置正确,并且与Mapper接口的方法对应。
- 示例:xml
<mapper namespace="com.example.mapper.UserMapper"> <select id="findUserById" parameterType="int" resultType="com.example.model.User"> SELECT * FROM users WHERE id = #{id} </select> </mapper>
Result Map未正确配置
- 如果使用了ResultMap,确保配置正确,并且字段名与数据库中的列名对应。
- 示例:xml
<resultMap id="userResultMap" type="com.example.model.User"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="email" column="email"/> </resultMap> <select id="findUserById" resultMap="userResultMap"> SELECT * FROM users WHERE id = #{id} </select>
Mapper接口方法返回值
- 确保Mapper接口的方法返回值类型正确。
- 示例:java
public interface UserMapper { User findUserById(int id); }
传递给Mapper方法的参数
- 确保传递给Mapper方法的参数不为null,且参数类型正确。
- 示例:java
int userId = 1; // 确保userId不为null User user = userMapper.findUserById(userId);
调试步骤
检查Mapper接口和实现
- 确保Mapper接口被正确扫描并注入到Spring上下文中。可以通过日志或者调试检查Mapper接口是否为null。
- 示例:java
@Autowired private UserMapper userMapper; public void someMethod() { if (userMapper == null) { System.out.println("UserMapper is null"); } }
检查SQL映射文件路径
- 确保SQL映射文件的路径正确,并且被加载。可以通过日志或者调试检查SQL映射文件是否被正确加载。
- 示例:java
SqlSessionFactory sqlSessionFactory = ... Configuration configuration = sqlSessionFactory.getConfiguration(); Collection<String> mappedStatements = configuration.getMappedStatementNames(); mappedStatements.forEach(System.out::println); // 输出所有被加载的SQL映射
启用MyBatis日志
- 启用MyBatis的日志输出,检查SQL执行情况,是否有SQL执行失败或者结果为空的情况。
- 配置示例:xml
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
示例代码
以下是一个完整的示例,包括Spring Boot应用中的MyBatis配置、Mapper接口、SQL映射文件和测试代码。
Spring Boot配置
java@SpringBootApplication
@MapperScan("com.example.mapper")
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
数据源配置(application.properties)
propertiesspring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=password spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver mybatis.mapper-locations=classpath*:mappers/*.xml
Mapper接口
javapackage com.example.mapper;
import com.example.model.User;
import org.apache.ibatis.annotations.Select;
public interface UserMapper {
@Select("SELECT * FROM users WHERE id = #{id}")
User findUserById(int id);
}
SQL映射文件(resources/mappers/UserMapper.xml)
xml<?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.example.mapper.UserMapper">
<select id="findUserById" resultType="com.example.model.User">
SELECT * FROM users WHERE id = #{id}
</select>
</mapper>
测试代码
javapackage com.example;
import com.example.mapper.UserMapper;
import com.example.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class MyRunner implements CommandLineRunner {
@Autowired
private UserMapper userMapper;
@Override
public void run(String... args) throws Exception {
User user = userMapper.findUserById(1);
if (user != null) {
System.out.println(user.getName());
} else {
System.out.println("User not found");
}
}
}
通过以上步骤,可以有效地排查和解决MyBatis中出现的java.lang.NullPointerException
问题。