【问题标题】:Grails - Unable to execute SELECT WHERE with MysqlGrails - 无法使用 Mysql 执行 SELECT WHERE
【发布时间】:2017-08-11 12:31:26
【问题描述】:

我正在尝试在 grails 中执行 SELECT WHERE 查询以实现登录页面。我不应该使用 PHP 或 Spring 进行数据验证。

user.groovy

包登录mysql

class User {

    String userName
    String password

    static constraints = {
        userName (unique:true)
        password (password:true)
    }
}

userController.groovy

package loginmysql

class UserController {

    def UserService

    def index() {
    UserService.createTables();
    //UserService.insertToTables() // upon Inserting, must not be inserted twice
}

def login() {
    UserService.searchLoginInput(params.userName,params.password)
    redirect(action: "index")   // return to index page again and display login message*/
}

}

userService.groovy

package loginmysql

import grails.transaction.Transactional
import groovy.sql.Sql

@Transactional
class UserService {

    def dataSource

    def searchLoginInput(String input_user, String input_pass) {
        def sql = new Sql(dataSource)
        def sql2 = new Sql(dataSource)
        int userNum = 0
        sql.eachRow('SELECT userName FROM users WHERE userName=$input_user') { row ->
            if (input_user == row.userName) {
                sql2.eachRow('SELECT password FROM users WHERE password=$input_pass') { row2 ->
                    if (input_pass == row2.password) {
                        flash.message = " login succeded!!!"
                        session.user = input_user   // keep info on who connected
                        userNum++
                    } else {
                        flash.message = "login failed!!!"
                    }
                }
            }
        }
        if (userNum==0) flash.message = "Username not found!!!"
    }

    def createTables(){
        def sql = new Sql(dataSource)
        sql.execute '''
            CREATE TABLE IF NOT EXISTS users (
            userId INTEGER AUTO_INCREMENT PRIMARY KEY NOT NULL,
            userName VARCHAR(50) UNIQUE,
            password VARCHAR(100)
            )ENGINE=InnoDB DEFAULT CHARSET=utf8;
            '''
    }

    def insertToTables(){
        def sql = new Sql(dataSource)
        def params = ['vagg77', 'pass']
        sql.execute 'INSERT INTO users (userName, password) VALUES (?, ?)', params
        params = ['mary', 'pass']
        sql.execute 'INSERT INTO users (userName, password) VALUES (?, ?)', params
    }
}

这是页面登录时发生的情况:

如果我在 searchLoginInput() 中添加一个 println() 函数,那么我会看到值已正确地从我的控制器发送到我的服务

这是我遇到的确切错误:

我想知道我输入的查询是否在 MySQL 中有错误的语法,所以我尝试在 mysql 控制台上执行查询。

数据库条目

控制台中的 MySQL 查询

【问题讨论】:

  • GStrings 使用双引号,而不是单引号。所以应该是sql.eachRow("SELECT userName FROM users WHERE userName=${input_user}"). 还要注意花括号的使用。

标签: mysql select grails groovy


【解决方案1】:

Groovy 字符串(或 GStrings)中的变量替换要求您使用双引号,而不是单引号。另外,使用花括号。

因此,在您的情况下,创建 SQL 语句将如下所示:

"SELECT userName FROM users WHERE userName=${input_user}"

【讨论】:

  • 感谢您的提醒,正如您从格式不佳的代码中看到的那样,我完全是 grails 的初学者。非常感谢您的帮助
  • “但是,作为旁注。您不应该创建这样的 SQL 语句。这样做会使您自己面临 SQL 注入攻击。” - 我不认为这是真的。 Sql 类拦截该属性访问并进行适当的转义。
  • 这是通过使用像 eachRow 这样的方法的重载版本来完成的,它接受 GString 作为参数,因此字符串在作为参数传递之前不会被插值。见github.com/apache/groovy/blob/…。从那里,从GString 中提取单个参数值,从GString 检索字符串值的其余部分,最终创建PreparedStatement 并填充参数,因此整个事情是SQL 注入安全的。
  • @JeffScottBrown,一如既往,谢谢。为此,还有很多其他方面!
  • 没问题。这是一个很棒的功能。
【解决方案2】:

为什么使用 SQL 而不是 Gorm? 如果你想改变查询,你只需要使用这个:

User.findByUsername(input_user) 

【讨论】:

  • 我被指示使用 sql 查询,注入数据源而不是 GORM :P
  • 好的,但是如果您是 Grails 的初学者,您应该知道使用 sql 查询而不是 GORM 是一个坏主意。除非您需要使用存储过程,否则您应该使用 Grails 标准。
  • "...您应该知道使用 sql 查询而不是 GORM 是一个坏主意。" - 这并不总是正确的。使用 SQL 有充分的理由。 GORM(以及一般的 ORM)并不总是适用于所有场景的最佳解决方案。有时 SQL 是完全合理的。
  • 当然可以,但是一般来说你不需要写SQL,除非你需要运行存储过程或者太具体的东西。对不起我的英语不好:/
  • “当然可以,但是一般来说你不需要编写 SQL,除非你需要运行存储过程之类的东西或者太具体的东西。” - 一般而言,这是合理的,但除了存储过程之外,还有其他原因使 SQL 可能比使用 ORM 更有意义。我正在解决“......你应该知道使用 sql 查询而不是 GORM 是一个坏主意”的说法。
猜你喜欢
  • 2011-06-02
  • 1970-01-01
  • 2012-01-21
  • 1970-01-01
  • 2014-09-23
  • 1970-01-01
  • 2013-01-03
  • 2011-06-28
  • 2013-06-21
相关资源
最近更新 更多