JDBC

Versi 1.0 dan 1.1 protokol keamanan TLS dinonaktifkan. Untuk membuat koneksi, gunakan TLS 1.2 atau yang lebih baru.

Google Apps Script dapat terhubung ke database eksternal melalui layanan JDBC, yaitu sebuah wrapper untuk teknologi Java Database Connectivity standar. Layanan JDBC mendukung database Google Cloud SQL untuk MySQL, MySQL, Microsoft SQL Server, Oracle, dan PostgreSQL.

Jika spreadsheet Anda menjadi terlalu besar atau Anda mengalami masalah waktu tunggu dengan penghitungan yang rumit, memindahkan data Anda ke database eksternal dapat meningkatkan performa dan keandalan secara signifikan.

Untuk memperbarui database eksternal dengan JDBC, skrip Anda harus membuka koneksi ke database, lalu membuat perubahan dengan mengirim pernyataan SQL.

Database Google Cloud SQL

Google Cloud SQL memungkinkan Anda membuat database relasional yang berada di cloud Google. Cloud SQL mungkin dikenai biaya berdasarkan penggunaan Anda.

Buat instance Google Cloud SQL dengan mengikuti langkah-langkah yang tercantum dalam panduan memulai Cloud SQL.

Membuat koneksi Google Cloud SQL

Ada dua cara untuk membuat koneksi dengan database Google Cloud SQL menggunakan layanan JDBC Apps Script:

Keduanya valid, tetapi metode kedua mengharuskan Anda mengizinkan serangkaian rentang IP untuk mengakses database Anda.

Metode ini membuat koneksi ke instance MySQL di Google Cloud SQL menggunakan metode Jdbc.getCloudSqlConnection. URL database memiliki bentuk jdbc:google:mysql://subname, dengan subname adalah Nama Koneksi Instance MySQL yang tercantum di halaman Ringkasan instance Cloud SQL di Konsol Google Cloud.

Untuk terhubung ke Cloud SQL SQL Server, lihat Jdbc.getConnection.

Gunakan Jdbc.getConnection

Untuk menggunakan metode ini, Anda harus memberikan otorisasi pada rentang alamat IP Classless Inter-Domain Routing (CIDR) tertentu agar server Apps Script dapat terhubung ke database Anda. Sebelum menjalankan skrip, selesaikan langkah-langkah berikut:

  1. Di instance Google Cloud SQL Anda, otorisasi rentang IP, satu per satu dari sumber data ini.

  2. Salin URL yang ditetapkan ke database Anda; URL tersebut harus dalam format jdbc:mysql:subname.

Setelah Anda mengizinkan rentang IP ini, buat koneksi ke instance SQL Google Cloud menggunakan salah satu metode Jdbc.getConnection dan URL yang Anda salin sebelumnya.

Database lainnya

Jika Anda sudah memiliki database MySQL, Microsoft SQL Server, Oracle, atau PostgreSQL sendiri, hubungkan ke database tersebut melalui layanan JDBC Apps Script.

Membuat koneksi database lainnya

Untuk membuat koneksi database menggunakan layanan JDBC Apps Script, di setelan database, Anda harus mengizinkan rentang IP dari sumber data ini.

Layanan JDBC hanya dapat terhubung ke port 1025 atau yang lebih baru. Pastikan database Anda tidak melayani dari port yang lebih rendah.

Setelah daftar yang diizinkan ini diterapkan, buat koneksi ke database menggunakan salah satu metode Jdbc.getConnection dan URL database Anda.

Kode contoh

Contoh kode berikut mengasumsikan Anda terhubung ke database Google Cloud SQL, dan membuat koneksi database menggunakan metode Jdbc.getCloudSqlConnection. Untuk database lain, Anda harus menggunakan metode Jdbc.getConnection untuk membuat koneksi database.

Untuk mengetahui informasi selengkapnya tentang metode JDBC, lihat dokumentasi Java untuk JDBC.

Membuat database, pengguna, dan tabel

Kebanyakan developer menggunakan alat command line MySQL untuk membuat database, pengguna, dan tabel. Namun, Anda dapat melakukan hal yang sama di Apps Script, seperti yang ditunjukkan dalam contoh berikut. Buat setidaknya satu pengguna lain agar skrip Anda tidak selalu harus terhubung ke database sebagai root.

service/jdbc.gs
/**
 * Create a new database within a Cloud SQL instance.
 */
function createDatabase() {
  try {
    const conn = Jdbc.getCloudSqlConnection(instanceUrl, root, rootPwd);
    conn.createStatement().execute(`CREATE DATABASE ${db}`);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log("Failed with an error %s", err.message);
  }
}

/**
 * Create a new user for your database with full privileges.
 */
function createUser() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, root, rootPwd);

    const stmt = conn.prepareStatement("CREATE USER ? IDENTIFIED BY ?");
    stmt.setString(1, user);
    stmt.setString(2, userPwd);
    stmt.execute();

    conn.createStatement().execute(`GRANT ALL ON \`%\`.* TO ${user}`);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log("Failed with an error %s", err.message);
  }
}

/**
 * Create a new table in the database.
 */
function createTable() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);
    conn
      .createStatement()
      .execute(
        "CREATE TABLE entries " +
          "(guestName VARCHAR(255), content VARCHAR(255), " +
          "entryID INT NOT NULL AUTO_INCREMENT, PRIMARY KEY(entryID));",
      );
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log("Failed with an error %s", err.message);
  }
}

Menulis ke database

Contoh berikut menunjukkan cara menulis satu catatan ke database serta batch 500 catatan. Pengelompokan sangat penting untuk operasi massal.

Pernyataan berparameter digunakan, dengan variabel yang ditandai dengan ?. Untuk mencegah serangan injeksi SQL, gunakan pernyataan berparameter untuk meng-escape semua data yang diberikan pengguna.

service/jdbc.gs
/**
 * Write one row of data to a table.
 */
function writeOneRecord() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);

    const stmt = conn.prepareStatement(
      "INSERT INTO entries " + "(guestName, content) values (?, ?)",
    );
    stmt.setString(1, "First Guest");
    stmt.setString(2, "Hello, world");
    stmt.execute();
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log("Failed with an error %s", err.message);
  }
}

/**
 * Write 500 rows of data to a table in a single batch.
 */
function writeManyRecords() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);
    conn.setAutoCommit(false);

    const start = new Date();
    const stmt = conn.prepareStatement(
      "INSERT INTO entries " + "(guestName, content) values (?, ?)",
    );
    for (let i = 0; i < 500; i++) {
      stmt.setString(1, `Name ${i}`);
      stmt.setString(2, `Hello, world ${i}`);
      stmt.addBatch();
    }

    const batch = stmt.executeBatch();
    conn.commit();
    conn.close();

    const end = new Date();
    console.log("Time elapsed: %sms for %s rows.", end - start, batch.length);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log("Failed with an error %s", err.message);
  }
}

/**
 * Write 500 rows of data to a table in a single batch.
 * Recommended for faster writes
 */
function writeManyRecordsUsingExecuteBatch() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);
    conn.setAutoCommit(false);

    const start = new Date();
    const stmt = conn.prepareStatement(
      "INSERT INTO entries " + "(guestName, content) values (?, ?)",
    );
    const params = [];
    for (let i = 0; i < 500; i++) {
      params.push([`Name ${i}`, `Hello, world ${i}`]);
    }

    const batch = stmt.executeBatch(params);
    conn.commit();
    conn.close();

    const end = new Date();
    console.log("Time elapsed: %sms for %s rows.", end - start, batch.length);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log("Failed with an error %s", err.message);
  }
}

Membaca dari database

Contoh ini menunjukkan cara membaca sejumlah besar data dari database, dengan melakukan loop pada set hasil sesuai kebutuhan.

service/jdbc.gs
/**
 * Read up to 1000 rows of data from the table and log them.
 */
function readFromTable() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);
    const start = new Date();
    const stmt = conn.createStatement();
    stmt.setMaxRows(1000);
    const results = stmt.executeQuery("SELECT * FROM entries");
    const numCols = results.getMetaData().getColumnCount();

    while (results.next()) {
      let rowString = "";
      for (let col = 0; col < numCols; col++) {
        rowString += `${results.getString(col + 1)}\t`;
      }
      console.log(rowString);
    }

    results.close();
    stmt.close();

    const end = new Date();
    console.log("Time elapsed: %sms", end - start);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log("Failed with an error %s", err.message);
  }
}

/**
 * Read up to 1000 rows of data from the table and log them.
 * Recommended for faster reads
 */
function readFromTableUsingGetRows() {
  try {
    const conn = Jdbc.getCloudSqlConnection(dbUrl, user, userPwd);
    const start = new Date();
    const stmt = conn.createStatement();
    stmt.setMaxRows(1000);
    const results = stmt.executeQuery("SELECT * FROM entries");
    const numCols = results.getMetaData().getColumnCount();
    const getRowArgs = [];
    for (let col = 0; col < numCols; col++) {
      getRowArgs.push(`getString(${col + 1})`);
    }
    const rows = results.getRows(getRowArgs.join(","));
    for (let i = 0; i < rows.length; i++) {
      console.log(rows[i].join("\t"));
    }

    results.close();
    stmt.close();

    const end = new Date();
    console.log("Time elapsed: %sms", end - start);
  } catch (err) {
    // TODO(developer) - Handle exception from the API
    console.log("Failed with an error %s", err.message);
  }
}

Menutup koneksi

Koneksi JDBC akan ditutup secara otomatis saat skrip selesai dieksekusi. (Panggilan google.script.run tunggal dihitung sebagai eksekusi yang selesai, meskipun halaman layanan HTML yang melakukan panggilan tetap terbuka.)

Namun, jika Anda tahu bahwa Anda telah selesai menggunakan koneksi, pernyataan, atau set hasil sebelum akhir skrip, tutup secara manual dengan memanggil JdbcConnection.close, JdbcStatement.close, atau JdbcResultSet.close.

Menampilkan dialog peringatan atau perintah juga akan menghentikan koneksi JDBC yang terbuka. Namun, elemen UI lain yang ditampilkan —seperti menu atau dialog kustom dan sidebar dengan konten kustom—tidak dapat.

Google, Google Workspace, serta merek dan logo terkait adalah merek dagang Google LLC. Semua nama perusahaan dan produk lainnya adalah merek dagang dari masing-masing perusahaan yang bersangkutan.