首页 文章

JDBC MySQL查询语法

提问于
浏览
1

我正在使用JDBC尝试从此表中进行选择:

CREATE TABLE PERIT (
    COGNOM1 VARCHAR(30) NOT NULL,
    COGNOM2 VARCHAR(30) NOT NULL,
    DATANAIX DATE NOT NULL,
    NOM VARCHAR(30) NOT NULL,
    NIF VARCHAR(10) NOT NULL,
    LOGIN VARCHAR(50) NOT NULL,
    PASSWORDMD5  VARCHAR(50) NOT NULL,
    NUMERO INT(3) NOT NULL AUTO_INCREMENT,
    PRIMARY KEY (NUMERO)
);

我想检查是否存在具有某个登录和PASSWORDMD5值的行,如下所示:

public int Login(String Login, String pass) {
    Statement st = null;
    ResultSet rs = null;
    int count =0;
    try {
        st = con.createStatement();
        String consulta = "Select count(*) from Perit p where p.LOGIN =";
        consulta += Login;
        consulta +=" and p.PASSWORDMD5 = MD5(";
        consulta +=pass;
        consulta+=")";
        rs =  st.executeQuery(consulta);
        while (rs.next()) {
            count = rs.getInt(1);
        }
        st.close();
        rs.close();
    } catch (SQLException ex) {
       Logger.getLogger(JDBCMySQL.class.getName()).log(Level.SEVERE, null, ex);
    }

    return count;
}

但是当我调用 Login("LOGINPERIT1","PASSWORDMDPERIT") 时,我收到此错误:

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)中sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)的'where子句'中的未知列'LOGINPERIT1'在sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)at java.lang.reflect.Constructor.newInstance(Constructor.java:423)at com.mysql.jdbc.Util.handleNewInstance(Util.java:425)at at com.mysql.jdbc.Util.getInstance(Util.java:408)在com.mysql.jdbc.SQLError.createSQLException(SQLError.java:943)在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3973)在com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:3909)在com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:2527)在com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2680 )com的com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2497)com的com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2455) .mysql.jdbc.StatementImpl.executeQuery(StatementImpl.java:1369)在info.infomila.info.JDBCMySQL.Login(JDBCMySQL.java:139)在info.infomila.info.ThreadHandler.run(ThreadHandler.java:56)

1 回答

  • 1

    正如评论中所提到的,您遇到的问题是因为您为登录和密码提供的字符串不包含在单引号中 .

    快速解决这个问题的方法是在您包含传入的登录值和密码之前和之后,在定义的sql字符串中包含单引号,如@DevilsHnd在评论中所述:

    String consulta = "SELECT COUNT(*) FROM Perit WHERE LOGIN = '" + Login + 
    "' AND PASSWORDMD5 = MD5('" + pass + "');"
    

    然而,这是一种危险的方法,我强烈建议您不要使用此方法,因为它使您的登录sql vunerable SQL注入 .

    为避免这种情况,您可以使用PreparedStatement来处理您的输入消毒 .

    您可以通过使用 ? 替换语句参数,然后使用PreparedStatement类的方法设置它们来完成此操作 .

    以下是如何实现此目的的示例:

    String consulta = "SELECT COUNT(*) FROM Perit WHERE LOGIN = ? AND PASSWORDMD5 = MD5(?);"
    try(PreparedStatement pstmt = con.prepareStatement(consulta))
    {
        pstmt.setString(1, login); 
        pstmt.setString(2, pass); 
        try(ResultSet rs = pstmt.executeQuery())
        {
            count = rs.getInt(1);
        }
    } 
    catch (SQLException ex) 
    {
        Logger.getLogger(JDBCMySQL.class.getName()).log(Level.SEVERE, null, ex);
    }
    

    您的方法中另一个值得关注的方面是 StatementResultSet 未在finally块中关闭 - 这可能导致代码中的内存泄漏 .

    请注意我使用资源块的尝试 - 这将关闭 PreparedStatementResultSet ,就像它们在finally块中关闭一样 .

    我会在这里留下这个xkcd漫画!

    enter image description here

相关问题