Parser คือโปรแกรมที่เข้าใจไวยากรณ์ของลำดับคำ/ประโยค และสร้าง syntactical tree representation ใช้ในหลายด้าน เช่น programming languages, natural language processing, SQL ฯลฯ เพื่อสาธิตการใช้ Parser เราจะอ้างอิง open source JSqlParser ในบทช่วยสอนนี้
JSqlParser
JSqlParser เป็น SQL statement parser แบบ open source บน Github มัน parse SQL statement และแปลงเป็น hierarchy ของ Java classes ในตัวอย่างต่อไป เราจะ parse CREATE TABLE statement ด้วย JSqlParser มาเขียน Java program เพื่อ parse CREATE TABLE และเพิ่ม primary key กัน
CREATE TABLE Statement
CREATE TABLE College_db.Students (
Student_id int,
Name varchar(255),
Course varchar(255),
Join_date DATE
);
ใน CREATE TABLE statement ข้างต้น เราต้องการเพิ่ม Column Student_id เป็น Primary key
Java program สำหรับ parse CREATE TABLE SQL ด้วย JSqlParser
ขั้นตอนที่ 1: เพิ่ม JSqlParser เป็น dependency
เราสร้าง maven project เพื่อเพิ่ม JSqlParser เป็น dependency ใส่ dependency ด้านล่างใน pom.xml
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.2</version>
</dependency>
ขั้นตอนที่ 2: กำหนด input CREATE TABLE statement ให้ตัวแปร
นี่คือ input CREATE TABLE statement ที่ไม่มี primary key ตัวอักษร new line \n เป็น optional เราสามารถให้ SQL ทั้งหมดในบรรทัดเดียวได้ เพื่อ readability เราเขียนแบบ multi-line
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: Parse SQL ด้วย JSqlParser
ใช้ Parser util class CCJSqlParserUtil เรียกเมธอด parse ด้วย argument CREATE TABLE sql
Statement createTable = CCJSqlParserUtil.parse(createTableSql);
หลัง execute parse method Statement object createTable จะมี hierarchy ของ Java classes ดังภาพ
ขั้นตอนที่ 4: สำรวจ parser output
ถ้า parse method ทำงานสำเร็จ เราจะได้ข้อมูลทั้งหมดเกี่ยวกับ CREATE TABLE statement มาได้ database/table name และ column definitions พร้อมเปลี่ยน database และ table name ใน create table statement
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 และ table name
((CreateTable) createTable).getTable().setSchemaName("College_db_bk");
((CreateTable) createTable).getTable().setName("Students_bkup");
ขั้นตอนที่ 5: สร้าง primary key constraint เป็น index
เราสามารถตั้ง index ต่างๆ ให้ SQL ได้ เช่น Check constraint, Exclude constraint, Foreign key และ Named constraint สำหรับ primary key ต้องสร้าง Named constraint ดังนี้:
// Creating Primary Key constraint
NamedConstraint namedConstraint = new NamedConstraint();
namedConstraint.setType("PRIMARY KEY");
// Adding column names for the Primary Key
List<Index.ColumnParams> columns = new ArrayList<>();
Index.ColumnParams columnParams = new Index.ColumnParams("Student_id");
columns.add(columnParams);
// Setting columns in the Primary Key constraint
namedConstraint.setColumns(columns);
ตั้ง Primary key ของ Student_id เป็น Named constraint ใน index
// Setting the Primary Key constraint in Index list
List<Index> indexList = new ArrayList<>();
indexList.add(namedConstraint);
ขั้นตอนที่ 6: ตั้ง index ใน CREATE TABLE statement
เราต้องตั้ง index list ใน create table ดังนี้ เพื่อให้ CREATE table statement generate 出来时带有 Primary key
((CreateTable) createTable).setIndexes(indexList);
Java program เต็มรูปแบบสำหรับเพิ่ม primary key ใน CREATE TABLE SQL
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");
// Assign the input CREATE TABLE sql
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 {
// Parsing Create table statement using JSqlParser
Statement createTable = CCJSqlParserUtil.parse(createTableSql);
// Getting the table and database name from 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());
}
// Changing the DB and table name
((CreateTable) createTable).getTable().setSchemaName("College_db_bk");
((CreateTable) createTable).getTable().setName("Students_bkup");
// Creating Primary Key constraint
NamedConstraint namedConstraint = new NamedConstraint();
namedConstraint.setType("PRIMARY KEY");
// Adding column names for the Primary Key
List<Index.ColumnParams> columns = new ArrayList<>();
Index.ColumnParams columnParams = new Index.ColumnParams("Student_id");
columns.add(columnParams);
// Setting columns in the Primary Key constraint
namedConstraint.setColumns(columns);
// Setting the Primary Key constraint in Index list
List<Index> indexList = new ArrayList<>();
indexList.add(namedConstraint);
// Setting the indexes in Create table statement
((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);
}
}
}
Output
ตามที่แสดงด้านล่าง CREATE TABLE ใหม่ถูกสร้างพร้อม primary key ของ Student_id database และ table name เปลี่ยนเป็น 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 parser example