在 Java 中使用 SQL 时,**防止 SQL 注入(SQL Injection)**的核心原则是:永远不要把用户输入直接拼接到 SQL 语句中。下面从最常见、最推荐到补充手段系统说明。
String sql = "SELECT * FROM user WHERE username = ? AND password = ?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, username);
ps.setString(2, password);
ResultSet rs = ps.executeQuery();
String sql = "SELECT * FROM user WHERE username = '" + username + "'";
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery(sql);
✅ PreparedStatement 会将参数作为数据处理,而不是 SQL 代码,从根本上防止注入。
#{} ✅(安全,预编译)SELECT * FROM user WHERE username = #{username}
${} ❌(直接拼接,危险)@Query("FROM User u WHERE u.username = :username")
List<User> findUser(@Param("username") String username);
✅ JPA 默认使用参数化查询。
⚠️ 不能单独依赖,但有用:
if (!username.matches("[a-zA-Z0-9_]{3,20}")) {
throw new IllegalArgumentException("非法用户名");
}
数据库账号应:
rootSELECT、UPDATE)✅ 如果使用参数化调用:
CallableStatement cs = conn.prepareCall("{call getUser(?)}");
cs.setString(1, username);
❌ 存储过程内部拼接 SQL 仍然危险。
Java 防 SQL 注入 = PreparedStatement + 参数化 + ORM + 输入校验 + 最小权限
如果你用的是 Spring Boot / MyBatis / JPA,我可以给你对应的最佳实践示例。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。