问题描述
org.apache.ibatis.exceptions.PersistenceException:
### Error opening session. Cause: java.lang.NullPointerException
### Cause: java.lang.NullPointerException
文件目录
- src
- bean
- Student.java
- controll
- StudentControll.java
- mappen
- StudentMapper.interface
- Mapper.xml
- util
- MybatisUtil.java
- bean
- MybatisCore.xml
- log4j.properties
- sql.properties
Mybatis配置文件 MybatisCore.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="sql.properties"/>
<!-- 引入日志插件-->
<settings>
<setting name="logImpl" value="log4j"/>
</settings>
<typeAliases>
<package name="bean"/>
</typeAliases>
<environments default="mysql">
<environment id="myql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- <mappers>-->
<!-- <package name="mapper.Mapper.xml"/>-->
<!-- </mappers>-->
<mappers>
<mapper resource="mapper/Mapper.xml"/>
</mappers>
</configuration>
调试日志配置文件 log4j.properties
#log4j.appender.fileAppender.layout.ConversionPattern=%d %5p %c{1}:%L - %m%n
# Global logging configuration
# ERROR WARN INFO DEBUG
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
sql(我用的是mysql) 配置文件 sql.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db_327
username=root
password=123456
MyBatis工具类 MybatisUtil.java
/**
* User: Tong
* Date: 2021/3/27
* Time: 20:06
* Project:Mybatis
* Type:
* Fucntion:
* To change this template use File | Settings | File Templates.
**/
package util;
import mapper.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.util.List;
public class MyBatisUtil {
private static SqlSessionFactory build ;
private static SqlSession sqlSession;
// 静态代码块进行mybatis配置文件的读取并且获取出来sqlsession
static {
InputStream rs = null;
try {
rs = Resources.getResourceAsStream("MybatisCore.xml");
build = new SqlSessionFactoryBuilder().build(rs);
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
if (rs!=null) rs.close();
} catch (IOException e) {
e.printStackTrace();
}
}//end finally
}
// 未使用代理的获取对象
public static Object getMapper(Class clazz){
sqlSession =build.openSession();
Object mapper = sqlSession.getMapper(clazz);
return mapper;
}
public static void commit(){
sqlSession.commit();
}
public static void rollback(){
sqlSession.rollback();
}
}
MyBatis的mapper文件 Mapper.xml
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="mapper.StudentMapper">
<resultMap id="stu" type="student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="sage" property="age"/>
<result column="sgender" property="gender"/>
</resultMap>
<!-- 查询所有的学生信息-->
<select id="selectAll" resultMap="stu">
SELECT *
FROM STUDENT
</select>
<!-- 按条件查询学生信息-->
<select id="selectStudent" resultMap="stu">
SELECT * FROM STUDENT
<where>
<if test="id !=null">
AND sid = #{id}
</if>
<if test="name !=null">
AND sname = #{name}
</if>
<if test="age !=null">
AND sage=${age}
</if>
<if test="gender !=null">
AND sGender=${gender}
</if>
</where>
</select>
<!-- 插入数据-->
<insert id="insertStudent" parameterType="List">
INSERT INTO STUDENT value
<foreach collection="list" separator="," item="student">
(#{student.id},#{student.name},#{student.age},#{student.gender})
</foreach>
</insert>
<!-- 按条件删除数据-->
<delete id="deleteStudent" parameterType="student">
DELETE FROM student
<where>
<if test="id!=null">
and sid = #{id}
</if>
<if test="name!=null">
and sname = #{name}
</if>
<if test="age!=null">
and sage = #{age}
</if>
<if test="gender!=null">
and sgender = #{gender}
</if>
</where>
</delete>
<!--修改数据内容-->
<update id="updateStudent" parameterType="student">
UPDATE
STUDENT
SET
<if test="id !=null">
sid = #{id} ,
</if>
<if test="name !=null">
sname = #{name},
</if>
<if test="age !=null">
sage=${age},
</if>
<if test="gender !=null">
sGender=${gender}
</if>
WHERE sid = #{id}
</update>
</mapper>
DAO接口对象 StudentMapper.interface
/**
* User: Tong
* Date: 2021/3/27
* Time: 19:08
* Project:Mybatis
* Type:
* Fucntion:
* To change this template use File | Settings | File Templates.
**/
package mapper;
import bean.Student;
import java.util.ArrayList;
import java.util.List;
public interface StudentMapper {
//查询学生的所有的数据
public List<Student> selectAll();
//按条件查询学生的数据
public List<Student> selectStudent(Student student);
//添加学生
//TODO 可以尝试添加Student...
public boolean insertStudent(ArrayList<Student> students);
//删除学生
public int deleteStudent(Student student);
//修改学生的数据
public boolean updateStudent(Student student);
}
Controll 层 StudentControll.java
/**
* User: Tong
* Date: 2021/3/27
* Time: 20:05
* Project:Mybatis
* Type:
* Fucntion:
* To change this template use File | Settings | File Templates.
**/
package cotroller;
import bean.Student;
import mapper.StudentMapper;
import org.junit.Test;
import util.MyBatisUtil;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.List;
public class StudnetCotroll {
//按照条件查询学生的信息
@Test
public void selectStudentOne() {
StudentMapper mapper = (StudentMapper) MyBatisUtil.getMapper(StudentMapper.class);
Student student = new Student(6, null, null, null);
List<Student> students = mapper.selectStudent(student);
students.forEach(o -> System.out.println(o));
}
// 查询所有的学生信息
@Test
public void selectAll() {
StudentMapper mapper = (StudentMapper) MyBatisUtil.getMapper(StudentMapper.class);
List<Student> students = mapper.selectAll();
students.forEach(o -> System.out.println(o));
}
@Test
//插入学生数据
public void insertStudent() {
ArrayList<Student> students = new ArrayList<>();
Student student = new Student(null, "迪迦奥特曼", 35, "男");
StudentMapper mapper = null;
try {
mapper = (StudentMapper) MyBatisUtil.getMapper(StudentMapper.class);
students.add(student);
boolean b = mapper.insertStudent(students);
if (b) System.out.println("insert successful");
else System.out.println("insert failed");
MyBatisUtil.commit();
} catch (Exception e) {
MyBatisUtil.rollback();
}
}
@Test
//按条件删除学生
public void deleteStudent() {
try {
StudentMapper mapper = (StudentMapper) MyBatisUtil.getMapper(StudentMapper.class);
Student student = new Student(11, null, null, null);
int i = mapper.deleteStudent(student);
if (i >= 0) {
MyBatisUtil.commit();
System.out.println("Delete student successful");
} else System.out.println("Delete student falide");
} catch (Exception e) {
MyBatisUtil.rollback();
}
}
@Test
//按照学号修改学生信息
public void updateStudent(){
try {
StudentMapper mapper = (StudentMapper) MyBatisUtil.getMapper(StudentMapper.class);
Student student = new Student(9,"Mr.Zhang",null,null);
boolean b = mapper.updateStudent(student);
if (b) {
System.out.println("Update successful");
MyBatisUtil.commit();
}else System.out.println("Update failed");
} catch (Exception e) {
System.out.println("Update failed:::Exception");
MyBatisUtil.rollback();
}
}
}
调试运行
org.apache.ibatis.exceptions.PersistenceException:
### Error opening session. Cause: java.lang.NullPointerException
### Cause: java.lang.NullPointerException
at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:100)
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSession(DefaultSqlSessionFactory.java:47)
at util.MyBatisUtil.getMapper(MyBatisUtil.java:46)
at cotroller.StudnetCotroll.selectAll(StudnetCotroll.java:35)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:220)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:53)
Caused by: java.lang.NullPointerException
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:95)
... 25 more
问题分析
就是这样的一直报空指针异常
### Cause: java.lang.NullPointerException
通过下面的报错信息可以查看到出错的位置
at util.MyBatisUtil.getMapper(MyBatisUtil.java:46)
对应的代码为
private static SqlSessionFactory build ;\\这个是用字段配置的
sqlSession =build.openSession();//出错行!!!!!
空指针模型那么应该是build是空的没有获取到 于是往上查 上面的话就只能是这两句出错了
rs = Resources.getResourceAsStream("MybatisCore.xml");
build = new SqlSessionFactoryBuilder().build(rs);
空指针的话不太可能第二句出错 那么就只能是第一句出了问题 检查语法没什么问题 就只能是MybatisCore.xml出错了 也就是配置出现了问题
经过很长时间的排查找到了问题所在
<environments default="mysql">
<environment id="myql">
<!--default 与 id 名字要相同-->
总结
opensession出问题大概率是配置文件出问题 往往还都是非常小的问题。。。