概要
- MySQL 8.0 にてテーブルに主要な SQL データ型のカラムを定義して、Java のプログラムからカラムの値を取得するサンプルコードを示す
- 今回の動作確認環境: MySQL Ver 8.0.21 for osx10.15 on x86_64 (Homebrew) + MySQL Connector/J 8.0.21 + Java 14 (AdoptOpenJDK 14.0.2) + Gradle 6.6 + macOS Catalina
サンプルコード
ファイル一覧
├── build.gradle
└── src
└── main
└── java
└── JdbcSample.java
build.gradle
plugins {
id 'application'
id 'java'
}
sourceCompatibility = JavaVersion.VERSION_14
repositories {
mavenCentral()
}
dependencies {
// 実行時に MySQL Connector/J 8.0.21 を使う
runtimeOnly 'mysql:mysql-connector-java:8.0.21'
}
tasks.withType(JavaCompile) {
// Java 14 のプレビュー機能を使う
options.compilerArgs += ['--enable-preview']
}
application {
// Java 14 のプレビュー機能を使う
applicationDefaultJvmArgs = ['--enable-preview']
mainClassName = 'JdbcSample'
}
JdbcSample.java
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.sql.Types;
import java.util.Arrays;
class JdbcSample {
public static void main(String[] args) throws Exception {
// MySQL に接続
String url = "jdbc:mysql://localhost/testdb";
String user = "foo";
String password = "cafebabe";
Connection con = DriverManager.getConnection(url, user, password);
Statement stmt = con.createStatement();
// テーブルを作成
// いろいろな MySQL のデータ型でカラムを定義
// (Java 14 プレビュー機能で使えるヒアドキュメントっぽく書けるテキストブロック機能を使う)
stmt.execute("""
create table test (
-- 文字列型
my_char CHAR(8), -- 固定長文字列 (最大長 255 文字)
my_varchar VARCHAR(1024), -- 可変長文字列 (最大長 65535 bytes (ただし指定する数値は文字数))
my_tinytext TINYTEXT, -- 可変長文字列 (最大長 255 bytes)
my_text TEXT, -- 可変長文字列 (最大長 65535 bytes)
my_mediumtext MEDIUMTEXT, -- 可変長文字列 (最大長 16777215 bytes)
my_longtext LONGTEXT, -- 可変長文字列 (最大長 4294967295 bytes)
-- バイナリ型
my_bit BIT(16), -- ビットフィールド値 (最大長 64 bits)
my_binary BINARY(4), -- 固定長バイナリ (最大長 255 bytes)
my_varbinary VARBINARY(4), -- 可変長バイナリ (最大長 65535 bytes)
my_tinyblob TINYBLOB, -- Binary Large Object (最大長 255 bytes)
my_blob BLOB, -- Binary Large Object (最大長 65535 bytes)
my_mediumblob MEDIUMBLOB, -- Binary Large Object (最大長 16777215 bytes)
my_longblob LONGBLOB, -- Binary Large Object (最大長 4294967295 bytes)
-- 真偽値型
my_boolean BOOLEAN, -- 真偽値
-- 整数型
my_tinyint TINYINT, -- 1 byte
my_smallint SMALLINT, -- 2 bytes
my_mediumint MEDIUMINT, -- 3 bytes
my_integer INTEGER, -- 4 bytes
my_bigint BIGINT, -- 8 bytes
-- 浮動小数点型
my_float FLOAT, -- 単精度浮動小数点数 float 4 bytes
my_double DOUBLE, -- 倍精度浮動小数点数 double 8 bytes
-- 固定小数点型
my_numeric NUMERIC, -- 固定小数点数
my_decimal DECIMAL, -- 固定小数点数
-- 時間型
my_date DATE, -- 年月日
my_time TIME, -- 時分秒
my_datetime DATETIME(6), -- 年月日 + 時分秒 + マイクロ秒
my_timestamp TIMESTAMP(6) -- 年月日 + 時分秒 + マイクロ秒 + タイムゾーン
) ENGINE=InnoDB""");
// レコードを追加
// (Java 14 プレビュー機能で使えるヒアドキュメントっぽく書けるテキストブロック機能を使う)
stmt.execute("""
insert into test values (
-- 文字列型
'Hello', -- CHAR
'Hello', -- VARCHAR
'Hello', -- TINYTEXT
'Hello', -- TEXT
'Hello', -- MEDIUMTEXT
'Hello', -- LONGTEXT
-- バイナリ型
b'0111111110000000', -- BIT
X'CAFEBABE', -- BINARY,
X'CAFEBABE', -- VARBINARY,
X'CAFEBABE', -- TINYBLOB,
X'CAFEBABE', -- BLOB,
X'CAFEBABE', -- MEDIUMBLOB,
X'CAFEBABE', -- LONGBLOB,
-- 真偽値型
TRUE, -- BOOLEAN
-- 整数型
127 , -- TINYINT
32767 , -- SMALLINT
8388607 , -- MEDIUMINT
2147483647 , -- INTEGER
9223372036854775807, -- BIGINT
-- 浮動小数点型
123.0001, -- FLOAT
123.0001, -- DOUBLE
-- 固定小数点型
123.0001, -- NUMERIC
123.0001, -- DECIMAL
-- 時間型
'2001-02-03', -- DATE
'04:05:06', -- TIME
'9999-12-31 23:59:59.999999', -- DATETIME
'2038-01-19 03:14:07.999999+00:00' -- TIMESTAMP
)""");
// レコードを取得
ResultSet rs = stmt.executeQuery("select * from test");
while (rs.next()) {
// カラムの JDBC 型や SQL 型に対する Java オブジェクトの型を取得
System.out.println("カラム名 - JDBC 型 - データベース固有の SQL 型 - Java オブジェクトの型");
ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 1; i <= rsmd.getColumnCount(); i++) {
System.out.println(
rsmd.getColumnName(i) + " - " +
getJdbcTypeName(rsmd.getColumnType(i)) + " - " +
rsmd.getColumnTypeName(i) + " - " +
rsmd.getColumnClassName(i));
}
System.out.println();
// カラムの値を取得していく
System.out.println("カラム名 - カラムの値");
// 文字列型
System.out.println("my_char=" + rs.getString("my_char"));
System.out.println("my_varchar=" + rs.getString("my_varchar"));
System.out.println("my_tinytext=" + rs.getString("my_tinytext"));
System.out.println("my_text=" + rs.getString("my_text"));
System.out.println("my_mediumtext=" + rs.getString("my_mediumtext"));
System.out.println("my_longtext=" + rs.getString("my_longtext"));
// バイナリ型
System.out.println("my_bit=" + Arrays.toString(rs.getBytes("my_bit")));
System.out.println("my_binary=" + Arrays.toString(rs.getBytes("my_binary")));
System.out.println("my_varbinary=" + Arrays.toString(rs.getBytes("my_varbinary")));
System.out.println("my_tinyblob=" + Arrays.toString(rs.getBytes("my_tinyblob")));
System.out.println("my_blob=" + Arrays.toString(rs.getBytes("my_blob")));
System.out.println("my_mediumblob=" + Arrays.toString(rs.getBytes("my_mediumblob")));
System.out.println("my_longblob=" + Arrays.toString(rs.getBytes("my_longblob")));
// 真偽値型
System.out.println("my_boolean=" + rs.getBoolean("my_boolean"));
// 整数型
System.out.println("my_tinyint=" + rs.getInt("my_tinyint"));
System.out.println("my_smallint=" + rs.getInt("my_smallint"));
System.out.println("my_mediumint=" + rs.getInt("my_mediumint"));
System.out.println("my_integer=" + rs.getInt("my_integer"));
System.out.println("my_bigint=" + rs.getLong("my_bigint"));
// 浮動小数点型
System.out.println("my_float=" + rs.getFloat("my_float"));
System.out.println("my_double=" + rs.getDouble("my_double"));
// 固定小数点型
System.out.println("my_numeric=" + rs.getBigDecimal("my_numeric"));
System.out.println("my_decimal=" + rs.getBigDecimal("my_decimal"));
// 時間型
System.out.println("my_date=" + rs.getDate("my_date"));
System.out.println("my_time=" + rs.getTime("my_time"));
System.out.println("my_datetime=" + rs.getTimestamp("my_datetime"));
System.out.println("my_timestamp=" + rs.getTimestamp("my_timestamp").toInstant());
}
stmt.close();
con.close();
}
// JDBC 型の名称を取得する
private static String getJdbcTypeName(int type) throws IllegalAccessException {
Field[] fs = Types.class.getDeclaredFields();
for (Field f : fs) {
if (type == f.getInt(null)) {
return f.getName();
}
}
return null;
}
}
実行結果
Gradle の run タスクで実行。
$ gradle run
> Task :compileJava
注意:/Users/foo/bar/src/main/java/JdbcSample.javaはプレビュー言語機能を使用します。
注意:詳細は、-Xlint:previewオプションを指定して再コンパイルしてください。
> Task :run
カラム名 - JDBC 型 - データベース固有の SQL 型 - Java オブジェクトの型
my_char - CHAR - CHAR - java.lang.String
my_varchar - VARCHAR - VARCHAR - java.lang.String
my_tinytext - VARCHAR - TINYTEXT - java.lang.String
my_text - LONGVARCHAR - TEXT - java.lang.String
my_mediumtext - LONGVARCHAR - MEDIUMTEXT - java.lang.String
my_longtext - LONGVARCHAR - LONGTEXT - java.lang.String
my_bit - BIT - BIT - java.lang.Boolean
my_binary - BINARY - BINARY - [B
my_varbinary - VARBINARY - VARBINARY - [B
my_tinyblob - VARBINARY - TINYBLOB - [B
my_blob - LONGVARBINARY - BLOB - [B
my_mediumblob - LONGVARBINARY - MEDIUMBLOB - [B
my_longblob - LONGVARBINARY - LONGBLOB - [B
my_boolean - BIT - BIT - java.lang.Boolean
my_tinyint - TINYINT - TINYINT - java.lang.Integer
my_smallint - SMALLINT - SMALLINT - java.lang.Integer
my_mediumint - INTEGER - MEDIUMINT - java.lang.Integer
my_integer - INTEGER - INT - java.lang.Integer
my_bigint - BIGINT - BIGINT - java.lang.Long
my_float - REAL - FLOAT - java.lang.Float
my_double - DOUBLE - DOUBLE - java.lang.Double
my_numeric - DECIMAL - DECIMAL - java.math.BigDecimal
my_decimal - DECIMAL - DECIMAL - java.math.BigDecimal
my_date - DATE - DATE - java.sql.Date
my_time - TIME - TIME - java.sql.Time
my_datetime - TIMESTAMP - DATETIME - java.sql.Timestamp
my_timestamp - TIMESTAMP - TIMESTAMP - java.sql.Timestamp
カラム名 - カラムの値
my_char=Hello
my_varchar=Hello
my_tinytext=Hello
my_text=Hello
my_mediumtext=Hello
my_longtext=Hello
my_bit=[127, -128]
my_binary=[-54, -2, -70, -66]
my_varbinary=[-54, -2, -70, -66]
my_tinyblob=[-54, -2, -70, -66]
my_blob=[-54, -2, -70, -66]
my_mediumblob=[-54, -2, -70, -66]
my_longblob=[-54, -2, -70, -66]
my_boolean=true
my_tinyint=127
my_smallint=32767
my_mediumint=8388607
my_integer=2147483647
my_bigint=9223372036854775807
my_float=123.0
my_double=123.0001
my_numeric=123
my_decimal=123
my_date=2001-02-03
my_time=04:05:06
my_datetime=9999-12-31 23:59:59.999999
my_timestamp=2038-01-19T03:14:07.999999Z
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed
参考資料
- JDBC API 入門 - SQL と Java の型のマッピング
- java.sql (Java SE 14 & JDK 14)
- MySQL :: MySQL 8.0 Reference Manual :: 11 Data Types
- MySQL :: MySQL 8.0 Reference Manual :: 11.1.2 Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT
- MySQL :: MySQL 8.0 Reference Manual :: 11.3.1 String Data Type Syntax
- MySQL :: MySQL 8.0 Reference Manual :: 11.7 Data Type Storage Requirements
- MySQL :: MySQL Connector/J 8.0 Developer Guide :: 6 Connector/J Reference
- MySQL :: MySQL Connector/J 8.0 Developer Guide :: 6.5 Java, JDBC, and MySQL Types
- Java + H2 Database で主要な JDBC 型の値を取得するサンプルコード - Qiita
- macOS に Homebrew で MySQL 8.0 をインストールしてデータベースを作成する - Qiita