You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin动态生成SQL查询用户时调用result.getObject()触发空指针

问题分析与解决方案

咱们先揪出触发NullPointerException的核心原因,再一步步把代码改对:

1. 空指针的直接诱因

你提到调用result.getObject()时触发NPE,结合你贴的代码来看:

  • 当DatabaseController().trySql(sql)返回null时,你没有做任何拦截就直接操作result,自然会炸;
  • 就算result不为null,如果结果集为空(isBeforeFirst为false),你只是打印日志,但如果后续继续调用result.getObject(),也会因为结果集没有有效数据抛出异常。

另外,你当前的代码没有返回值,这和方法定义的User?返回类型不匹配,编译器应该也会提示错误。

2. 必须重视的安全漏洞:SQL注入

你直接把用户输入的name拼进SQL字符串里,这是非常危险的操作!恶意用户可以构造特殊用户名(比如" OR 1=1; --")来执行任意SQL语句,轻则泄露所有用户数据,重则删除数据库表。必须用预编译SQL语句来解决这个问题。

3. 修正后的完整代码

fun getByUsername(name: String): User? {
    // 使用预编译语句,彻底避免SQL注入风险
    val sql = "SELECT * FROM usertable WHERE username = ?;"
    // 假设trySql方法支持传入预编译参数
    val result = DatabaseController().trySql(sql, name)

    return result?.let { rs ->
        if (rs.next()) { // 移动到第一条数据,同时判断是否存在有效结果
            // 根据你的User类字段,从结果集中取值构建对象
            User(
                id = rs.getLong("id"),
                username = rs.getString("username"),
                // 补充其他需要的字段...
            )
        } else {
            println("User was not found......")
            null
        }
    } ?: run {
        println("Database query failed......")
        null
    }
}

关键改进点

  • 用预编译SQL替代字符串拼接,从根源杜绝SQL注入;
  • 用result?.let安全处理result为null的情况;
  • 用rs.next()判断并定位到有效数据行,避免对空结果集的无效操作;
  • 明确返回User对象或null,符合方法的返回类型定义;
  • 增加了查询失败的日志提示,方便排查问题。

内容的提问来源于stack exchange,提问作者cela

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 11:07:35