我正在为uni进行一个项目(恰好在14个小时内到期),我处在一个棘手的问题上。它是一个基于web的网上商店,在apache tomcat和derby上运行。
我有一个准备好的语句,用于检查用户名和密码,无论我尝试此语句返回0行。相同的sql在sql便笺簿中运行并返回预期的内容。
我使用调试器来检查预处理的语句对象,查询似乎很好。文本中的?仍然存在而不是填充变量,但这似乎是正常的。我也尝试从控制台运行完全相同的手写sql,但没有任何运气。
我在sql控制台中运行的查询是
SELECT * FROM username WHERE username='user@system.com' AND passwordhash='passwordhash'
准备好的陈述看起来像这样。
PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username " +
"WHERE emailaddress=?" +
" AND passwordhash=?");
pstmt.setString(1,username);
pstmt.setString(2, username + ":" + passwordLogin);
我正处于尝试所有事情的地步,并且已经完成了搜索。我知道这是一个单项目,标准答案是让人们去看看。在这一点上,我需要用勺子喂一条小路。
编辑以下是更多背景信息,我尝试在此管道中运行已知的工作查询,但也无法返回任何行。
public static User getUser(String username, String passwordHash) {
DBBean db = new DBBean();
System.out.println("Logging in for username " + username + " and password " + passwordHash);
try {
ResultSet rs;
PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username " +
"WHERE emailaddress=?" +
" AND passwordhash=?");
pstmt.setString(1,username);
pstmt.setString(2,passwordHash);
//PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.product");
//PreparedStatement pstmt = db.prepareStatement("SELECT * FROM reallynice.username WHERE emailaddress='user@me.com' AND passwordhash='megahashstring'");
rs = pstmt.executeQuery();
System.out.println("Rows returned\t" + rs.getRow());
if(rs.getRow() < 1)
return null;
int id = rs.getInt("uid");
String name = rs.getString("name");
String emailaddress = rs.getString("emailaddress");
String password = rs.getString("passwordhash");
boolean isAdmin = false;
pstmt = db.prepareStatement("SELECT * FROM reallnice.admin WHERE uid= ?");
pstmt.setInt(1, id);
rs = pstmt.executeQuery();
if(rs.getMetaData().getColumnCount() > 0)
isAdmin = true;
return new User(id,isAdmin,name,emailaddress,password);
} catch(Exception ex) {
System.out.println(ex);
}
return null;
}
我还包括了我为此尝试的其他查询。
答案 0 :(得分:1)
每当我看到某人有这样的经历时:“无论我尝试什么,这句话都会返回0行,”有两个可能的原因立即浮现在脑海中:
1)您没有使用您认为自己的数据库。 Derby的连接URL,如果你说“; create = true”,如果你没有在你期望的位置找到现有的数据库,那么当你连接时,它将很乐意创建一个新的空数据库。这种问题源于对数据库创建位置的混淆;将在任何目录中创建具有相对名称的数据库,该目录将转换为获取该连接URL的Derby实例的be derby.system.home。因此,请检查您是否使用不同的当前工作目录,或者由于某些其他原因连接到您认为不同的数据库。
2)您没有使用您认为自己的架构。 Derby非常乐意创建多个模式,每个模式都有一组单独的表,所以如果你最初以用户A身份连接,然后以用户B身份连接,并且不发出SET SCHEMA,那么用户A和用户B具有完全独立的表集,因此您将无法访问您认为自己的表。因此,请检查您是否以同一用户身份进行连接,并在连接到数据库时使用相同的架构。
答案 1 :(得分:0)
尝试更改显示日志记录声明的方式
System.out.println("Rows returned\t" + rs.getRow());
getRow()返回当前行号,而不是返回的记录数。为了让用户getRow()计算结果集中的条目数,您需要将结果集的指针移动到最后一个条目。
你还有,还没有叫next(),这意味着你没有指向任何东西(很可能是你总是看到0作为数字的原因)。尝试使用
while(rs.next()){ //go through the entire ResultSet}
或
if(rs.next()) { //access the first record in the ResultSet}
总而言之,如果您将代码更改为类似以下内容,则可能会有更好的结果。
rs = pstmt.executeQuery();
if(rs.next()){
System.out.println("Processing Row " + rs.getRow());
//continue on
}else{
System.out.println("No Records");
}
如果您将表设置为用户名是唯一键的表,则可以确定这将返回0或1行。否则使用while()选项而不是if()
修改:: 强> 另外作为旁注,因为你没有调用next()
if(rs.getRow() < 1)
return null;
将始终为0,从您的方法返回null。