フレームワークを作成するには、JavaアノテーションとJava Reflection APIを使用します。
それでは始めましょう。
いくつかのユースケースから始めましょう。
例1
特定のPersonクラスがあるとしましょう:
public static class Person { public String firstName; public String lastName; public int age; }
次の呼び出しは、このクラスに基づいてテーブルを作成するSQLクエリを生成します。
System.out.println(MySQLQueryGenerator.generateCreateTableQuery(Person.class));
実行すると、コンソールに次の出力が表示されます。
CREATE TABLE `Person_table` ( `firstName` VARCHAR(256), `lastName` VARCHAR(256), `age` INT);
例2
これで、注釈を使用した例はより複雑になります。
@IfNotExists // CREATE- IF NOT EXISTS @TableName("persons") // public static class Person { @AutoIncrement // AUTO_INCREMENT @PrimaryKey // PRIMARY KEY public int id; @NotNull // NOT NULL public long createTime; @NotNull public String firstName; @NotNull public String lastName; @Default("21") // public Integer age; @Default("") @MaxLength(1024) // VARCHAR public String address; @ColumnName("letter") // public Character someLetter; }
このクラスに基づいて、次のSQLクエリを取得します。
CREATE TABLE IF NOT EXISTS `persons` ( `id` INT AUTO_INCREMENT, `createTime` BIGINT NOT NULL, `firstName` VARCHAR(256) NOT NULL, `lastName` VARCHAR(256) NOT NULL, `age` INT DEFAULT '21', `address` VARCHAR(1024) DEFAULT '', `letter` VARCHAR(1), PRIMARY KEY (`id`));
例3
また、データベースサーバーに接続し、そこに生成されたSQLクエリを送信できるMySQLClientクラスも作成しました。
クライアントには、 createTable 、 alterTable 、 insert 、 update 、 selectのメソッドが含まれています 。
おおよそ次のように使用されます。
MySQLClient client = new MySQLClient("login", "password", "dbName"); client.connect(); // client.createTable(PersonV1.class); // client.alterTable(PersonV1.class, PersonV2.class); // PersonV2 person = new PersonV2(); person.createTime = new Date().getTime(); person.firstName = "Ivan"; person.lastName = "Ivanov"; client.insert(person); // person.age = 28; person.createTime = new Date().getTime(); person.address = "Zimbabve"; client.insert(person); person.createTime = new Date().getTime(); person.firstName = "John"; person.lastName = "Johnson"; person.someLetter = 'i'; client.insert(person); List selected = client.select(PersonV2.class); // System.out.println("Rows: " + selected.size()); for (Object obj: selected) { System.out.println(obj); } client.disconnect(); //
仕組み
最初に、アルゴリズムはReflection APIを使用して、クラスのすべてのパブリックフィールドと非静的フィールドを反復処理します。 この場合のフィールドがアルゴリズムでサポートされている型(すべてのプリミティブデータ型、オブジェクト類似体、String型がサポートされている)の場合、データベースオブジェクトフィールドに関するデータを含むColumnオブジェクトがFieldオブジェクトから作成されます。 Javaデータ型とMySQL型の間の変換は自動的に行われます。 また、フィールドとクラスの注釈から、テーブルとそのフィールドのすべての修飾子が抽出されます。 次に、すべてのColumnからSQLクエリが形成されます。
public static String generateCreateTableQuery(Class clazz) throws MoreThanOnePrimaryKeyException { List<Column> columnList = new ArrayList<>(); Field[] fields = clazz.getFields(); // for (Field field: fields) { int modifiers = field.getModifiers(); if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers)) { // public static Column column = Column.fromField(field); // Field Column if (column!=null) columnList.add(column); } } /* Column */ } /***************************/ public static Column fromField(Field field) { Class fieldType = field.getType(); // ColumnType columnType; if (fieldType == boolean.class || fieldType == Boolean.class) { columnType = ColumnType.BOOL; } /* */ { } else if (fieldType==String.class) { columnType = ColumnType.VARCHAR; } else { // return null; } Column column = new Column(); column.columnType = columnType; column.name = field.getName(); column.isAutoIncrement = field.isAnnotationPresent(AutoIncrement.class); /* */ if (field.isAnnotationPresent(ColumnName.class)) { // ColumnName columnName = (ColumnName)field.getAnnotation(ColumnName.class); String name = columnName.value(); if (!name.trim().isEmpty()) column.name = name; } return column; }
同様に、ALTER TABLE、INSERT、およびUPDATEクエリが生成されます。 後者の2つの場合、列リストに加えて、そのフィールドの値もオブジェクトから抽出されます。
Column column = Column.fromField(field); if (column!=null) { if (column.isAutoIncrement) continue; Object value = field.get(obj); if (value==null && column.hasDefaultValue) continue; // : if (column.isNotNull && value==null) { throw new NotNullColumnHasNullValueException(); } String valueString = value!=null ? "'" + value.toString().replace("'","\\'") + "'" : "NULL"; String setValueString = "`"+column.name+"`="+valueString; valueStringList.add(setValueString); }
フレームワークにはResultSetExtractorクラスもあり、そのメソッドであるextractResultSet(ResultSet resultSet、Class clazz)は、resultSetからclazzクラスのオブジェクトのリストを自動的に作成します。 これは非常に簡単に行われるため、ここではその動作の原理について説明しません。
github では、フレームワークの完全なソースコードを見ることができます。 これで私はすべてを持っています。