我正在使用MySQL数据库和Java JDBC客户端来访问它。
我有一个包含会话信息的表。每个会话都与SessionToken相关联。此标记是Base64编码的某些会话值的哈希值。它应该是独一无二的。并且在db中定义为varchar(50)。
当我尝试通过其令牌查找会话时,我使用如下的sql语句查询数据库:
select SessionId, ClientIP, PersonId, LastAccessTime, SessionCreateTime from InkaSession where SessionToken like 'exK/Xw0imW/qOtN39uw5bddeeMg='
我有一个测试此功能的UnitTest,它一直都失败了,因为查询没有返回任何Session,即使很难,我刚刚将会话写入了DB。
我的单元测试执行以下操作:
Create Connection via DriverManager.getConnection
Add a session via Sql Insert query
close the connection
create Connection via DriverManager.getConnection
look for the session via sql select
unit test fails, because nothing found
当我使用调试器逐步执行此UnitTest并将要发送到db的select sql复制到mysql命令行时,它工作正常,我得到会话行。
我还试图通过询问较旧的SessionToken来从db中检索旧会话。这也很好。如果我在插入后立即请求SessionToken,它只会失败。
所有连接都在AutoCommit上。不过我尝试将事务级别设置为“Read Uncommited”。这也不起作用。
还有人有任何进一步的建议吗?
答案 0 :(得分:1)
这通常是由于insert和select之间没有提交连接引起的。
你基本上做了以下事情吗?
statement.executeUpdate("INSERT INTO session (...) VALUES (...)");
connection.commit();
resultSet = statement.executeQuery("SELECT ... FROM session WHERE ...");
编辑我在MySQL 5.1.30上使用Connector / J 5.1.7尝试了以下SSCCE:
public static void main(String[] args) throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost/javabase", "root", null);
statement = connection.createStatement();
statement.executeUpdate("INSERT INTO foo (foo) VALUES ('foo')");
resultSet = statement.executeQuery("SELECT id FROM foo WHERE foo = 'foo'");
if (resultSet.next()) {
System.out.println(resultSet.getLong("id"));
} else {
System.out.println("Not inserted?");
}
} finally {
SQLUtil.close(connection, statement, resultSet);
}
}
完美无瑕地工作。可能是JDBC驱动程序的问题。尝试升级。
答案 1 :(得分:0)
解决:两个令牌字符串不相同。其中一个最后有几个零字节。 (由于加密和解密以及填充...)两个字符串在视觉上完全相同,但MySQL和Java都说,它们不在哪里。 (他们像往常一样正确)