JSqlParserを使ってCREATE TABLE文に主キー(PRIMARY KEY)を追加する方法
パーサー(Parser)とは、単語や文の並びからなるシーケンスの文法を解析し、構文木として表現するプログラムのことです。プログラミング言語、自然言語処理、SQLなど、さまざまな分野で活用されています。このチュートリアルでは、パーサーの使い方を示す例として、オープンソースの JSqlParser を取り上げます。
JSqlParserとは
JSqlParserは、GitHubで公開されているオープンソースのSQLステートメントパーサーです。SQL文を解析し、Javaクラスの階層構造へと変換します。以下の例では、JSqlParserを使ってCREATE TABLE文を解析し、主キーを追加するJavaプログラムを作成していきます。
対象となるCREATE TABLE文
CREATE TABLE College_db.Students (
Student_id int,
Name varchar(255),
Course varchar(255),
Join_date DATE
);
上記のCREATE TABLE文では、Student_id カラムを主キーとして追加することを目標とします。
JSqlParserでCREATE TABLE文を解析するJavaプログラム
ステップ1:JSqlParserを依存関係に追加する
Mavenプロジェクトを作成し、pom.xmlファイルに以下の依存関係を追加します。
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.2</version>
</dependency>
ステップ2:入力となるCREATE TABLE文を変数に代入する
これは主キーが定義されていないCREATE TABLE文です。改行文字「\n」は必須ではなく、SQL全体を1行で指定しても問題ありません。ここでは可読性を高めるために複数行で記述しています。
String createTableSql = "CREATE TABLE College_db.Students (\n" +
" Student_id int,\n" +
" Name varchar(255),\n" +
" Course varchar(255),\n" +
" Join_date DATE\n" +
");";
ステップ3:JSqlParserでSQLを解析する
ユーティリティクラス CCJSqlParserUtil のparseメソッドを呼び出し、引数としてCREATE TABLE文を渡します。
Statement createTable = CCJSqlParserUtil.parse(createTableSql);
parseメソッドを実行すると、Statementオブジェクト createTable には次のようなJavaクラスの階層構造が格納されます。
ステップ4:パーサーの出力内容を確認する
parseメソッドが正常に完了すると、CREATE TABLE文に関するすべての情報を取得できます。ここではデータベース名・テーブル名とカラム定義を取得し、さらにデータベース名とテーブル名を変更してみます。
System.out.println("Table Name from query: " + ((CreateTable) createTable).getTable().getName());
System.out.println("Database Name from query: " + ((CreateTable) createTable).getTable().getSchemaName());
System.out.println("\nColumns in the given insert query");
System.out.println("---------------------------------\n");
for(ColumnDefinition col: ((CreateTable) createTable).getColumnDefinitions())
{
System.out.println(col.getColumnName() + " - " + col.getColDataType().toString());
}
//DB名とテーブル名を変更
((CreateTable) createTable).getTable().setSchemaName("College_db_bk");
((CreateTable) createTable).getTable().setName("Students_bkup");
ステップ5:主キー制約をインデックスとして作成する
SQLにはCHECK制約、EXCLUDE制約、外部キー、名前付き制約など、さまざまな種類のインデックスを設定できます。主キーの場合は、以下のようにNamedConstraint(名前付き制約)を作成する必要があります。
//主キー制約の作成
NamedConstraint namedConstraint = new NamedConstraint();
namedConstraint.setType("PRIMARY KEY");
//主キーにカラム名を追加
List<Index.ColumnParams> columns = new ArrayList<>();
Index.ColumnParams columnParams = new Index.ColumnParams("Student_id");
columns.add(columnParams);
//主キー制約にカラムを設定
namedConstraint.setColumns(columns);
続いて、Student_id を主キーとするNamedConstraintをインデックスリストに設定します。
//インデックスリストに主キー制約を設定
List<Index> indexList = new ArrayList<>();
indexList.add(namedConstraint);
ステップ6:CREATE TABLE文にインデックスを設定する
以下のように作成したインデックスリストをCREATE TABLE文にセットすると、主キーを含むCREATE TABLE文が生成されます。
((CreateTable) createTable).setIndexes(indexList);
主キーを追加する完全なJavaプログラム
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.Statement;
import net.sf.jsqlparser.statement.create.table.ColumnDefinition;
import net.sf.jsqlparser.statement.create.table.CreateTable;
import net.sf.jsqlparser.statement.create.table.Index;
import net.sf.jsqlparser.statement.create.table.NamedConstraint;
import java.util.ArrayList;
import java.util.List;
public class AddPrimaryKey {
public static void main(String[] args) {
System.out.println("Adding Primary key in the CREATE TABLE statement");
System.out.println("-------------------------------------\n");
//入力となるCREATE TABLE文を代入
String createTableSql = "CREATE TABLE College_db.Students (\n" +
" Student_id int,\n" +
" Name varchar(255),\n" +
" Course varchar(255),\n" +
" Join_date DATE\n" +
");";
try {
//JSqlParserでCREATE TABLE文を解析
Statement createTable = CCJSqlParserUtil.parse(createTableSql);
//テーブル名とデータベース名を取得
System.out.println("Table Name from query: " + ((CreateTable) createTable).getTable().getName());
System.out.println("Database Name from query: " + ((CreateTable) createTable).getTable().getSchemaName());
System.out.println("\nColumns in the given insert query");
System.out.println("---------------------------------\n");
for (ColumnDefinition col : ((CreateTable) createTable).getColumnDefinitions()) {
System.out.println(col.getColumnName() + " - " + col.getColDataType().toString());
}
//DB名とテーブル名を変更
((CreateTable) createTable).getTable().setSchemaName("College_db_bk");
((CreateTable) createTable).getTable().setName("Students_bkup");
//主キー制約の作成
NamedConstraint namedConstraint = new NamedConstraint();
namedConstraint.setType("PRIMARY KEY");
//主キーにカラム名を追加
List<Index.ColumnParams> columns = new ArrayList<>();
Index.ColumnParams columnParams = new Index.ColumnParams("Student_id");
columns.add(columnParams);
//主キー制約にカラムを設定
namedConstraint.setColumns(columns);
//インデックスリストに主キー制約を設定
List<Index> indexList = new ArrayList<>();
indexList.add(namedConstraint);
//CREATE TABLE文にインデックスを設定
((CreateTable) createTable).setIndexes(indexList);
System.out.println("New CREATE TABLE statement with Primary Key");
System.out.println("---------------------------------");
System.out.println(createTable + ";");
} catch (JSQLParserException e) {
throw new RuntimeException(e);
}
}
}
実行結果
以下のように、Student_id を主キーとした新しいCREATE TABLE文が生成されます。あわせて、データベース名とテーブル名も College_db_bk.Students_bkup に変更されていることが確認できます。
Adding Primary key in the CREATE TABLE statement
-------------------------------------
Table Name from query: Students
Database Name from query: College_db
Columns in the given insert query
---------------------------------
Student_id - int
Name - varchar (255)
Course - varchar (255)
Join_date - DATE
New CREATE TABLE statement with Primary Key
---------------------------------
CREATE TABLE College_db_bk.Students_bkup (Student_id int,
Name varchar (255),
Course varchar (255),
Join_date DATE,
PRIMARY KEY (Student_id));
関連記事
- Apache Hive パーサーの実装例
-
JavaFXアプリケーションの基本構造を解説!Stage・Scene・Nodesの役割と関係
一般的に、JavaFXアプリケーションは「Stage(ステージ)」「Scene(シーン)」「Nodes(ノード)」という3つの主要コンポーネントで構成されています。以下の図のように、それぞれが階層的に連携することでアプリケーションの画面が実現されます。Stage(ステージ)とはStageはウィンドウそのものを指し、JavaFXアプリケーションのすべてのオブジェクトを格納する最上位のコンテナです。Stageはパッケージjavafx.stageのStageクラスによって表現されます。なお、Stageの内容を画面に表示するには、show()メソッドを呼び出す必要があります。Scene Graph(シ
-
JavaでJTextAreaの切り取り・コピー・貼り付け機能を無効化する方法
JTextAreaとは JTextAreaはJTextComponentクラスのサブクラスであり、テキストを表示したりユーザーのテキスト入力を受け付けたりするための複数行テキストコンポーネントです。JTextAreaの機能を実装する際には、キャレット(カーソル)の移動などを監視するCaretListenerインターフェースを利用できます。 デフォルトでは、JTextAreaクラスは切り取り(カット)、コピー、貼り付け(ペースト)の各機能を標準でサポートしています。しかし、アプリケーションの要件によっては、これらの操作を禁止したいケースもあります。そのような場合は、JTextAreaクラスのge