如何用Lambda函数向MySQL插入数据?编译错误求助
问题解决:Lambda变量作用域导致的编译错误及词频数据入库实现
错误原因
编译错误k cannot be resolved的核心是变量作用域问题:
k是forEach(k -> out.println(...))这个Lambda表达式的局部参数,它的作用域仅局限于该Lambda的代码块内部- 后续的数据库操作代码在Lambda外部,无法访问这个局部变量,因此编译器无法识别
k
修复方案
要实现排序后的词频数据插入数据库,需要将数据库插入逻辑嵌入到遍历排序后entry的Lambda代码块中,这样就能正确访问每个词频条目。同时可以优化代码结构和排序逻辑,提升可读性和性能。
关键改动点
- 将
PreparedStatement的参数设置与执行逻辑移到forEach的Lambda内部 - 用更简洁的
Comparator实现降序排序:Comparator.comparingInt(Map.Entry::getValue).reversed() - 调整代码嵌套结构,合理管理数据库连接、IO资源等
修正后的完整代码
import java.io.*; import java.sql.*; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; public class SomeRandomName { static Map<String, Integer> count(Scanner scanner) { Map<String, Integer> words = new LinkedHashMap<>(); while (scanner.hasNext()) { words.merge(scanner.next(), 1, Integer::sum); } return words; } public static void main(String[] args) throws IOException { // 1. 统计词频 Map<String, Integer> map = null; try (Scanner scanner = new Scanner(new File("FlyingRats.txt")).useDelimiter("\\W+")) { try { map = count(scanner); } catch (Exception e) { e.printStackTrace(); } } if (map == null || map.isEmpty()) { System.out.println("没有统计到有效词频数据"); return; } // 2. 写入文件并插入数据库 try (FileWriter fw = new FileWriter("FlyingRats.txt", true); BufferedWriter bw = new BufferedWriter(fw); PrintWriter out = new PrintWriter(bw)) { // 加载JDBC驱动 try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); return; } String url = "jdbc:mysql://localhost:3306/eagle_scoutleader"; String user = "root"; String password = "**********"; String sql = "INSERT INTO cats(wordCount, wordName) VALUES(?,?)"; String query = "SELECT * FROM cats"; // 建立数据库连接 try (Connection con = DriverManager.getConnection(url, user, password); PreparedStatement pst = con.prepareStatement(sql); Statement statement = con.createStatement()) { // 遍历排序后的词频数据,同时写入文件和数据库 map.entrySet().stream() .sorted(Comparator.comparingInt(Map.Entry::getValue).reversed()) .forEach(k -> { // 写入文件 out.println(k.getKey() + ": " + k.getValue()); // 插入数据库 try { pst.setInt(1, k.getValue()); pst.setString(2, k.getKey()); pst.executeUpdate(); } catch (SQLException ex) { Logger lgr = Logger.getLogger(SomeRandomName.class.getName()); lgr.log(Level.SEVERE, "插入数据失败:" + k.getKey(), ex); } }); // 查询并打印数据库数据 try (ResultSet rs = statement.executeQuery(query)) { while (rs.next()) { System.out.print(rs.getInt(1)); System.out.print(": "); System.out.print(rs.getInt(2) + " "); System.out.println(rs.getString(3)); } } } catch (SQLException ex) { Logger lgr = Logger.getLogger(SomeRandomName.class.getName()); lgr.log(Level.SEVERE, "数据库操作失败", ex); } } } }
额外优化说明
- 增加了空值判断,避免
map为null时出现空指针异常 - 使用try-with-resources自动管理所有资源(Scanner、IO流、数据库连接、Statement等),无需手动关闭
- 将排序逻辑简化为Java 8提供的Comparator工具方法,代码更简洁易维护
- 拆分了代码模块,逻辑更清晰,便于后续维护
内容的提问来源于stack exchange,提问作者John Hendricks
相关产品推荐
相关产品推荐

