今天开始接触Mybatis,在学习第一步时就遇到了一个空指针的错误,所以记录一下,免得以后再犯:
具体错误如下
Exception in thread "main" 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 com.mybatis.test.UserDao.init(UserDao.java:32)
at com.mybatis.test.UserDao.main(UserDao.java:41)
Caused by: java.lang.NullPointerException
at org.apache.ibatis.session.defaults.DefaultSqlSessionFactory.openSessionFromDataSource(DefaultSqlSessionFactory.java:95)
... 3 more
具体的代码
public class UserDao {
private SqlSession session;
public void select(int id){
User user = session.selectOne("findById", id);
System.out.println(user);
}
public void init(){
String resource = "com/mybatis/map/mybatisConfig.xml";
try {
Reader reader = Resources.getResourceAsReader(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
session = sqlSessionFactory.openSession(); <----错误定位代码
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
UserDao userDao = new UserDao();
userDao.init();
userDao.select(1);
}
}
mybatis配置文件如下
<?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>
<environments default="development">
<environment id="database1">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mybatis_test1"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="database2">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mybatis_test2"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="database3">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mybatis_test3"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/mybatis/map/User.xml"/>
</mappers>
</configuration>
通过调试发现,SqlSessionFactory不为 null,但是在
session = sqlSessionFactory.openSession();
时报了错误
后来查看mybatis文档才了解到,在mybatis配置时,可能由于我们开发时的数据库环境和最终上线时的数据库环境不同,因此可以在配置文件中配置多个数据库环境;
即在 < enviroments >标签下可以配置多个< enviroment>标签,每一个< enviroment >标签对应一个数据库环境
而不同的数据库环境通过< enviroment > 标签的 id 属性用以区分
那么具体开发时如果知道使用的是哪一个环境呢?
在< envirments> 标签里有一个default属性,该属性对应的是下面的不同的< enviroment > 的id属性
default的值为哪一个id,则代表此时使用的是哪一个environment数据库环境
由于一开始我照着教程写的代码,直接填的default=”development”,我以为该值是一个mybatis框架下的一个默认值,< environments default=”development”>,因此它在获取environment时,在我的配置中未查找到id为 development的enviroment (database1,databse2,database3),在openSession时会导致获取为空
因此解决办法
< environment default=”“> 该值为下面配置的< environment id=”“>中需要使用的环境的id即可
即
<?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>
<environments default="database1"> <!-- default属性选择此次开发时需要的数据库环境的id值即可 (database1、database2、database3) -->
<environment id="database1">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mybatis_test1"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="database2">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mybatis_test2"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="database3">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost/mybatis_test3"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/mybatis/map/User.xml"/>
</mappers>
</configuration>
最终问题解决