任何人都可以帮我解决这个问题,我正在使用SQLMap(ibatis)处理java。 我有3个类,MainConfiguration,SQLMap,DBUtility。
public class MainConfiguration
{
public static String file = "configuration/db/SQLMapConfig.conf";
public static void main(String[] args) throws Exception
{
new MainConfiguration().loadConfiguration();
}
public static void loadConfiguration()
{
SQLMap.setMapFile(file);
List list = DBUtility.loadUsers();
}
}
public final class SQLMap
{
private static SqlMapClient sqlMap;
public static void setMapFile(String sMapFile)
{
try
{
sqlMap = SqlMapClientBuilder.buildSqlMapClient(new FileReader(sMapFile));
}
catch (Exception e)
{
throw new RuntimeException("Error initializing SqlMapClient class", e);
}
}
public static SqlMapClient getSqlMapInstance()
{
return sqlMap;
}
}
DBUtility(此类是对象实例和从SQLMap类获取对象的地方)
public class DBUtility
{
// object utility
protected static SqlMapClient sqlMap = SQLMap.getSqlMapInstance();
//constructor
public DBUtility() throws Exception
{
}
public static List loadUsers()
{
//it's working
logger.info("SQLMap Get Instance = " + SQLMap.getSqlMapInstance());
//it's not working
logger.info("SQLMap Get Instance = " + sqlMap);
//code below will be error because of null sqlMap
try
{
listUser = sqlMap.queryForList("getUsers");
}
catch (Exception sqle)
{
logger.error("Error on load all user", sqle);
}
return listUser;
}
}
记录器给我这个:
SQLMap Get Instance = com.ibatis.sqlmap.engine.impl.SqlMapClientImpl@76707e36
SQLMap Get Instance = null
为什么第二个日志会给我null,即使我有实例对象?
答案 0 :(得分:0)
当加载DBUtility类时,您的字段sqlMap
被初始化,这显然发生在SQLMap.setMapFile(file);
被调用之前。因此,sqlMap
指向不同的内容:静态字段中的null
,以及loadUsers()
中调用getter时的实际实例。
问题是DBUtility
过早查找sqlMap
。它必须等到file
传递给SQLMap
。像这样更改代码以延迟DbUtility.sqlMap
的初始化:
public static void loadConfiguration()
{
SQLMap.setMapFile(file);
DBUtility.initMapClient(); // notify DBUtility
List list = DBUtility.loadUsers();
}
public class DBUtility
{
protected static SqlMapClient sqlMap; // do not initialize too early
public static void initMapClient()
{
sqlMap = SQLMap.getSqlMapInstance(); // wait for SQLMap to be ready
}
当然,如果你在DBUtility中甚至没有sqlMap
字段,那会更简单。每次需要时都可以致电SQLMap.getSqlMapInstance()
。如果实例发生变化,这一点尤为重要:
listUser = SQLMap.getSqlMapInstance().queryForList("getUsers");
阅读When are static variables are initialized?以获取有关静态字段的更详细说明。