8.2.2.3 连接并从数据库获取数据

原文链接: https://kotlinlang.org/docs/data-analysis-connect-to-db.html

8.2.2.3 连接并从数据库获取数据

Kotlin DataFrame 库支持最常见的 SQL 数据库:

探索 GitHub 上的 Kotlin DataFrame SQL 示例。

开始之前

注意: 从 IntelliJ IDEA 2026.2 开始,Kotlin Notebook 将不再随 IDE 一起提供,也不再由 JetBrains 官方支持。源代码仍可在 GitHub 上获取。更多信息请参阅博客文章。

要学习本教程:

  1. 选择 File | New | Kotlin Notebook。
  2. 在笔记本的第一个代码单元中,为你的数据库添加 Java 数据库连接(JDBC)驱动依赖。

例如,要连接到 MariaDB 数据库,请添加:

1
2
3
   USE {
      dependencies("org.mariadb.jdbc:mariadb-java-client:$version")
   }
  1. 导入 Kotlin DataFrame:
1
   %use dataframe

请在任何其他代码单元之前先运行包含 %use dataframe 这一行的代码单元,以确保 DataFrame 库及其 API 在笔记本中可用。

要学习本教程,你也可以把 DataFrame 用作 Gradle 或 Maven 依赖。

连接到数据库

要连接到数据库,请使用 DbConnectionConfig() 函数创建连接配置:

  1. 导入以下功能:
1
2
   import org.jetbrains.kotlinx.dataframe.io.DbConnectionConfig
   import org.jetbrains.kotlinx.dataframe.schema.DataFrameSchema
  1. 使用 DbConnectionConfig() 函数定义连接参数(URL、用户名、密码):
1
2
3
4
5
   val URL = "YOUR_URL"
   val USER_NAME = "YOUR_USERNAME"
   val PASSWORD = "YOUR_PASSWORD"

   val dbConfig = DbConnectionConfig(URL, USER_NAME, PASSWORD)

提示: 关于连接 SQL 数据库的更多信息,请参阅 Kotlin DataFrame 文档中的从 SQL 数据库读取。

检查数据库模式

在加载数据之前,先检查数据库模式,了解你有哪些表以及它们包含哪些列。你可以利用这些模式决定把哪张表加载到 DataFrame 中。

要获取数据库中所有用户创建的表的模式,请使用 DataFrameSchema.readAllSqlTables() 函数:

1
2
3
4
5
6
7
val dataSchemas = DataFrameSchema.readAllSqlTables(dbConfig)

dataSchemas.forEach { (tableName, schema) ->
    println("---Schema for table: $tableName---")
    println(schema)
    println()
}

加载数据

检查完数据库模式并选定数据之后,把数据加载到 DataFrame 中。

Kotlin DataFrame 提供了两种从数据库加载数据的方式:

  • 直接从表加载数据。
  • 加载自定义 SQL 查询的结果。

两种方式都会返回一个 DataFrame,你可以对其进行检查、转换和分析。

从表加载数据

要从表加载数据,请使用 DataFrame.readSqlTable() 函数。

下面的示例从 movies 表加载前 100 行:

1
2
3
4
5
6
7
val moviesDf = DataFrame.readSqlTable(
    dbConfig = dbConfig,
    tableName = "movies",
    limit = 100
)

moviesDf

使用 SQL 查询加载数据

要对数据库执行特定的 SQL 查询,请使用 DataFrame.readSqlQuery() 函数。当你需要在数据库中加载特定列、连接表、过滤行或聚合数据时,这种方式很有用。

我们来获取与昆汀·塔伦蒂诺执导的电影相关的特定数据集。这个查询选择电影详情,并为每部电影合并类型信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
val TARANTINO_FILMS_SQL_QUERY = """
    SELECT name, year, rank, GROUP_CONCAT(genre) as "genres"
    FROM movies JOIN movies_directors ON movie_id = movies.id
    JOIN directors ON directors.id=director_id LEFT JOIN movies_genres ON movies.id = movies_genres.movie_id
    WHERE directors.first_name = "Quentin" AND directors.last_name = "Tarantino"
    GROUP BY name, year, rank
    ORDER BY year
    """

val tarantinoMoviesDf = DataFrame.readSqlQuery(dbConfig, TARANTINO_FILMS_SQL_QUERY)

tarantinoMoviesDf

处理数据

把数据库加载到 DataFrame 之后,你可以使用 DataFrame 操作来处理获取到的数据。

例如,我们来处理上一节中的数据。以下代码:

  1. 使用 .fillNA() 函数替换 year 列中的缺失值。
  2. 使用 .convert() 函数把该列转换为 Int。
  3. 使用 .filter() 函数只保留 2000 年之后上映的电影。
1
2
3
4
5
6
val filteredTarantinoMovies = tarantinoMoviesDf
    .fillNA { year }.with { 0 }
    .convert { year }.toInt()
    .filter { year > 2000 }

filteredTarantinoMovies

分析数据

使用 DataFrame 库对数据分组、排序和聚合,从而发现并理解数据中的模式。

例如,我们从 actors 表中读取演员数据,并找出最常见的 20 个名字:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
// 从 actors 表中提取数据
val actorDf = DataFrame.readSqlTable(dbConfig, "actors", 10000)
val top20ActorNames = actorDf
   // 按 first_name 列对数据分组
   .groupBy { first_name }

   // 统计每个唯一名字出现的次数
   .count()

    // 按计数降序对结果排序
   .sortByDesc("count")

   // 选出出现频率最高的 20 个名字用于分析。
   .take(20)

接下来做什么