As the title says, this time I made an application that generates Java files of Entity class! It has been confirmed to work with OracleDB11g2R and MySQL.
Test.java
import java.util.ArrayList;
import annotation.Entity;
import annotation.Table;
import annotation.column;
import annotation.id;
@Entity
@Table("test")//The table name registered in the DB is displayed.
public class Test {
@id//Primary key
@column//column
private String num;
@column//column
private String namename;
public void setNum(String num) {
this.num = num;
}
public String getNum() {
return this.num;
}
public void setNamename(String namename) {
this.namename = namename;
}
public String getNamename() {
return this.namename;
}
}
name of the class | Description |
---|---|
EntityGenerator | A class that creates JavaFile and writes the contents of the file while calling the following class |
DBReader | Class that connects to DB and fetches metadata (table list, column name, primary key etc...) |
DataTypeMapper | Class that converts column data type to DB data type → java data type |
EntityInfo | Class to store the information acquired by DBReader |
annotation group | @Table, @Id, @column |
EntityGenerator
interface
EntityGenerator.java
package entityCreater.generator;
public interface EntityGenerator {
void generateEntity();
}
Implementation class
EntityGeneratorImplements.java
package entityCreater.generator;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import entityCreater.info.EntityInfo;
import entityCreater.reader.DBReaderImplements;
public class EntityGeneratorImplements implements EntityGenerator{
//Where to save the file
String filePlace;
/**
*constructor
*/
public EntityGeneratorImplements(String filePlace) {
this.filePlace = filePlace;
}
/**
*Entity creation method
*/
@Override
public void generateEntity() {
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Start EntityFile creation method");
ArrayList<EntityInfo> entityInfos = new DBReaderImplements().read();
for(EntityInfo ei : entityInfos) {
createFile(ei);
}
}
/**
*EntityFile creation method
* @param entityInfo
*/
private void createFile(EntityInfo entityInfo) {
//Get DB table information
String tableName = entityInfo.getTableName();
String id = entityInfo.getId();
List<String[]> columns = entityInfo.getColumns();
//Generate class name
String className = tableName.substring(0, 1).toUpperCase() + tableName.substring(1).toLowerCase();
//EntityFile class
File entityFile = new File(filePlace + "/" + className + ".java");
try{
if (entityFile.createNewFile()){
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("The file was created successfully.");
}else{
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Failed to create file");
}
}catch(IOException e){
System.out.println(e);
}
//Create the contents of File
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Create the contents of the file.");
try(PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter(entityFile, true)));) {
//Annotation import statement
pw.println("import annotation.Entity;");
pw.println("import annotation.Table;");
pw.println("import annotation.id;");
pw.println("import annotation.column;");
pw.println("");
//Class declaration(start)
pw.println("@Entity");
pw.println("@Table(\"" + tableName + "\")");
pw.println("public class " + className + " {");
pw.println("");
//Column declaration
Iterator<String[]> it = columns.iterator();
while(it.hasNext()) {
String[] colum = it.next();
//Column declaration
if(colum[1].equals(id)) {
pw.println(" @id");
}
pw.println(" @column");
pw.println(" private " + colum[0] + " " + colum[1] + ";");
pw.println("");
}
//Setter.Getter Declaration
//Put Iterator back
it = columns.iterator();
while(it.hasNext()) {
String[] colum = it.next();
//Setter declaration
pw.println(" public void set" + colum[1].substring(0, 1).toUpperCase() + colum[1].substring(1).toLowerCase() + "(" + colum[0] + " " + colum[1] + ") {");
pw.println(" this." + colum[1] + " = " + colum[1] + ";");
pw.println(" }");
pw.println("");
//Getter Declaration
pw.println(" public " + colum[0] + " get" + colum[1].substring(0, 1).toUpperCase() + colum[1].substring(1).toLowerCase() + "() {");
pw.println(" return this." + colum[1] + ";");
pw.println(" }");
pw.println("");
}
//Class declaration(End)
pw.println("}");
//End display
System.out.println(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("*************************************************************");
System.out.println("***Add the SUCCESS package declaration and multiplicity declaration.***");
System.out.println("*************************************************************");
} catch (IOException e) {
e.printStackTrace();
}finally {
}
}
}
DBReader interface
DBReader.java
package entityCreater.reader;
import java.util.ArrayList;
import entityCreater.info.EntityInfo;
public interface DBReader {
ArrayList<EntityInfo> read();
}
Implementation class
DBReaderImplements.java
package entityCreater.reader;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Iterator;
import container.DBConfig;
import container.EnvironmentConfigReader;
import db_access.DBAccess;
import entityCreater.dataTypeMapper.DataTypeMapper;
import entityCreater.info.EntityInfo;
public class DBReaderImplements implements DBReader{
@Override
public ArrayList<EntityInfo> read() {
//For storing metadata
ResultSet rs = null;
//For storing Table information
ArrayList<String> tableNames = new ArrayList<>();
//For storing Entity information
ArrayList<EntityInfo> entityInfos = new ArrayList<>();
//Get DB settings
/*
*Don't worry too much about the following ranges.
*Get the DB connection information (URL, PASSWORD, etc.) from your own yaml file,
*I'm just getting the Connection with the DB inside the DBAccess class.
*The source of EnvironmentConfigReader and DBAccess is described for reference.
*/
/*
*from here
*/
EnvironmentConfigReader ecr = new EnvironmentConfigReader();
DBConfig dbc = ecr.read();
String dbName = dbc.getDbName();
//Establishing a connection
DBAccess dba = new DBAccess(dbc);
/*
*So far
*/
try {
//Connection with database
Connection con = dba.getConnection();
//Get database metadata
DatabaseMetaData dbmd = con.getMetaData();
//Get Table name
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Get Table list");
String[] types = { "TABLE", "VIEW", "SYSTEM TABLE" };
rs = dbmd.getTables(dbName, null, "%", types);
while (rs.next()) {
String tableName = rs.getString("TABLE_NAME");
//Storage of Table name
tableNames.add(tableName);
}
//Classes for storing Table information
Iterator<String> tableNameList = tableNames.iterator();
String tableName;
String id = null;
ArrayList<String[]> columns;
while (tableNameList.hasNext()) {
//Get TableName
tableName = tableNameList.next();
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Table name:" + tableName + "Generate Entity class of");
//Get all column information of Table
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Table name:" + tableName + "Get all column information of");
rs = dbmd.getColumns(dbName, null, tableName, "%");
//For column storage
columns = new ArrayList<>();
while (rs.next()) {
//Convert from SQL data type to Java data type
String dataType = DataTypeMapper.dataTypeChange(rs.getString("TYPE_NAME"));
//Convert variable names to lowercase
String columnName = rs.getString("COLUMN_NAME").toLowerCase();
String[] column = { dataType, columnName };
columns.add(column);
}
//Get Primary Key
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Table name:" + tableName + "Get the Primary Key of");
ResultSet primaryKeys = dbmd.getPrimaryKeys(dbName, null, tableName);
if (primaryKeys.next()) {
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Table name:" + tableName + "Primary Key" + primaryKeys.getString("COLUMN_NAME") + "is");
id = primaryKeys.getString("COLUMN_NAME").toLowerCase();
}
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Table information is stored in EntityInfo class");
//Table information storage class
EntityInfo ei = new EntityInfo();
//Set TableName in the table information storage class
ei.setTableName(tableName);
//Set id in Table information storage class
ei.setId(id);
//Set column information in Table information storage class
ei.setColumns(columns);
entityInfos.add(ei);
}
rs.close();
//Database close
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Discard the connection with the DB");
con.close();
} catch (Exception e) {
System.out.println("Exception occurred");
e.printStackTrace();
}
return entityInfos;
}
}
DataTypeMapper
DataTypeMapper.java
package entityCreater.dataTypeMapper;
public class DataTypeMapper {
/**
*A class that converts SQL data types to Java data types
* @param sqlDataType
* @return
*/
public static String dataTypeChange(String sqlDataType) {
String javaDataType = null;
switch (sqlDataType) {
case "CHAR":
case "VARCHAR":
case "LONGVARCHAR":
javaDataType = "String";
break;
case "NUMERIC":
case "DECIMAL":
javaDataType = "java.math.BigDecimal";
break;
case "BIT":
javaDataType = "boolean";
break;
case "TINYINT":
javaDataType = "byte";
break;
case "SMALLINT":
javaDataType = "short";
break;
case "INTEGER":
case "INT":
javaDataType = "Integer";
break;
case "BIGINT":
javaDataType = "long";
break;
case "REAL":
javaDataType = "float";
break;
case "FLOAT":
case "DOUBLE":
javaDataType = "double";
break;
case "BINARY":
case "VARBINARY":
case "LONGVARBINARY":
javaDataType = "byte[]";
break;
case "DATE":
javaDataType = "java.sql.Date";
break;
case "TIME":
javaDataType = "java.sql.Time";
break;
case "TIMESTAMP":
javaDataType = "java.sql.Timestamp";
break;
default:
break;
}
return javaDataType;
}
}
EntityInfo
EntityInfo.java
package entityCreater.info;
import java.util.List;
/**
*
*Entity information storage class
* @author okamotoyuuma
*
*/
public class EntityInfo {
//table name
private String tableName;
//Primary Key name
private String id;
//All column names and types
private List<String[]> columns;
/**
* (non-javadoc)
* getter setter
* @return
*/
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<String[]> getColumns() {
return columns;
}
public void setColumns(List<String[]> columns) {
this.columns = columns;
}
}
@Table annotation (class that stores table name in attribute)
Table.java
package annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Target(TYPE)
@Retention(RUNTIME)
public @interface Table {
String value();
}
@id annotation (assigned to the primary key field)
id.java
package annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(FIELD)
public @interface id {
}
@columnn annotation (added to the column value of the table)
column.java
package annotation;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@Retention(RUNTIME)
@Target(FIELD)
public @interface column {
}
Create a Main method and specify the location to store the generated Entity class as shown below.
main.java
public class main {
public static void main(String[] args) {
EntityGenerator eg = new EntityGeneratorImplements("Destination path");
eg.generateEntity();
}
}
This time I tried to automatically generate the Entity class. The source and logic are still immature and childish, but it was a very good experience because I had never created a file! If you have any suggestions for points that have not been taken into consideration or improvements in the source, please leave a comment.
Since the DB setting file and the class to be read are listed in the following reference section, which are not listed in the above source. If you are interested, please take a look.
DB configuration file
DBProfile.yaml
#DB settings
!!container.DBConfig #DB definition setting class path
driver: com.mysql.cj.jdbc.Driver #driver name
url: jdbc:mysql://localhost:3306/DB name#DB URL
user:DB username#DB user
password: password #DB password
numberOfAccess: 10 #Number of connections
dbName:Database name#DB name
dbType: MySQL #DB type (only MySQL and Oracle DB are supported this time)
schema:Schema name
Class for storing setting information
DBConfig.java
package container;
//Database configuration file
public class DBConfig {
//Driver name
String driver;
//DB URL
String url;
//DB user
String user;
//password
String password;
//Schema name
String schema;
//Number of established connections
int numberOfAccess;
//DBName
String dbName;
//DBType
String dbType;
public String getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public int getNumberOfAccess() {
return numberOfAccess;
}
public void setNumberOfAccess(int numberOfAccess) {
this.numberOfAccess = numberOfAccess;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
}
EnvironmentConfigReader class that reads the above configuration file
EnvironmentConfigReader.java
package container;
import org.yaml.snakeyaml.Yaml;
public class EnvironmentConfigReader implements Reader<DBConfig>{
//DB configuration file
static String configFileName = "DBProfile.yaml";
//Method to get DB settings from yaml file(No arguments)
@Override
public DBConfig read() {
//Log generation location
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
//Processing content
System.out.println(configFileName + "Will start loading.");
Yaml yaml = new Yaml();
DBConfig dbc = (DBConfig) yaml.load(getClass().getResourceAsStream(configFileName));
//Log generation location
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
//Processing content
System.out.println(configFileName + "Has been loaded.");
return dbc;
}
//Method to get DB settings from yaml file(With arguments)
@Override
public DBConfig read(String setConfigFileName) {
//Log generation location
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
//Processing content
System.out.println(configFileName + "Will start loading.");
//Set the specified file name
if (configFileName != null) {
configFileName = setConfigFileName;
}
Yaml yaml = new Yaml();
DBConfig dbc = (DBConfig) yaml.load(getClass().getResourceAsStream(configFileName));
//Log generation location
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
//Processing content
System.out.println(configFileName + "Has been loaded.");
return dbc;
}
}
Class that stores the connection with DB
DBAccess.java
package db_access;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import container.DBConfig;
public class DBAccess {
//member
private Connection conn = null;
public DBAccess(DBConfig dbc) {
try {
Class.forName(dbc.getDriver());
conn = DriverManager.getConnection(dbc.getUrl(), dbc.getUser(), dbc.getPassword());
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Connected to DB");
//Auto commit OFF
conn.setAutoCommit(false);
} catch (SQLException | ClassNotFoundException e) {//Failed to establish connection
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Failed to connect to DB");
e.printStackTrace();
}
}
//Distribute the connection
public Connection getConnection() {
return conn;
}
//Break connection
public void closeConnection() {
try {
conn.close();
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Disconnected from DB");
} catch (SQLException e) {
//TODO auto-generated catch block
System.out.print(Thread.currentThread().getStackTrace()[1].getClassName() + ":");
System.out.println("Could not disconnect from DB");
e.printStackTrace();
}
}
}
Recommended Posts