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
相关产品推荐
相关产品推荐

