Principle Analysis of Code Generator

Principle Analysis of Code Generator

Understand the requirements and implementation ideas of code generators and master the use of freemaker

Understand the metadata in the database to complete the environment construction work

Talking about Code Generator

overview

In the process of project development, the focus is more on the development of business functions and ensuring the correctness of business processes. Writing repetitive codes takes up a lot of time and energy for programmers, and these codes are often regular . Just like the structure of controller, service, serviceImpl, dao, daoImpl, model, jsp, modules such as users, roles, permissions, etc. have similar structures. For this part of the code, we can use a code generator to let the computer automatically generate code for us, freeing our hands and reducing manual repetitive labor.

The traditional way for programmers to develop modules is as follows:

  • Create database tables
  • Design entity classes based on table fields
  • Write CRUD
  • Write the service layer according to the business
  • Web layer code and front page

Usually you only need to know the structure of a table, the code format of the front and back pages for addition, deletion, modification and query is fixed, and the rest is complicated business. The goal of the code generation tool is to automatically generate that part of the fixed-format CRUD code

demand analysis

In our code generator, code is automatically generated based on public templates and information in database tables.

For development without the help of code generation tools, programmers usually copy and modify the code based on an already written code. According to the needs of different business database tables, this code can be called a public code template. .

The generated code is closely related to the information in the database table, so in addition to the template, the database table information is also required as data to fill the template content

Implementation ideas

There are many implementations of code generators. Let's take the example of generating corresponding codes from the mysql database table structure to illustrate how to implement a code generator. There are the following key points:

  • Database and table parsing for generating models and other codes

Obtain the table name, table fields and other attributes in the database through database analysis : the entity class name can be determined according to the table name, and the attributes in the entity class can be determined according to the fields (for example: the entity class corresponding to the tb_user table is User)

  • Template development generates code files

The template defines the common basic code and the placeholder content that needs to be replaced (for example: ${tableName} will eventually be replaced with User according to the database table), and the data is replaced according to the parsed database information and a code file is generated

  • Template code extraction of the basic framework

Through the analysis of ideas, it is not difficult to find that for code generation tools, only database analysis and template development need to be done. Then the automatic code generation is not so mysterious and complicated. Then complete your own code generator.

Sao Dai understands: the code generator is mainly composed of two parts, metadata + template, metadata usually refers to the table name, field, etc. of the database, the template is some public code that needs a template, and then replace the metadata into the template Can generate code

Deep into FreeMarker

What is FreeMarker

FreeMarker is a template engine: a general-purpose tool for generating output text (any text from HTML format used to automatically generate source code) based on templates. It is a development kit or class library for Java programmers. It is not intended for end users, but an application for programmers that can be embedded in the products they develop.

FreeMarker is actually designed to be used to generate HTML web pages, especially through Servlet applications based on the implementation of the MVC (ModelView Controller, Model-View-Controller) pattern. The idea of ​​dynamic web pages using the MVC pattern allows you to separate the front-end designers (who write HTML) from the programmers. Everyone performs their duties and plays their best side. Web designers can rewrite the display effect of the page without being affected by the programmer's compiled code, because the logic of the application (Java program) and page design (FreeMarker template) have been separated. Page template code is not affected by complex program code. This idea of ​​separation is very useful even for a project where the programmer and page designer are the same person, because the separation keeps the code clean and easy to maintain.

Although FreeMarker also has programming capabilities, it is not a comprehensive programming language like PHP. Instead, Java programs prepare data for display (eg SQL queries), and FreeMarker simply uses templates to generate text pages to present the prepared data

FreeMarker is not a web application framework. It is a suitable component in the web application framework, but the FreeMarker engine itself does not know the HTTP protocol or Servlets. It's just for generating text. Even so, it is well suited for development in non-web application environments

Application scenarios of Freemarker

dynamic page

Generate page files based on template configuration and expressions, which can be accessed by clients like jsp

page static

For applications in the system that frequently use databases for queries but have little content updates, FreeMarker can be used to staticize web pages, thus avoiding a large number of database access requests and improving website performance

Code generator

Can automatically generate pages or codes according to the background configuration

Features and highlights of freemarker

  • Powerful template language: conditional blocks, iteration, assignment, string and arithmetic operations and formatting, macros and functions, encoding and more;
  • Multi-purpose and lightweight: zero dependencies, output in any format, templates can be loaded from anywhere (pluggable), rich in configuration options;
  • Smart Internationalization and Localization: Sensitive to locale and date/time formats.
  • XML processing functions: put dom-s into XML data models and traverse them, even process their declarations
  • Generic data model: Java objects are exposed to templates as variable trees through pluggable adapters.

Basic use of Freemarker

Tectonic environment

Create maven project codeutil and introduce response coordinates

    <dependencies>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.20</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
    </dependencies>

Getting Started Case

  • Create template template.ftl

Welcome: ${username}

  • Use freemarker to complete the operation
package cn.itcast.freemarker.test;

import freemarker.cache.FileTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.junit.Test;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 第一个FreeMarker程序(数据+模板=文件输出)
 *      1.操作步骤
 */
public class FreeMarkerTest01 {

    @Test
    public void test01() throws Exception {
        //1.创建FreeMarker的配置类
        Configuration cfg = new Configuration();
        //2.指定模板加载器:将模板存入缓存中
        //文件路径加载器
        FileTemplateLoader ftl = new FileTemplateLoader(new File("templates"));
        cfg.setTemplateLoader(ftl);
        //3.获取模板
        Template template = cfg.getTemplate("template01.ftl");
        //4.构造数据模型
        Map<String,Object> dataModel = new HashMap<>();

        //

        //user对象
        dataModel.put("username","ZHangsan");
        dataModel.put("flag",3);

        List<String> list = new ArrayList<>();
        list.add("星期一");
        list.add("星期二");
        list.add("星期三");
        list.add("星期四");

        dataModel.put("weeks",list);

        //5.文件输出
        /**
         * 处理模型
         *      参数一:数据模型
         *      参数二:writer(FileWriter(文件输出),printWriter(控制台输出))
         */
        //template.process(dataModel,new FileWriter(new File("C:\\Users\\ThinkPad\\Desktop\\ihrm\\day12\\test\\a.txt")));
        template.process(dataModel,new PrintWriter(System.out));
    }
}

Sao Dai understands: FileTemplateLoader ftl = new FileTemplateLoader(new File("templates")); This refers to loading all files from the templates file in the project code, for example, template.ftl here is under the templates file, cfg .setTemplateLoader(ftl); is to set the template loader. There are many kinds of template loaders. The following are the template loaders available in FreeMarker and their meanings:

1. FileTemplateLoader: Load templates from the file system. You need to specify the directory where the template files are located.

2. ClassTemplateLoader: Load templates from the class path. You need to specify the package name where the template file is located.

3. ServletContextTemplateLoader: Loads templates from the context of the web application. The relative path where the template file is located needs to be specified.

4. StringTemplateLoader: Load templates from strings. Template content can be passed directly to the template loader.

5. MultiTemplateLoader: Multiple template loaders can be combined to load templates from multiple sources.

6. TemplateLoader: This is an abstract class that can be inherited from it to implement a custom template loader.

string template

package cn.itcast.freemarker.test;

import freemarker.cache.StringTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.junit.Test;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.util.HashMap;
import java.util.Map;

/**
 * 测试字符串模板
 *
 *
 */
public class FreeMarkerTest02 {

    /**
     *  com.${p1}.${p1}.${p1}.User
     *
     */
    @Test
    public void test() throws Exception {
        //1.创建配置对象
        Configuration cfg = new Configuration();
        //2.指定加载器
        cfg.setTemplateLoader(new StringTemplateLoader());
        //3.创建字符串模板
        // i.字符串
        String templateString = "欢迎您:${username}";
        // ii.通过字符串创建模板
        Template template = new Template("name1",new StringReader(templateString),cfg);
        //4.构造数据
        Map<String,Object> dataModel = new HashMap<>();
        dataModel.put("username","张三");
        //5.处理模板
        template.process(dataModel,new PrintWriter(System.out));
    }
}

Sao Dai understands: Template template = new Template("name1",new StringReader(templateString),cfg); The meanings of the three parameters are:

  • "name1" - The name of the template, typically used for debugging and error reporting. name is optional, so it can also be null.
  • new StringReader(templateString) - This is a StringReader object used to pass the template string to the FreeMarker engine. StringReader provides the read() method for reading a string character by character.
  • cfg - the configuration object, usually an instance of the Configuration class. It provides various settings and options of the FreeMarker engine, including template caching, encoding, instruction syntax, etc.

Freemarker Templates

overview

The FreeMarker template file mainly consists of 5 parts:

  • Data model: all the data that the template can use
  • text, part of direct output
  • Comments, i.e. <#--...--> format will not be output
  • Interpolation: The part in the format of ${..} or #{..} will use the part in the data model to replace the output
  • FTL command: FreeMarker command, similar to HTML markup, with # in front of the name to distinguish it, and it will not be output.

data model

FreeMarker (and template developers) don't care how the data is calculated, FreeMarker just knows what the actual data is. All data available to the template is packaged into a data-model data model

Sao Dai understands: For example, ${user} can get the value whose key is user in root. ${lastestProduct.url} can get the url attribute whose member variable is lastestProduct

Common tags for templates

The following specific sections can be included in a FreeMarker template:

1. ${...}: called interpolations, FreeMarker will replace it with the actual value when outputting.

    • ${name} can get the value whose key is name in root.
    • ${person.name} can obtain the name attribute whose member variable is person

2. <#…>: FTL tags (FreeMarker template language tags): similar to HTML tags, in order to distinguish them from HTML tags

3. <@>: macro, custom tag

4. Comments: included between <#-- and --> (instead of)

Common directives for templates

if instruction

branch control statement

<#if 条件>
    ....
    <#elseif 条件>
        ...
    <#elseif 条件>      
        ...
    <#else>
        ...
</#if>

give a chestnut

<#if flag=1>
    传入数据=1
    <#elseif flag=2>
    传入数据=2
    <#else>
    传入数据=其他
</#if>
package cn.itcast.freemarker.test;

import freemarker.cache.FileTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.junit.Test;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 第一个FreeMarker程序(数据+模板=文件输出)
 *      1.操作步骤
 */
public class FreeMarkerTest01 {

    @Test
    public void test01() throws Exception {
        //1.创建FreeMarker的配置类
        Configuration cfg = new Configuration();
        //2.指定模板加载器:将模板存入缓存中
        //文件路径加载器
        FileTemplateLoader ftl = new FileTemplateLoader(new File("templates"));
        cfg.setTemplateLoader(ftl);
        //3.获取模板
        Template template = cfg.getTemplate("template01.ftl");
        //4.构造数据模型
        Map<String,Object> dataModel = new HashMap<>();

        //

        //user对象
        dataModel.put("flag",3);

        //5.文件输出
        /**
         * 处理模型
         *      参数一:数据模型
         *      参数二:writer(FileWriter(文件输出),printWriter(控制台输出))
         */
        //template.process(dataModel,new FileWriter(new File("C:\\Users\\ThinkPad\\Desktop\\ihrm\\day12\\test\\a.txt")));
        template.process(dataModel,new PrintWriter(System.out));
    }
}

list, break command

The list command is a typical iterative output command, which is used to iteratively output the collection in the data model

<#list weeks as abc>
    ${abc_index} =  ${abc}
</#list>
package cn.itcast.freemarker.test;

import freemarker.cache.FileTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.junit.Test;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 第一个FreeMarker程序(数据+模板=文件输出)
 *      1.操作步骤
 */
public class FreeMarkerTest01 {

    @Test
    public void test01() throws Exception {
        //1.创建FreeMarker的配置类
        Configuration cfg = new Configuration();
        //2.指定模板加载器:将模板存入缓存中
        //文件路径加载器
        FileTemplateLoader ftl = new FileTemplateLoader(new File("templates"));
        cfg.setTemplateLoader(ftl);
        //3.获取模板
        Template template = cfg.getTemplate("template01.ftl");
        //4.构造数据模型
        Map<String,Object> dataModel = new HashMap<>();

        //

        //user对象
        dataModel.put("username","ZHangsan");
        dataModel.put("flag",3);

        List<String> list = new ArrayList<>();
        list.add("星期一");
        list.add("星期二");
        list.add("星期三");
        list.add("星期四");

        dataModel.put("weeks",list);

        //5.文件输出
        /**
         * 处理模型
         *      参数一:数据模型
         *      参数二:writer(FileWriter(文件输出),printWriter(控制台输出))
         */
        //template.process(dataModel,new FileWriter(new File("C:\\Users\\ThinkPad\\Desktop\\ihrm\\day12\\test\\a.txt")));
        template.process(dataModel,new PrintWriter(System.out));
    }
}

In addition, when iterating collection objects, it also includes two special loop variables: the alias of item

a. item_index: the index value of the current variable.

b. item_has_next: Whether there is a next object

You can also use the <#break> directive to break out of the iteration

<#list ["星期一","星期二","星期三","星期四","星期五"] as x>
    ${x_index +1}.${x} <#if x_has_next>,</#if>
    <#if x = "星期四"><#break></#if>
</#list>

Sao Dai's understanding: Note that the x_index subscript starts from 0! So the execution result is

1.Monday, 2.Tuesday, 3.Wednesday, 4.Thursday

include directive

The function of the include instruction is similar to that of JSP, which is used to include the specified page. The syntax format of the include instruction is as follows

<#include filename [options]></#include>

举个栗子
<#--模板包含 include-->
<#include "template02.ftl" >

In the syntax format above, the two parameters are explained as follows

a. filename: This parameter specifies the included template file

b. options: This parameter can be omitted, specify the option when including, including encoding and parse two options, encoding specifies the encoding set used when including the page, and parse specifies whether the included page should be parsed as an FTL file. If the parse option value is omitted, the option value defaults to true

assign command

It is used to create or replace a top-level variable for this template page

<#-- assign指令 : 再ftl模板中定义数据存入到root节点下-->
<#assign name="zhangsan">

${name}

Sao Dai understands: the assign command is actually to define a variable, and then you can directly use this variable in the ftl file, for example, the variable name=zhangsan defined above, you can directly use ${name} below

built-in function

FreeMarker also provides some built-in functions to convert the output. Any variable can be followed by ?,? followed by a built-in function, and the output variable can be converted by the built-in function. The following are commonly used built-in string functions:

 ?html:html字符转义
 ?cap_first: 字符串的第一个字母变为大写形式
 ?lower_case :字符串的小写形式
 ?upper_case :字符串的大写形式
 ?trim:去掉字符串首尾的空格
 ?substring:截字符串
 ?lenth: 取长度
 ?size: 序列中元素的个数
 ?int : 数字的整数部分(比如- 1.9?int 就是- 1)
 ?replace:字符串替换

give a chestnut

${username?lower_case}

Sao Dai’s understanding: The method of use is to add ?lower_case directly, and he will change the username passed in the java code into lowercase, for example, Zhan will become zhan

database metadata

metadata in the database

What is Data Metadata?

Metadata (MetaData) refers to the data that defines the data structure. Then database metadata refers to the data that defines the structure of various objects in the database. For example, the database name in the database indicates that column names, user names, version names, and most strings in the results obtained from SQL statements are metadata

The role of database metadata

Take advantage of database metadata in application design

It will be easier to understand the implementation principles of data access related frameworks after a deep understanding of the database organizational structure.

How to get metadata

There are three main interfaces for using JDBC to process databases in front of us, namely Connection, PreparedStatement and ResultSet. For these three interfaces, different types of metadata can also be obtained, and some database information can be obtained through these metadata classes. . The following will introduce the three types of metadata objects and use the MYSQL database to illustrate the cases

database metadata

overview

Database metadata (DatabaseMetaData): obtained by the Connection object through the getMetaData method, mainly encapsulates some overall comprehensive information about the database itself, such as the product name of the database, the version number of the database, the URL of the database, whether it supports transactions, etc. wait.

Here are some commonly used methods on DatabaseMetaData:

  • getDatabaseProductName: Get the product name of the database
  • getDatabaseProductName: Get the version number of the database
  • getUserName: Get the user name of the database
  • getURL: Get the URL of the database connection
  • getDriverName: Get the driver name of the database
  • driverVersion: Get the driver version number of the database
  • isReadOnly: Check whether the database only allows read operations
  • supportsTransactions: Check whether the database supports transactions

Sao Dai's understanding: Generally speaking, the metadata of the database is divided into four major blocks

  • Basic database information: such as user name, version number, driver version number, whether it supports transactions or not. [This database refers to the Mysql software installed on the computer, which is a database software. There are many database databases in this software]
  • All database database names: Get all database names [this database refers to all database names]
  • All table information of a database: get all table information of a specified database database, that is, all kinds of information of all tables in that database can be obtained
  • All column information of a certain table: Get all the column information of a specified table of a specified database database

Getting Started Case

build environment

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.6</version>
</dependency>

Get basic database information

/**
 * 测试数据库元数据
 */
public class DataBaseMetaDataTest {

    private Connection connection;

    @Before
    public void init() throws Exception {

        String driver ="com.mysql.jdbc.Driver";
        String url="jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8";
        //String url="jdbc:mysql://127.0.0.1:3306/ihrm?useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="111111";

        Properties props = new Properties();
        props.put("remarksReporting","true");//获取数据库的备注信息
        props.put("user",username);
        props.put("password",password);

        //1.获取连接
        Class.forName(driver);//注册驱动
        connection = DriverManager.getConnection(url,props);
    }

    //获取数据库基本信息
    @Test
    public void test01() throws Exception {
        //2.获取元数据
        DatabaseMetaData metaData = connection.getMetaData();

        //3.获取数据库基本信息
        System.out.println(metaData.getUserName());

        System.out.println(metaData.supportsTransactions());//是否支持事务

        System.out.println(metaData.getDatabaseProductName());
    }
}

Sao Dai understands: DatabaseMetaData can be obtained directly through connection.getMetaData();, and then the API interface is called according to the requirements. The following are some common methods about DatabaseMetaData:

  • getDatabaseProductName: Get the product name of the database
  • getDatabaseProductName: Get the version number of the database
  • getUserName: Get the user name of the database
  • getURL: Get the URL of the database connection
  • getDriverName: Get the driver name of the database
  • driverVersion: Get the driver version number of the database
  • isReadOnly: Check whether the database only allows read operations
  • supportsTransactions: Check whether the database supports transactions

Get database list

/**
 * 测试数据库元数据
 */
public class DataBaseMetaDataTest {

    private Connection connection;

    @Before
    public void init() throws Exception {

        String driver ="com.mysql.jdbc.Driver";
        String url="jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8";
        //String url="jdbc:mysql://127.0.0.1:3306/ihrm?useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="111111";

        Properties props = new Properties();
        props.put("remarksReporting","true");//获取数据库的备注信息
        props.put("user",username);
        props.put("password",password);

        //1.获取连接
        Class.forName(driver);//注册驱动
        connection = DriverManager.getConnection(url,props);
    }

    //获取数据库列表
    @Test
    public void test02() throws SQLException {
        //1.获取元数据
        DatabaseMetaData metaData = connection.getMetaData();
        //2.获取所有数据库列表
        ResultSet rs = metaData.getCatalogs();
        while (rs.next()) {
            System.out.println(rs.getString(1));
        }
        rs.close();
        connection.close();
    }
}

Sao Dai understands: rs.getString(1) means to get the value of the first column of the current row in the ResultSet and return it in the form of a string. Returns null if the value of the first column is null. In ResultSet, the column number starts from 1 and increases in sequence. Here, the ResultSet obtained through ResultSet rs = metaData.getCatalogs(); has only one field, so the name of the database database is obtained through rs.getString(1)

Get table information in the specified database

/**
 * 测试数据库元数据
 */
public class DataBaseMetaDataTest {

    private Connection connection;

    @Before
    public void init() throws Exception {

        String driver ="com.mysql.jdbc.Driver";
        String url="jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8";
        //String url="jdbc:mysql://127.0.0.1:3306/ihrm?useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="111111";

        Properties props = new Properties();
        props.put("remarksReporting","true");//获取数据库的备注信息
        props.put("user",username);
        props.put("password",password);

        //1.获取连接
        Class.forName(driver);//注册驱动
        connection = DriverManager.getConnection(url,props);
    }

    //获取指定数据库中的表信息
    @Test
    public void test03() throws Exception {
        //1.获取元数据
        DatabaseMetaData metaData = connection.getMetaData();

        //2.获取数据库中表信息
        /**
         * String catalog, String schemaPattern,String tableNamePattern, String types[]
         *
         *  catalog:当前操作的数据库
         *      mysql:
         *          :ihrm
         *          catalog
         *      oralce:
         *          xxx:1521:orcl
         *          catalog
         *   schema:
         *      mysql:
         *          :null
         *      oracle:
         *          :用户名(大写)
         *
         *    tableNamePattern:
         *      null:查询所有表
         *      为空:查询目标表
         *
         *    types:类型
         *      TABLE:表
         *      VIEW:视图
         *
         */
        ResultSet rs = metaData.getTables(null, null, null, new String[]{"TABLE"});


        while (rs.next()) {
            System.out.println(rs.getString("TABLE_NAME"));
        }
    }
}

Sao Dai understands: In JDBC, the DatabaseMetaData interface provides a set of methods for obtaining metadata information of the database, such as tables, columns, indexes and other information in the database. Among them, the getTables() method is used to obtain all table information in the database, and its method signature is as follows:

ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException;

This method accepts four parameters with the following meanings:

  • catalog: Specify the catalog name to filter the returned result set. If it is null, all catalog table information will be returned.
  • schemaPattern: Specifies the schema name pattern for filtering the returned result set. If it is null, table information of all schemas will be returned.
  • tableNamePattern: Specifies the table name pattern used to filter the returned result set. If null, returns all table information.
  • types: Specify the table type to return, such as TABLE, VIEW, etc. If null, returns information for all table types.

In this example, we call the getTables() method and pass in four parameters. The first parameter is null, which means returning the table information of all catalogs; the second parameter is null, which means returning the table information of all schemas; The third parameter is null, which means to return all table information; the fourth parameter is new String[]{"TABLE"}, which means to return only the information of table type TABLE, that is, to exclude other types of objects, such as VIEW, SYSTEM TABLE wait. Therefore, the ResultSet returned by calling this method only contains the table information of the table type TABLE.

knowledge expansion

(1) What does the schema of mysql mean?

In MySQL, schema refers to the namespace of database objects, which is used to group database objects (such as tables, views, stored procedures, etc.) for easy management and authorization. In MySQL, a schema can contain multiple tables, views, stored procedures and other objects, and an object can only belong to one schema.

In MySQL, a schema is usually equivalent to a database, that is, a schema corresponds to a database. Therefore, in MySQL, we can use the CREATE SCHEMA statement to create a new schema, for example:

CREATE SCHEMA mydatabase;

In this example, we create a new schema called mydatabase that will be used as a new database. You can switch to this schema with the USE statement, for example:

USE mydatabase;

In this example, we switch to the schema mydatabase in order to create new objects such as tables, views, and stored procedures in the schema.

(2) What does the catalog of mysql mean?

In MySQL, catalog refers to the metadata information of the database, including database name, table name, column name and other information. In MySQL, a catalog can contain multiple schemas, and a schema can contain multiple tables, views, stored procedures, and other objects.

In MySQL, a catalog is usually equivalent to a database, that is, a catalog corresponds to a database. Therefore, when using JDBC to connect to a MySQL database, you can use the name of the database as the catalog name, for example:

String url = "jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=UTC";
Connection conn = DriverManager.getConnection(url, "username", "password");

Sao Dai’s understanding: Simply put, schema refers to the database database, and catalog refers to the metadata

Get the field information in the specified table

/**
 * 测试数据库元数据
 */
public class DataBaseMetaDataTest {

    private Connection connection;

    @Before
    public void init() throws Exception {

        String driver ="com.mysql.jdbc.Driver";
        String url="jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8";
        //String url="jdbc:mysql://127.0.0.1:3306/ihrm?useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="111111";

        Properties props = new Properties();
        props.put("remarksReporting","true");//获取数据库的备注信息
        props.put("user",username);
        props.put("password",password);

        //1.获取连接
        Class.forName(driver);//注册驱动
        connection = DriverManager.getConnection(url,props);
    }
    //获取指定表中的字段信息
    @Test
    public void test04() throws Exception {
        DatabaseMetaData metaData = connection.getMetaData();

        //获取表中的字段信息
        /**
         *  catalog
         *  schema
         *  tableName
         *  columnName
         */
        ResultSet rs = metaData.getColumns(null, null, "bs_user", null);

        while (rs.next()) {
            System.out.println(rs.getString("COLUMN_NAME"));
        }
    }
}

Sao Dai understands: In JDBC, the DatabaseMetaData interface provides a set of methods for obtaining metadata information of the database, such as tables, columns, indexes and other information in the database. Among them, the getColumns() method is used to obtain all column information of the specified table, and its method signature is as follows:

ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException;

This method accepts four parameters with the following meanings:

  • catalog: Specify the catalog name to filter the returned result set. If it is null, all catalog column information will be returned.
  • schemaPattern: Specifies the schema name pattern for filtering the returned result set. If it is null, all schema column information will be returned.
  • tableNamePattern: Specifies the table name pattern used to filter the returned result set. If null, column information for all tables is returned.
  • columnNamePattern: Specifies the column name pattern used to filter the returned result set. If null, returns all column information.

In this example, we call the getColumns() method and pass in four parameters. The first parameter is null, which means returning the column information of all catalogs; the second parameter is null, which means returning the column information of all schemas; The third parameter is "bs_user", which means to return the column information of the table named "bs_user"; the fourth parameter is null, which means to return the information of all columns in the table. Therefore, the ResultSet returned by calling this method only contains all the column information of the "bs_user" table. We can traverse all column information in ResultSet through the following code:

ResultSet rs = metaData.getColumns(null, null, "bs_user", null);
while (rs.next()) {
    String columnName = rs.getString("COLUMN_NAME");
    String columnType = rs.getString("TYPE_NAME");
    int columnSize = rs.getInt("COLUMN_SIZE");
    System.out.println(columnName + " " + columnType + "(" + columnSize + ")");
}

In this example, we use a while loop to traverse all the rows in the ResultSet, get the column name, column type and column size of the current row each time, and print the output. It should be noted that the field name corresponding to the column name in the ResultSet is "COLUMN_NAME", the field name corresponding to the column type is "TYPE_NAME", and the field name corresponding to the column size is "COLUMN_SIZE".

parameter metadata

Parameter Metadata (ParameterMetaData): It is obtained by the PreparedStatement object through the getParameterMetaData method, mainly to provide some information for the PreparedStatement object and its precompiled SQL command statement. ParameterMetaData can provide the number of placeholder parameters, and obtain the specified position bit SQL type etc.

Here are some commonly used methods on ParameterMetaData:

getParameterCount: Get the number of placeholder parameters in the precompiled SQL statement

  /**
 * 测试数据库元数据
 */
public class DataBaseMetaDataTest {

    private Connection connection;

    @Before
    public void init() throws Exception {

        String driver ="com.mysql.jdbc.Driver";
        String url="jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8";
        //String url="jdbc:mysql://127.0.0.1:3306/ihrm?useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="111111";

        Properties props = new Properties();
        props.put("remarksReporting","true");//获取数据库的备注信息
        props.put("user",username);
        props.put("password",password);

        //1.获取连接
        Class.forName(driver);//注册驱动
        connection = DriverManager.getConnection(url,props);
    }

  @Test
    public void test() throws Exception {
        String sql = "select * from bs_user where id=?";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, "1063705482939731968");
        //获取ParameterMetaData对象
        ParameterMetaData paramMetaData = pstmt.getParameterMetaData();
        //获取参数个数
        int paramCount = paramMetaData.getParameterCount();
        System.out.println(paramCount);
   }
}


Sao Dai understands: This ParameterMetaData actually has many methods, but only the getParameterCount method is accurate

result set metadata

Result set metadata (ResultSetMetaData): obtained by the ResultSet object through the getMetaData method, mainly for some information provided in the result set object ResultSet obtained by the SQL script command executed by the database, such as the number of columns in the result set and the specified column The name, the SQL type of the specified column, etc., it can be said that this is a very important object for the framework.

Here are some commonly used methods on ResultSetMetaData:

  • getColumnCount: Get the number of columns in the result set
  • getColumnType: Get the SQL type of the specified column corresponding to the field of the Types class in Java
  • getColumnTypeName: Get the SQL type of the specified column
  • getClassName: Get the specified column SQL type corresponding to the type in Java (package name plus class name)
  /**
 * 测试数据库元数据
 */
public class DataBaseMetaDataTest {

    private Connection connection;

    @Before
    public void init() throws Exception {

        String driver ="com.mysql.jdbc.Driver";
        String url="jdbc:mysql://127.0.0.1:3306?useUnicode=true&characterEncoding=utf8";
        //String url="jdbc:mysql://127.0.0.1:3306/ihrm?useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="111111";

        Properties props = new Properties();
        props.put("remarksReporting","true");//获取数据库的备注信息
        props.put("user",username);
        props.put("password",password);

        //1.获取连接
        Class.forName(driver);//注册驱动
        connection = DriverManager.getConnection(url,props);
    }

     @Test
    public void test() throws Exception {
        String sql = "select * from bs_user where id=?";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, "1063705482939731968");
        //执行sql语句
        ResultSet rs = pstmt.executeQuery() ;
        //获取ResultSetMetaData对象
        ResultSetMetaData metaData = rs.getMetaData();
        //获取查询字段数量
        int columnCount = metaData.getColumnCount() ;
        for (int i=1;i<=columnCount;i++) {
            //获取表名称
            String columnName = metaData.getColumnName(i);
            //获取java类型
            String columnClassName = metaData.getColumnClassName(i);
            //获取sql类型
            String columnTypeName = metaData.getColumnTypeName(i);
            System.out.println(columnName);
            System.out.println(columnClassName);
            System.out.println(columnTypeName);
       }
        System.out.println(columnCount);
   }
}

    

   

Code generator build environment

Idea analysis

The execution logic of the tool is shown in the figure below:

As analyzed above, it is known that the completion of the code generator requires the following operations:

  • The database information and project construction information filled in by the user need to be constructed into entity class objects for easy operation
  • Database table information, database field information needs to be constructed into entity classes
  • Construct the Freemarker data model, and store the database table objects and basic configuration in the Map collection
  • Code generation with Freemarker
  • Customize public code templates

build environment

configuration coordinates

    <dependencies>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.20</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
    </dependencies>

Configure entity class

  • The database configuration obtained by the UI page is encapsulated into the database entity class
package cn.itcast.generate.entity.db;



//数据库实体类
public class DataBase {

    private static String mysqlUrl = "jdbc:mysql://[ip]:[port]/[db]?useUnicode=true&amp;characterEncoding=UTF8";
    private static String oracleUrl = "jdbc:oracle:thin:@[ip]:[port]:[db]";

    private String dbType;//数据库类型
    private String driver;
    private String userName;
    private String passWord;
    private String url;

    public DataBase() {}

    public DataBase(String dbType) {
        this(dbType,"127.0.0.1","3306","");
    }

    public DataBase(String dbType,String db) {
        this(dbType,"127.0.0.1","3306",db);
    }

    public DataBase(String dbType,String ip,String port,String db) {
        this.dbType = dbType;
        if("MYSQL".endsWith(dbType.toUpperCase())) {
            this.driver="com.mysql.jdbc.Driver";
            this.url=mysqlUrl.replace("[ip]",ip).replace("[port]",port).replace("[db]",db);
        }else{
            this.driver="oracle.jdbc.driver.OracleDriver";
            this.url=oracleUrl.replace("[ip]",ip).replace("[port]",port).replace("[db]",db);
        }
    }

    public String getDbType() {
        return dbType;
    }

    public void setDbType(String dbType) {
        this.dbType = dbType;
    }

    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassWord() {
        return passWord;
    }

    public void setPassWord(String passWord) {
        this.passWord = passWord;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}
  • The automatically generated project configuration obtained by the UI page is encapsulated into the setting entity class
package cn.itcast.generate.entity;

import cn.itcast.generate.utils.StringUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

public class Settings {

    private String project="example";
    private String pPackage="com.example.demo";
    private String projectComment;
    private String author;
    private String path1="com";
    private String path2="example";
    private String path3="demo";
    private String pathAll;

    public Settings(String project, String pPackage, String projectComment, String author) {
        if(StringUtils.isNotBlank(project)) {
            this.project = project;
        }
        if(StringUtils.isNotBlank(pPackage)) {
            this.pPackage = pPackage;
        }
        this.projectComment = projectComment;
        this.author = author;
        String[] paths = pPackage.split("\\.");
        path1 = paths[0];
        path2 = paths.length>1?paths[1]:path2;
        path3 = paths.length>2?paths[2]:path3;
        pathAll = pPackage.replaceAll(".","/");
    }

    public Map<String, Object> getSettingMap(){
        Map<String, Object> map = new HashMap<>();
        Field[] declaredFields = Settings.class.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            try{
                map.put(field.getName(), field.get(this));
            }catch (Exception e){}
        }
        return map;
    }

    public String getProject() {
        return project;
    }

    public void setProject(String project) {
        this.project = project;
    }

    public String getpPackage() {
        return pPackage;
    }

    public void setpPackage(String pPackage) {
        this.pPackage = pPackage;
    }

    public String getProjectComment() {
        return projectComment;
    }

    public void setProjectComment(String projectComment) {
        this.projectComment = projectComment;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public String getPath1() {
        return path1;
    }

    public void setPath1(String path1) {
        this.path1 = path1;
    }

    public String getPath2() {
        return path2;
    }

    public void setPath2(String path2) {
        this.path2 = path2;
    }

    public String getPath3() {
        return path3;
    }

    public void setPath3(String path3) {
        this.path3 = path3;
    }

    public String getPathAll() {
        return pathAll;
    }

    public void setPathAll(String pathAll) {
        this.pathAll = pathAll;
    }
}
  • Encapsulate the metadata of the query data table into the Table entity class
package cn.itcast.generate.entity.db;

import java.util.List;

/**
 * 表实体
 * @author Administrator
 *
 */
public class Table {
    
    private String name;//表名称
    private String name2;//处理后的表名称
    private String comment;//介绍
    private String key;// 主键列
    private List<Column> columns;//列集合

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName2() {
        return name2;
    }

    public void setName2(String name2) {
        this.name2 = name2;
    }

    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public List<Column> getColumns() {
        return columns;
    }

    public void setColumns(List<Column> columns) {
        this.columns = columns;
    }
}

Sao Dai understands: the above private String name2; attribute refers to the corresponding conversion of the database table name into the name of the entity class, for example, the t_user table is converted into the User entity class through the code generator, then this name2 is User, and the private String of the Column entity class below columnName2; the same, refers to the attribute name after being converted into an entity class

  • Encapsulate the metadata of the query data field into the Column entity class
package cn.itcast.generate.entity.db;
/**
 * 列对象
 */
public class Column {
    
    private String columnName;//列名称
    private String columnName2;//列名称(处理后的列名称)
    private String columnType;//列类型
    private String columnDbType;//列数据库类型
    private String columnComment;//列备注D
    private String columnKey;//是否是主键

    public String getColumnName() {
        return columnName;
    }

    public void setColumnName(String columnName) {
        this.columnName = columnName;
    }

    public String getColumnName2() {
        return columnName2;
    }

    public void setColumnName2(String columnName2) {
        this.columnName2 = columnName2;
    }

    public String getColumnType() {
        return columnType;
    }

    public void setColumnType(String columnType) {
        this.columnType = columnType;
    }

    public String getColumnDbType() {
        return columnDbType;
    }

    public void setColumnDbType(String columnDbType) {
        this.columnDbType = columnDbType;
    }

    public String getColumnComment() {
        return columnComment;
    }

    public void setColumnComment(String columnComment) {
        this.columnComment = columnComment;
    }

    public String getColumnKey() {
        return columnKey;
    }

    public void setColumnKey(String columnKey) {
        this.columnKey = columnKey;
    }
}

Import tool class

FileUtil tool class

  • getRelativePath: get the relative path of the file
  • searchAllFile : query all files under the folder
  • mkdir: create a file directory
package cn.itcast.generate.utils;

import java.io.*;
import java.net.URL;
import java.util.*;

//文件处理工具类
public class FileUtils {

    // 得到相对路径
    public static String getRelativePath(File baseDir,File file) {
        if(baseDir.equals(file))
            return "";
        if(baseDir.getParentFile() == null)
            return file.getAbsolutePath().substring(baseDir.getAbsolutePath().length());
        return file.getAbsolutePath().substring(baseDir.getAbsolutePath().length()+1);
    }

    //查询某个目录下的所有文件
    public static List<File> searchAllFile(File dir) throws IOException {
        ArrayList arrayList = new ArrayList();
        searchFiles(dir,arrayList);
        return arrayList;
    }

    //递归获取某个目录下的所有文件
    public static void searchFiles(File dir,List<File> collector) throws IOException {
        if(dir.isDirectory()) {
            File[] subFiles = dir.listFiles();
            for(int i = 0; i < subFiles.length; i++) {
                searchFiles(subFiles[i],collector);
            }
        }else{
            collector.add(dir);
        }
    }

    //创建文件
    public static File mkdir(String dir,String file) {
        if(dir == null) throw new IllegalArgumentException("dir must be not null");
        File result = new File(dir,file);
        if(result.getParentFile() != null) {
            result.getParentFile().mkdirs();
        }
        return result;
    }
}

PropertiesMaps tool class

  • Load all properties and store them in the Map collection:
  • Load the code generator's base configuration fileLoad the user's custom configuration file
  • All configuration files need to be placed in the "/properties" folder
package cn.itcast.generate.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

public class PropertiesUtils {

    public static Map<String,String> customMap = new HashMap<>();

    static {
        File dir = new File("properties");
        try {
            List<File> files = FileUtils.searchAllFile(new File(dir.getAbsolutePath()));
            for (File file : files) {
                if(file.getName().endsWith(".properties")) {
                    Properties prop = new Properties();
                    prop.load(new FileInputStream(file));
                    customMap.putAll((Map) prop);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        PropertiesUtils.customMap.forEach((k, v)->{
            System.out.println(k+"--"+v);
        });
    }
}

Sao Dai understands: File dir = new File("properties"); means that if this tool class is to be used, then the configuration file must be placed in the properties directory, which is the same level directory as src

StringHelper string processing tool class

package cn.itcast.generate.utils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class StringUtils {

    public static String removeCrlf(String str) {
        if(str == null) return null;
        return StringUtils.join(StringUtils.tokenizeToStringArray(str,"\t\n\r\f")," ");
    }

    private static final Map<String,String> XML = new HashMap<String,String>();

    static{
        XML.put("apos", "'");
        XML.put("quot", "\"");
        XML.put("amp", "&");
        XML.put("lt", "<");
        XML.put("gt", ">");
    }

    public static String unescapeXml(String str) {
        if(str == null) return null;
        for(String key : XML.keySet()) {
            String value = XML.get(key);
            str = StringUtils.replace(str, "&"+key+";", value);
        }
        return str;
    }


    public static String removePrefix(String str,String prefix) {
        return removePrefix(str,prefix,false);
    }

    public static String removePrefix(String str,String prefix,boolean ignoreCase) {
        if(str == null) return null;
        if(prefix == null) return str;
        if(ignoreCase) {
            if(str.toLowerCase().startsWith(prefix.toLowerCase())) {
                return str.substring(prefix.length());
            }
        }else {
            if(str.startsWith(prefix)) {
                return str.substring(prefix.length());
            }
        }
        return str;
    }

    public static boolean isBlank(String str) {
        return str == null || str.trim().length() == 0;
    }

    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    public static String getExtension(String str) {
        if(str == null) return null;
        int i = str.lastIndexOf('.');
        if(i >= 0) {
            return str.substring(i+1);
        }
        return null;
    }

    /**
     * Count the occurrences of the substring in string s.
     * @param str string to search in. Return 0 if this is null.
     * @param sub string to search for. Return 0 if this is null.
     */
    public static int countOccurrencesOf(String str, String sub) {
        if (str == null || sub == null || str.length() == 0 || sub.length() == 0) {
            return 0;
        }
        int count = 0;
        int pos = 0;
        int idx;
        while ((idx = str.indexOf(sub, pos)) != -1) {
            ++count;
            pos = idx + sub.length();
        }
        return count;
    }

    public static boolean contains(String str,String... keywords) {
        if(str == null) return false;
        if(keywords == null) throw new IllegalArgumentException("'keywords' must be not null");

        for(String keyword : keywords) {
            if(str.contains(keyword.toLowerCase())) {
                return true;
            }
        }
        return false;
    }

    public static String defaultString(Object value) {
        if(value == null) {
            return "";
        }
        return value.toString();
    }

    public static String defaultIfEmpty(Object value,String defaultValue) {
        if(value == null || "".equals(value)) {
            return defaultValue;
        }
        return value.toString();
    }

    public static String makeAllWordFirstLetterUpperCase(String sqlName) {
        String[] strs = sqlName.toLowerCase().split("_");
        String result = "";
        String preStr = "";
        for(int i = 0; i < strs.length; i++) {
            if(preStr.length() == 1) {
                result += strs[i];
            }else {
                result += capitalize(strs[i]);
            }
            preStr = strs[i];
        }
        return result;
    }

    public static int indexOfByRegex(String input,String regex) {
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(input);
        if(m.find()) {
            return m.start();
        }
        return -1;
    }

    public static String toJavaVariableName(String str) {
        return uncapitalize(toJavaClassName(str));
    }

    public static String toJavaClassName(String str) {
        return makeAllWordFirstLetterUpperCase(StringUtils.toUnderscoreName(str));
    }

    public static String removeMany(String inString, String... keywords) {
        if (inString == null) {
            return null;
        }
        for(String k : keywords) {
            inString = replace(inString, k, "");
        }
        return inString;
    }

    public static String replace(String inString, String oldPattern, String newPattern) {
        if (inString == null) {
            return null;
        }
        if (oldPattern == null || newPattern == null) {
            return inString;
        }

        StringBuffer sbuf = new StringBuffer();
        // output StringBuffer we'll build up
        int pos = 0; // our position in the old string
        int index = inString.indexOf(oldPattern);
        // the index of an occurrence we've found, or -1
        int patLen = oldPattern.length();
        while (index >= 0) {
            sbuf.append(inString.substring(pos, index));
            sbuf.append(newPattern);
            pos = index + patLen;
            index = inString.indexOf(oldPattern, pos);
        }
        sbuf.append(inString.substring(pos));

        // remember to append any characters to the right of a match
        return sbuf.toString();
    }
    /**    ĸ  copy from spring*/
    public static String capitalize(String str) {
        return changeFirstCharacterCase(str, true);
    }

    /**    ĸСдcopy from spring*/
    public static String uncapitalize(String str) {
        return changeFirstCharacterCase(str, false);
    }
    /**copy from spring*/
    private static String changeFirstCharacterCase(String str, boolean capitalize) {
        if (str == null || str.length() == 0) {
            return str;
        }
        StringBuffer buf = new StringBuffer(str.length());
        if (capitalize) {
            buf.append(Character.toUpperCase(str.charAt(0)));
        }
        else {
            buf.append(Character.toLowerCase(str.charAt(0)));
        }
        buf.append(str.substring(1));
        return buf.toString();
    }

    private static final Random RANDOM = new Random();
    public static String randomNumeric(int count) {
        return random(count, false, true);
    }

    public static String random(int count, boolean letters, boolean numbers) {
        return random(count, 0, 0, letters, numbers);
    }

    public static String random(int count, int start, int end, boolean letters, boolean numbers) {
        return random(count, start, end, letters, numbers, null, RANDOM);
    }

    public static String random(int count, int start, int end, boolean letters,
                                boolean numbers, char[] chars, Random random) {
        if (count == 0) {
            return "";
        } else if (count < 0) {
            throw new IllegalArgumentException(
                    "Requested random string length " + count
                            + " is less than 0.");
        }
        if ((start == 0) && (end == 0)) {
            end = 'z' + 1;
            start = ' ';
            if (!letters && !numbers) {
                start = 0;
                end = Integer.MAX_VALUE;
            }
        }

        char[] buffer = new char[count];
        int gap = end - start;

        while (count-- != 0) {
            char ch;
            if (chars == null) {
                ch = (char) (random.nextInt(gap) + start);
            } else {
                ch = chars[random.nextInt(gap) + start];
            }
            if ((letters && Character.isLetter(ch))
                    || (numbers && Character.isDigit(ch))
                    || (!letters && !numbers)) {
                if (ch >= 56320 && ch <= 57343) {
                    if (count == 0) {
                        count++;
                    } else {
                        // low surrogate, insert high surrogate after putting it
                        // in
                        buffer[count] = ch;
                        count--;
                        buffer[count] = (char) (55296 + random.nextInt(128));
                    }
                } else if (ch >= 55296 && ch <= 56191) {
                    if (count == 0) {
                        count++;
                    } else {
                        // high surrogate, insert low surrogate before putting
                        // it in
                        buffer[count] = (char) (56320 + random.nextInt(128));
                        count--;
                        buffer[count] = ch;
                    }
                } else if (ch >= 56192 && ch <= 56319) {
                    // private high surrogate, no effing clue, so skip it
                    count++;
                } else {
                    buffer[count] = ch;
                }
            } else {
                count++;
            }
        }
        return new String(buffer);
    }

    /**
     */
    public static String toUnderscoreName(String name) {
        if(name == null) return null;

        String filteredName = name;
        if(filteredName.indexOf("_") >= 0 && filteredName.equals(filteredName.toUpperCase())) {
            filteredName = filteredName.toLowerCase();
        }
        if(filteredName.indexOf("_") == -1 && filteredName.equals(filteredName.toUpperCase())) {
            filteredName = filteredName.toLowerCase();
        }

        StringBuffer result = new StringBuffer();
        if (filteredName != null && filteredName.length() > 0) {
            result.append(filteredName.substring(0, 1).toLowerCase());
            for (int i = 1; i < filteredName.length(); i++) {
                String preChart = filteredName.substring(i - 1, i);
                String c = filteredName.substring(i, i + 1);
                if(c.equals("_")) {
                    result.append("_");
                    continue;
                }
                if(preChart.equals("_")){
                    result.append(c.toLowerCase());
                    continue;
                }
                if(c.matches("\\d")) {
                    result.append(c);
                }else if (c.equals(c.toUpperCase())) {
                    result.append("_");
                    result.append(c.toLowerCase());
                }
                else {
                    result.append(c);
                }
            }
        }
        return result.toString();
    }

    public static String removeEndWiths(String inputString,String... endWiths) {
        for(String endWith : endWiths) {
            if(inputString.endsWith(endWith)) {
                return inputString.substring(0,inputString.length() - endWith.length());
            }
        }
        return inputString;
    }

    /**
     * 将string转换为List<ColumnEnum> 格式为: "enumAlias(enumKey,enumDesc)"
     */
    static Pattern three = Pattern.compile("(.*)\\((.*),(.*)\\)");
    static Pattern two = Pattern.compile("(.*)\\((.*)\\)");

    /**
     * Test whether the given string matches the given substring
     * at the given index.
     * @param str the original string (or StringBuilder)
     * @param index the index in the original string to start matching against
     * @param substring the substring to match at the given index
     */
    public static boolean substringMatch(CharSequence str, int index, CharSequence substring) {
        for (int j = 0; j < substring.length(); j++) {
            int i = index + j;
            if (i >= str.length() || str.charAt(i) != substring.charAt(j)) {
                return false;
            }
        }
        return true;
    }

    public static String[] tokenizeToStringArray(String str,String seperators) {
        if(str == null) return new String[0];
        StringTokenizer tokenlizer = new StringTokenizer(str,seperators);
        List result = new ArrayList();

        while(tokenlizer.hasMoreElements()) {
            Object s = tokenlizer.nextElement();
            result.add(s);
        }
        return (String[])result.toArray(new String[result.size()]);
    }
    public static String join(List list, String seperator) {
        return join(list.toArray(new Object[0]),seperator);
    }

    public static String replace(int start, int end, String str,String replacement) {
        String before = str.substring(0,start);
        String after = str.substring(end);
        return before + replacement + after;
    }

    public static String join(Object[] array, String seperator) {
        if(array == null) return null;
        StringBuffer result = new StringBuffer();
        for(int i = 0; i < array.length; i++) {
            result.append(array[i]);
            if(i != array.length - 1)  {
                result.append(seperator);
            }
        }
        return result.toString();
    }
    public static int containsCount(String string, String keyword) {
        if(string == null) return 0;
        int count = 0;
        for(int i = 0; i < string.length(); i++ ) {
            int indexOf = string.indexOf(keyword,i);
            if(indexOf < 0) {
                break;
            }
            count ++;
            i = indexOf;
        }
        return count;
    }
}

DataBaseUtils tool class

Get a list of all database databases

package cn.itcast.generate.utils;

import cn.itcast.generate.entity.DataBase;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class DataBaseUtils {

    //获取到mysql中所有的数据库名称

    //获取数据库连接
    public static Connection getConnection(DataBase db) throws Exception {
        Properties props = new Properties();
        props.put("remarksReporting","true");//获取数据库的备注信息
        props.put("user",db.getUserName());
        props.put("password",db.getPassWord());
        Class.forName(db.getDriver());//注册驱动
        return DriverManager.getConnection(db.getUrl(),props);
    }


    //获取数据库列表
    public static List<String> getSchemas(DataBase db) throws Exception {
        //1.获取元数据
        Connection connection = getConnection(db);
        DatabaseMetaData metaData = connection.getMetaData();
        //2.获取所有数据库列表
        ResultSet rs = metaData.getCatalogs();
        List<String> list = new ArrayList<>();
        while (rs.next()) {
            list.add(rs.getString(1));
        }
        rs.close();
        connection.close();
        return list;
    }
}

Configure the UI interface

In order to facilitate the demonstration, a set of UI pages is constructed using the swing program. You don’t need to master swing, just use it directly

DatabaseUtil code generator swing program code

/*
 * DatabaseUtil.java
 *
 * Created on __DATE__, __TIME__
 */

package cn.itcast.generate.ui;


import cn.itcast.generate.entity.DataBase;
import cn.itcast.generate.utils.DataBaseUtils;

import javax.swing.*;
import java.sql.SQLException;
import java.util.List;


public class DatabaseUtil extends JFrame {

	/** Creates new form DatabaseUtil */
	public DatabaseUtil() {
		initComponents();
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	//GEN-BEGIN:initComponents
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		jLabel1 = new JLabel();
		jComboBox1 = new JComboBox();
		jLabel2 = new JLabel();
		jTextField1 = new JTextField();
		jLabel3 = new JLabel();
		jTextField2 = new JTextField();
		jLabel4 = new JLabel();
		jComboBox2 = new JComboBox();
		jButton1 = new JButton();
		jButton2 = new JButton();
		jTextField3 = new JTextField();
		jLabel5 = new JLabel();

		//setTitle("\u4f20\u667a\u5218\u5907\u4ee3\u7801\u751f\u6210\u56682.3");
		setTitle("代码生成器v1.0");
		setBackground(new java.awt.Color(204, 255, 204));
		addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowClosed(java.awt.event.WindowEvent evt) {
				formWindowClosed(evt);
			}

			public void windowOpened(java.awt.event.WindowEvent evt) {
				formWindowOpened(evt);
			}

			public void windowClosing(java.awt.event.WindowEvent evt) {
				formWindowClosing(evt);
			}
		});

		jLabel1.setText("\u9009\u62e9\u6570\u636e\u5e93\u7c7b\u578b");

		jComboBox1.setModel(new DefaultComboBoxModel(
				new String[] { "--请选择--" }));

		jLabel2.setText("\u7528\u6237\u540d");

		jLabel3.setText("\u5bc6\u7801");

		jLabel4.setText("\u6570\u636e\u5e93");

		jComboBox2.setModel(new DefaultComboBoxModel(
				new String[] { "--请选择数据库--" }));

		jButton1.setText("\u6d4b\u8bd5\u8fde\u63a5");
		jButton1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton1ActionPerformed(evt);
			}
		});

		jButton2.setLabel("\u8df3\u8fc7");
		jButton2.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton2ActionPerformed(evt);
			}
		});

		jTextField3.setText("127.0.0.1");

		jLabel5.setText("\u670d\u52a1\u5668IP");

		GroupLayout layout = new GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addGroup(
						GroupLayout.Alignment.TRAILING,
						layout.createSequentialGroup()
								.addGap(75, 75, 75)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.LEADING)
												.addComponent(jLabel3)
												.addComponent(jLabel5)
												.addComponent(jLabel1)
												.addComponent(jLabel2)
												.addComponent(jLabel4)
												.addComponent(jButton1))
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.TRAILING)
												.addGroup(
														layout.createSequentialGroup()
																.addPreferredGap(
																		LayoutStyle.ComponentPlacement.RELATED)
																.addComponent(
																		jButton2,
																		GroupLayout.PREFERRED_SIZE,
																		99,
																		GroupLayout.PREFERRED_SIZE))
												.addGroup(
														GroupLayout.Alignment.LEADING,
														layout.createSequentialGroup()
																.addGap(34, 34,
																		34)
																.addGroup(
																		layout.createParallelGroup(
																				GroupLayout.Alignment.LEADING)
																				.addComponent(
																						jComboBox2,
																						GroupLayout.Alignment.TRAILING,
																						0,
																						174,
																						Short.MAX_VALUE)
																				.addComponent(
																						jTextField1,
																						GroupLayout.Alignment.TRAILING,
																						GroupLayout.DEFAULT_SIZE,
																						174,
																						Short.MAX_VALUE)
																				.addComponent(
																						jComboBox1,
																						GroupLayout.Alignment.TRAILING,
																						0,
																						174,
																						Short.MAX_VALUE)
																				.addComponent(
																						jTextField3,
																						GroupLayout.DEFAULT_SIZE,
																						174,
																						Short.MAX_VALUE)
																				.addComponent(
																						jTextField2,
																						GroupLayout.DEFAULT_SIZE,
																						174,
																						Short.MAX_VALUE))))
								.addGap(106, 106, 106)));
		layout.setVerticalGroup(layout
				.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addGroup(
						layout.createSequentialGroup()
								.addGap(53, 53, 53)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(jLabel1)
												.addComponent(
														jComboBox1,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE))
								.addGap(18, 18, 18)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(
														jTextField3,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(jLabel5))
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.RELATED)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(
														jTextField1,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(jLabel2))
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.RELATED)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(
														jTextField2,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(jLabel3))
								.addGap(11, 11, 11)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.LEADING)
												.addComponent(jLabel4)
												.addComponent(
														jComboBox2,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE))
								.addGap(11, 11, 11)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(jButton1)
												.addComponent(jButton2))
								.addContainerGap()));

		pack();
	}// </editor-fold>
	//GEN-END:initComponents

	private void formWindowClosing(java.awt.event.WindowEvent evt) {
		dispose();
		System.exit(0);
		System.out.println("释放");
	}

	private void formWindowClosed(java.awt.event.WindowEvent evt) {
		dispose();
		System.exit(0);
		System.out.println("释放");
	}

	private void formWindowOpened(java.awt.event.WindowEvent evt) {
		setLocationRelativeTo(null);

		String [] dbTypes = new String[]{"MYSQL","ORACLE"};

		for (String key : dbTypes) {
			this.jComboBox1.addItem(key);
		}

		setLocationRelativeTo(null);
	}
	
	private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
		if (this.jButton2.getText().equals("下一步")) {
			this.jButton2.setText("运行中...");
			this.jButton2.setEnabled(false);
			final Thread t=new Thread(new Runnable(){
				  public void run(){
					  String dbName = jComboBox2.getSelectedItem().toString();
					  String ip = jTextField3.getText();
					  String username = jTextField1.getText();
					  String password = jTextField2.getText();
					  String dbType = (String)jComboBox1.getSelectedItem();
					  DataBase db = new DataBase(dbType,ip,"3306",dbName);
					  db.setUserName(username);
					  db.setPassWord(password);
					  CodeUtil codeUtil = new CodeUtil(db,null);
					  codeUtil.setDbInfo(db,dbName);
					  codeUtil.setVisible(true);
					  setVisible(false);
				  }}
				 );
			t.start();
			
		 }else{
			JOptionPane.showMessageDialog(null, "请选择数据库", "提示",
					JOptionPane.OK_OPTION);
		 }
	}

	private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
		//
		jButton1.setText("连接中...");
		jButton1.setEnabled(false);
		
		final Thread t=new Thread(new Runnable(){
			  public void run(){
				  try{
				  	  String ip = jTextField3.getText();
					  String username = jTextField1.getText();
					  String password = jTextField2.getText();
					  String dbType = (String)jComboBox1.getSelectedItem();
					  DataBase db = new DataBase(dbType,ip,"3306","");
					  db.setUserName(username);
					  db.setPassWord(password);
					  List<String> catalogs = DataBaseUtils.getSchemas(db);
						jComboBox2.removeAllItems();
						for (String c : catalogs) {
							jComboBox2.addItem(c);
						}
						
						JOptionPane.showMessageDialog(null, "连接成功", "提示",
									JOptionPane.DEFAULT_OPTION);
						jButton2.setText("下一步");
					  
				  }catch (ClassNotFoundException e) {
						e.printStackTrace();
						JOptionPane.showMessageDialog(null, "无法加载驱动类", "提示",
								JOptionPane.OK_OPTION);
						
				  } catch (SQLException e) {
						e.printStackTrace();
						JOptionPane.showMessageDialog(null, "无法连接数据库,请核对连接信息是否正确", "提示",
								JOptionPane.OK_OPTION);
				   }catch (Exception e) {
				     e.printStackTrace();
				     JOptionPane.showMessageDialog(null, "发生错误", "错误详情请查看error.log",
								JOptionPane.INFORMATION_MESSAGE);
				  }
				  jButton1.setEnabled(true);
				  jButton1.setText("测试连接");
			  }}
			 );
		t.start();
	}

	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new DatabaseUtil().setVisible(true);
			}
		});
	}

	//GEN-BEGIN:variables
	// Variables declaration - do not modify
	private JButton jButton1;
	private JButton jButton2;
	private JComboBox<String> jComboBox1;
	private JComboBox jComboBox2;
	private JLabel jLabel1;
	private JLabel jLabel2;
	private JLabel jLabel3;
	private JLabel jLabel4;
	private JLabel jLabel5;
	private JTextField jTextField1;
	private JTextField jTextField2;
	private JTextField jTextField3;
	// End of variables declaration//GEN-END:variables

}

CodeUtil tool class

/*
 * CodeUtil.java
 * CodeUtil.java
 *
 * Created on __DATE__, __TIME__
 */

package cn.itcast.generate.ui;


import cn.itcast.generate.entity.DataBase;
import cn.itcast.generate.entity.Settings;
import javax.swing.*;
import java.io.File;
import java.util.HashMap;
import java.util.Map;


public class CodeUtil extends JFrame {

	private DataBase db;
	private String dbName;

	/** Creates new form CodeUtil */
	public CodeUtil(DataBase db,String dbName) {
		this.db = db;
		this.dbName = dbName;
		initComponents();
	}

	/** This method is called from within the constructor to
	 * initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is
	 * always regenerated by the Form Editor.
	 */
	//GEN-BEGIN:initComponents
	// <editor-fold defaultstate="collapsed" desc="Generated Code">
	private void initComponents() {

		jLabel1 = new JLabel();
		jLabel4 = new JLabel();
		jSeparator1 = new JSeparator();
		//jTextField4 = new javax.swing.JTextField();
		jLabel5 = new JLabel();
		jTextField5 = new JTextField();
		jSeparator2 = new JSeparator();
		jLabel6 = new JLabel();
		jTextField6 = new JTextField();
		jLabel7 = new JLabel();
		jTextField7 = new JTextField();
		jLabel8 = new JLabel();
		jTextField8 = new JTextField();
		jLabel9 = new JLabel();
		jTextField9 = new JTextField();
		jButton1 = new JButton();
		jButton2 = new JButton();
		//jButton6 = new javax.swing.JButton();
		jButton7 = new JButton();
		数据库 = new JLabel();
		jTextField10 = new JTextField();
		jLabel10 = new JLabel();
		jTextField11 = new JTextField();
		jLabel11 = new JLabel();
		jTextField12 = new JTextField();
		jComboBox1 = new JComboBox();

		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		//setTitle("\u4f20\u667a\u5218\u5907\u4ee3\u7801\u751f\u6210\u5668 V2.3");
		setTitle("代码生成器v1.0");
		addWindowListener(new java.awt.event.WindowAdapter() {
			public void windowActivated(java.awt.event.WindowEvent evt) {
				formWindowActivated(evt);
			}

			public void windowOpened(java.awt.event.WindowEvent evt) {
				formWindowOpened(evt);
			}

			public void windowClosing(java.awt.event.WindowEvent evt) {
				formWindowClosing(evt);
			}
		});

		jLabel1.setText("\u6a21\u677f");

		//jLabel4.setText("\u7ed3\u6784\u6587\u6863\u8def\u5f84");

		jLabel5.setText("\u4ee3\u7801\u751f\u6210\u8def\u5f84");

		jLabel6.setText("\u9879\u76ee\u540d\uff08\u82f1\u6587\uff09");

		jLabel7.setText("\u9879\u76ee\u4e2d\u6587\u540d\u79f0");

		jLabel8.setText("\u5305\u540d");

		jLabel9.setText("\u4f5c\u8005");

		jButton1.setText("\u751f\u6210\u4ee3\u7801");
		jButton1.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton1ActionPerformed(evt);
			}
		});

		jButton2.setText("\u5173\u95ed");
		jButton2.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton2ActionPerformed(evt);
			}
		});

//		jButton6.setText("\u9009\u62e9");
//		jButton6.addActionListener(new java.awt.event.ActionListener() {
//			public void actionPerformed(java.awt.event.ActionEvent evt) {
//				jButton6ActionPerformed(evt);
//			}
//		});

		jButton7.setText("\u9009\u62e9");
		jButton7.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				jButton7ActionPerformed(evt);
			}
		});

		数据库.setText("\u6570\u636e\u5e93");

		jLabel10.setText("\u7528\u6237\u540d");

		jLabel11.setText("\u5bc6\u7801");

		jComboBox1.setModel(new DefaultComboBoxModel(
				new String[] { "--请选择模板--" }));

		GroupLayout layout = new GroupLayout(
				getContentPane());
		getContentPane().setLayout(layout);
		layout.setHorizontalGroup(layout
				.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addComponent(jSeparator2,
						GroupLayout.DEFAULT_SIZE, 543,
						Short.MAX_VALUE)
				.addComponent(jSeparator1,
						GroupLayout.Alignment.TRAILING,
						GroupLayout.DEFAULT_SIZE, 543,
						Short.MAX_VALUE)
				.addGroup(
						GroupLayout.Alignment.TRAILING,
						layout.createSequentialGroup()
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.LEADING)
												.addGroup(
														layout.createSequentialGroup()
																.addGap(26, 26,
																		26)
																.addGroup(
																		layout.createParallelGroup(
																				GroupLayout.Alignment.LEADING)
																				.addComponent(
																						jLabel4)
																				.addGroup(
																						layout.createSequentialGroup()
																								.addPreferredGap(
																										LayoutStyle.ComponentPlacement.RELATED)
																								.addComponent(
																										jLabel5))))
												.addGroup(
														layout.createSequentialGroup()
																.addGap(25, 25,
																		25)
																.addGroup(
																		layout.createParallelGroup(
																				GroupLayout.Alignment.LEADING)
																				.addComponent(
																						jLabel6)
																				.addComponent(
																						jLabel8)
																				.addComponent(
																						jLabel7)
																				.addComponent(
																						jLabel9)
																				.addComponent(
																						数据库)
																				.addComponent(
																						jLabel10))))
								.addGap(0, 0, 0)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.LEADING)
												.addGroup(
														layout.createSequentialGroup()
																.addComponent(
																		jTextField11,
																		GroupLayout.PREFERRED_SIZE,
																		104,
																		GroupLayout.PREFERRED_SIZE)
																.addGap(18, 18,
																		18)
																.addComponent(
																		jLabel11)
																.addGap(36, 36,
																		36)
																.addComponent(
																		jTextField12,
																		GroupLayout.DEFAULT_SIZE,
																		118,
																		Short.MAX_VALUE))
												.addComponent(
														jTextField10,
														GroupLayout.DEFAULT_SIZE,
														300, Short.MAX_VALUE)
												.addGroup(
														GroupLayout.Alignment.TRAILING,
														layout.createSequentialGroup()
																.addComponent(
																		jButton1)
																.addPreferredGap(
																		LayoutStyle.ComponentPlacement.RELATED,
																		140,
																		Short.MAX_VALUE)
																.addComponent(
																		jButton2,
																		GroupLayout.PREFERRED_SIZE,
																		79,
																		GroupLayout.PREFERRED_SIZE))
//												.addComponent(
//														jTextField4,
//														javax.swing.GroupLayout.DEFAULT_SIZE,
//														300, Short.MAX_VALUE)
												.addComponent(
														jTextField5,
														GroupLayout.DEFAULT_SIZE,
														300, Short.MAX_VALUE)
												.addComponent(
														jTextField6,
														GroupLayout.DEFAULT_SIZE,
														300, Short.MAX_VALUE)
												.addComponent(
														jTextField7,
														GroupLayout.DEFAULT_SIZE,
														300, Short.MAX_VALUE)
												.addComponent(
														jTextField8,
														GroupLayout.DEFAULT_SIZE,
														300, Short.MAX_VALUE)
												.addComponent(
														jTextField9,
														GroupLayout.DEFAULT_SIZE,
														300, Short.MAX_VALUE))
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.RELATED)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.TRAILING,
												false)
//												.addComponent(
//														jButton7,
//														javax.swing.GroupLayout.Alignment.LEADING,
//														0, 0, Short.MAX_VALUE)
												.addComponent(
														jButton7,
														GroupLayout.Alignment.LEADING,
														GroupLayout.DEFAULT_SIZE,
														73, Short.MAX_VALUE)
									)
								.addGap(54, 54, 54))
				.addGroup(
						GroupLayout.Alignment.TRAILING,
						layout.createSequentialGroup()
								.addGap(27, 27, 27)
								.addComponent(jLabel1)
								.addGap(57, 57, 57)
								.addComponent(jComboBox1,
										GroupLayout.PREFERRED_SIZE,
										299,
										GroupLayout.PREFERRED_SIZE)
								.addGap(136, 136, 136)));
		layout.setVerticalGroup(layout
				.createParallelGroup(GroupLayout.Alignment.LEADING)
				.addGroup(
						layout.createSequentialGroup()
								.addGap(96, 96, 96)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(
														jComboBox1,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(jLabel1))
								.addGap(18, 18, 18)
								.addComponent(jSeparator1,
										GroupLayout.PREFERRED_SIZE,
										10,
										GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.RELATED)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(jLabel4)
//												.addComponent(jTextField4)
												//.addComponent(jButton6)
								)
								.addGap(15, 15, 15)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(jLabel5)
												.addComponent(jTextField5)
												.addComponent(jButton7))
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.UNRELATED)
								.addComponent(jSeparator2,
										GroupLayout.PREFERRED_SIZE,
										10,
										GroupLayout.PREFERRED_SIZE)
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.RELATED)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(jLabel6)
												.addComponent(jTextField6))
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.UNRELATED)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.LEADING)
												.addComponent(jLabel8)
												.addComponent(jTextField7))
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.RELATED)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(jLabel7)
												.addComponent(jTextField8))
								.addPreferredGap(
										LayoutStyle.ComponentPlacement.UNRELATED)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(jTextField9)
												.addComponent(jLabel9))
								.addGap(18, 18, 18)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(数据库)
												.addComponent(jTextField10))
								.addGap(18, 18, 18)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(jLabel10)
												.addComponent(
														jTextField11,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(jLabel11)
												.addComponent(
														jTextField12,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE))
								.addGap(26, 26, 26)
								.addGroup(
										layout.createParallelGroup(
												GroupLayout.Alignment.BASELINE)
												.addComponent(jButton2)
												.addComponent(jButton1))
								.addGap(24, 24, 24)));

		pack();
	}// </editor-fold>
	//GEN-END:initComponents

	private void formWindowClosing(java.awt.event.WindowEvent evt) {
		dispose();
		System.exit(0);

	}


	private void formWindowOpened(java.awt.event.WindowEvent evt) {
		setLocationRelativeTo(null);
		//获取当前文件夹下的模板目录下的所有文件夹
		File directory = new File(new File("").getAbsolutePath() + "\\模板");//设定为当前文件夹
		File[] listFiles = directory.listFiles();
		if (listFiles != null) {
			for (File f : listFiles) {
				if (f.isDirectory()) {
					this.jComboBox1.addItem(f.getName());
				}
			}
		}
		//this.jTextField4.setText(new File("").getAbsolutePath() + "\\db");
	}

	private void formWindowActivated(java.awt.event.WindowEvent evt) {

	}

	private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
		//this.dispose();
		System.exit(0);
	}

	public void setDbInfo(DataBase dbs,String name) {
		this.jTextField10.setText(name);
		this.jTextField11.setText(dbs.getUserName());
		this.jTextField12.setText(dbs.getPassWord());

	}

	private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
		jButton1.setEnabled(false);
		jButton1.setText("代码生成中...");
		final Thread t=new Thread(new Runnable(){
			  public void run(){
				  try{
					//路径map封装
						Map<String, String> pathMap = new HashMap<String, String>();
						//获取当前文件夹下的模板目录下的所有文件夹
						String basePath = new File("").getAbsolutePath() + "\\模板\\"
								+ jComboBox1.getSelectedItem();//设定为当前文件夹

						String templetPath = basePath;
						String outpath = jTextField5.getText();

						//全局替换符
						Map<String, String> publicMap = new HashMap<String, String>();
						String project = jTextField6.getText();
						String pPackage = jTextField7.getText();
						String projectComment = jTextField8.getText();
						String author = jTextField9.getText();
					  Settings settings = new Settings(project,pPackage,projectComment,author);
					  generator(templetPath,outpath,settings,db);
					  JOptionPane.showMessageDialog(null, "代码生成成功", "提示",
								JOptionPane.DEFAULT_OPTION);
				  }catch (Exception e) {
				     e.printStackTrace();
				     JOptionPane.showMessageDialog(null, "发生错误", "错误详情请查看error.log",
								JOptionPane.INFORMATION_MESSAGE);
				     
				  }
				  jButton1.setEnabled(true);
				  jButton1.setText("生成代码");
				  
			  }}
		  );
		t.start();
	}

	private void jButton7ActionPerformed(java.awt.event.ActionEvent evt) {
		this.jTextField5.setText(selectPath("选择代码生成路径"));
	}

//	private void jButton6ActionPerformed(java.awt.event.ActionEvent evt) {
//		this.jTextField4.setText(selectPath("选择结构文档路径"));
//	}

	private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {
		//this.jTextField2.setText(selectPath("选择表级模板路径"));
	}

	/**
	 * 选择路径
	 * @param title
	 * @return
	 */
	private String selectPath(String title) {
		JFileChooser jfc = new JFileChooser();
		jfc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		jfc.showDialog(new JLabel(), title);
		File file = jfc.getSelectedFile();
		if (file == null) {
			return null;
		}
		return file.getPath();
	}

	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				DataBase db = new DataBase("mysql","ihrm");
				db.setUserName("root");
				db.setPassWord("111111");
				new CodeUtil(db,null).setVisible(true);
			}
		});
	}

	//GEN-BEGIN:variables
	// Variables declaration - do not modify
	private JButton jButton1;
	private JButton jButton2;
	private JButton jButton6;
	private JButton jButton7;
	private JComboBox jComboBox1;
	private JLabel jLabel1;
	private JLabel jLabel10;
	private JLabel jLabel11;
	private JLabel jLabel4;
	private JLabel jLabel5;
	private JLabel jLabel6;
	private JLabel jLabel7;
	private JLabel jLabel8;
	private JLabel jLabel9;
	private JSeparator jSeparator1;
	private JSeparator jSeparator2;
	private JTextField jTextField10;
	private JTextField jTextField11;
	private JTextField jTextField12;
	private JTextField jTextField4;
	private JTextField jTextField5;
	private JTextField jTextField6;
	private JTextField jTextField7;
	private JTextField jTextField8;
	private JTextField jTextField9;
	private JLabel 数据库;
	// End of variables declaration//GEN-END:variables


	//UI调用程序入口

	/**
	 *
	 * @param templetPath		模板所在路径
	 * @param outpath			选择代码生成路径
	 * @param settings			工程配置对象
	 * @param db				数据库信息
	 */
	private void generator(String templetPath,String outpath,Settings settings,DataBase db) {
		System.out.println(templetPath);
		System.out.println(outpath);
		System.out.println(settings);
		System.out.println(db);
//		GeneratorFacade gf = new GeneratorFacade(templetPath,outpath,settings);
//		gf.generatorByTable(db);
	}

}

Guess you like

Origin blog.csdn.net/qq_50954361/article/details/130941854