我在Spring+MyBatis项目中想做一个独立的类,手动获取到数据库连接,用于操作数据库,单例的,不想每次使用都创建连接,而是一个不关闭的长连接。但是现在问题来了,单例实现了。SqlSession 也一直都在,Debug下SqlSession的Id也没有变化。应该是达到要求了,但是通过SqlSession.OpenConnection()获得到的数据库连接,在第一次调用的时候还有,第二次就抛异常了。显示此连接为空。我跟过MyBatis的源码,每次执行结束会Close掉SqlSession,但是我这个单例应该是不受MyBatis影响的,只是借用了它的sessionFactory。百思不得其解。跪求大神解惑呀,上代码:class DataBaseHelper {
// Spring配置文件路径,相对于classpath
final String Spring_conf_path = "applicationContext.xml";
// jdbc配置文件路径,相对于classpath
final String jdbc_conf_path = "fiad.properties";
// SessionFactory在Spring中的配置ID
final String factory_id = "sqlSessionFactory";
        //私有,单例避免重复创建
private SqlSession session;
private Connection connection;
        //单例实现
private static class DataBaseHolder {
private static final DataBaseHelper INSTANCE = new DataBaseHelper();
} public static final DataBaseHelper getInstance() {
return DataBaseHolder.INSTANCE;
} private DataBaseHelper() {
initConnection();
} private void initConnection() {
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(new ClassPathResource(Spring_conf_path));
PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
cfg.setLocation(new ClassPathResource(jdbc_conf_path));
cfg.postProcessBeanFactory(factory);
SqlSessionFactory sessionFactory = (SqlSessionFactory) factory
.getBean(factory_id);
session = sessionFactory.openSession(true);
connection = session.getConnection();
}
       
      /**
 * 插入系统日志
 * 
 * @param log
 * @return
 * @throws Exception
 */
int insertLogs(LogBean log) throws Exception {
int i = 0;
PreparedStatement st = null;
try {
//此处第1次调用毫无问题,但当第二次调用的时候,就抛空指针异常了。
st = connection.prepareStatement(log.getInsert());
// dataContent,createTime,userID,moduleID,featureID
st.setString(1, log.getDataContent());
st.setTimestamp(2, log.getCreateTime());
st.setInt(3, log.getUserID());
st.setInt(4, log.getModuleID());
st.setInt(5, log.getFeatureID());
i = st.executeUpdate();
} catch (Exception ex) {
throw ex;
} finally {
if (st != null)
st.close();
}
return i;
}
}

解决方案 »

  1.   

    目前实现了我的目标,可以单例生成数据库连接了,但是不是用SqlSession 获得的,是根据配置文件重组的JDBC,因为是单例,所以没用连接池,只是一个单连接。代码如下,希望大神能解答一下问题,暂不关贴。
    BasicDataSource dataSource = (BasicDataSource) factory
    .getBean(dataSourceId);
    String dbUsername=dataSource.getUsername();
    String dbDriver = dataSource.getDriverClassName();
    String dbPassword = dataSource.getPassword();
    String dbUrl = dataSource.getUrl();
            try {
         Class.forName(dbDriver);
    connection = DriverManager.getConnection(dbUrl,dbUsername,dbPassword);
    } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    } catch (ClassNotFoundException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
    }
      

  2.   

    SqlSession是方法级别的声明周期,不是一个线程安全的类,不建议做成单例的。想复用连接可以使用数据库连接池