Assume that the data table has been generated and the table structure is:

DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user`  (
  `id` bigint(20) UNSIGNED NOT NULL COMMENT 'primary key id'.`username` varchar(64) NOT NULL COMMENT 'Username, unique'.`password` varchar(255) NOT NULL COMMENT 'password',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `id`(`id`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COMMENT = 'User table';
Copy the code

To map a database table to a Java entity class, I used Mybatis Generator. This looks like this:

package com.cc.model.entity;

import java.util.Date;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Id;

@Entity
@Table(name = "tb_user")
public class TbUserMember implements Serializable {
    @Id
    @Column(name = "id")
    private Long id;

    @Column(name = "username")
    private String username;

    @Column(name = "password")
    private String password;

    public Long getId(a) {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername(a) {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword(a) {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString(a) {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append("[");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", username=").append(username);
        sb.append(", password=").append(password);
        sb.append("]");
        returnsb.toString(); }}Copy the code

I hope to add:

  • @ ApiModelProperty annotations
  • Varchar (64) NOT NULL COMMENT ‘username, unique’
  • More customization needs

However, I did not find a way for Mybaits Generator to implement the above requirements, or perhaps not, so I handbrushed a mapping utility class. In my opinion, compared to Mybatis Generator, this utility class has the following advantages:

  • Single class, easy to use
  • Source code is simple, access to it
  • Customization is high

The source code

Without more words, directly on the source code:

package com.cc.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.sql.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/** * Database table conversion entity class tool, the existing database table, by reading the field information to generate Java entity class. * * Instructions: * 1. Fill in the correct database configuration * 2. Set on demand whether to add@Entity3. Set alias to map specified database table to entity class * 4. Create a new model package and copy the absolute path to savePath * 5. Set the model package to packageName * 6@author chen
 * @dateThe 2021-06-10 with * /
public class DatabaseConvertUtil {
    private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
    private static final String URL = "jdbc:mysql://myserverhost:3306/mymall? characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "root";

    private final static Logger log = LoggerFactory.getLogger(DatabaseConvertUtil.class);

    static private boolean doEntity = false;    // Add hibernate entity class content
    static private boolean doSwagger = false;   // Add swagger

    static private boolean doDao = false;   // Generate the DAO class for Tk.mybatis
    static private String daoPackageName;   // The package name where dao is stored
    static private String daoSavePath;  // dao saves the path

    // Database table name mapping entity class name, default initial capital hump, such as tb_user -> TbUser
    static private Map<String, String> alias = new HashMap<>();
    static private String entityPackageName;  // The package name to store
    static private String entitySavePath; // Save path
    static private String fileSuffix = ".java"; // Generate file suffix, debugging can be changed to.txt to see the effect

    static private Map<String, String> importMap;
    static private Map<String, String> typeMap;

    public static void main(String[] args) {
        doEntity = true;
        doSwagger = true;
        doDao = false;

        entityPackageName = "com.cc.model.entity";
        daoPackageName = "com.cc.dao";

        daoSavePath = "E:\\xxx\\src\\main\\java\\com\\cc\\dao";

        entitySavePath = "E:\\xxx\\src\\main\\java\\com\\cc\\model\\entity";

        alias.put("tb_user_member"."TbUserMember");
        alias.put("tb_user_admin"."TbUserAdmin");
        alias.put("tb_user_resource"."TbUserResource");
        alias.put("tb_user_role"."TbUserRole");
        alias.put("tb_user_role_relation"."TbUserRoleRelation");
        alias.put("tb_user_role_resource_relation"."TbUserRoleResourceRelation");
        alias.put("tb_user_menu"."TbUserMenu");

        System.out.println("Start mapping...");
        generatorEntityClass();
        System.out.println("Database table mapping to entity class completed");
    }

    static {
        try {
            // Load the driver
            Class.forName(DRIVER);

            // initialize, add here if conditions are not enough
            // Map variable types to imported dependencies
            importMap = new HashMap<>();
            importMap.put("Date"."import java.util.Date;");
            importMap.put("BigDecimal"."import java.math.BigDecimal;");

            // Map database table types to Java variable types
            typeMap = new HashMap<>();
            typeMap.put("CHAR"."String");
            typeMap.put("VARCHAR"."String");
            typeMap.put("LONGVARCHAR"."String");
            typeMap.put("NUMERIC"."BigDecimal");
            typeMap.put("DECIMAL"."BigDecimal");
            typeMap.put("BIT"."Boolean");
            typeMap.put("BOOLEAN"."Boolean");
            typeMap.put("TINYINT"."Byte");
            typeMap.put("SMALLINT"."Short");
            typeMap.put("INTEGER"."Integer");
            typeMap.put("INT"."Integer");
            typeMap.put("BIGINT"."Long");
            typeMap.put("REAL"."Float");
            typeMap.put("FLOAT"."Double");
            typeMap.put("DATE"."Date");
            typeMap.put("DATETIME"."Date");
            typeMap.put("TIME"."Time");
            typeMap.put("TIMESTAMP"."Timestamp");
        } catch (ClassNotFoundException e) {
            log.error("can not load jdbc driver", e); }}public static Map<String, String> getImportMap(a) {
        return importMap;
    }

    public static Map<String, String> getTypeMap(a) {
        return typeMap;
    }

    // Get the database connection
    public static Connection getConnection(a) {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
        } catch (SQLException e) {
            log.error("get connection failure", e);
        }
        return conn;
    }

    // Close the database connection
    public static void closeConnection(Connection conn) {
        if(conn ! =null) {
            try {
                conn.close();
            } catch (SQLException e) {
                log.error("close connection failure", e); }}}// Start conversion
    public static void generatorEntityClass(a) {
        for (Map.Entry<String, String> entry : alias.entrySet()) {
            String tableName = entry.getKey();  / / the name of the table
            String className = entry.getValue();    / / the name of the class

            System.out.printf("Mapping table: %s to entity class: %s%n", tableName, className);

            if (doDao) {
                try {
                    String interfaceName = className.substring(2, className.length()) + "Dao";
                    String path = daoSavePath + "\ \" + interfaceName + fileSuffix;
                    BufferedWriter out = new BufferedWriter(new FileWriter(path));
                    out.write(String.format("package %s; \n", daoPackageName));
                    out.write("\n");
                    out.write(String.format("import %s.%s; \n", entityPackageName, className));
                    out.write("import org.springframework.stereotype.Repository; \n");
                    out.write("import tk.mybatis.mapper.common.Mapper; \n");
                    out.write("\n");
                    out.write("@Repository\n");
                    out.write(String.format("public interface %s extends Mapper<%s> {\n", interfaceName, className));
                    out.write("}\n");
                    out.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            Connection connection = getConnection();
            PreparedStatement preparedStatement;
            String sql = "SELECT * FROM " + tableName;
            ResultSet rs = null;
            try {
                preparedStatement = connection.prepareStatement(sql);
                rs = preparedStatement.executeQuery("show full columns from " + tableName); // Get all columns of the table

                Set<String> importStrArray = new HashSet<>();   // import xxx
                List<String> fieldStrArray = new ArrayList<>(); // private Long id;
                List<String> getterAndSetterArray = new ArrayList<>();  // getter and setter
                List<String> fields = new ArrayList<>();    // All fields
                boolean hasId = false;
                while (rs.next()) {
                    String fieldStr = getFieldStr(rs);
                    String _field = rs.getString("Field");
                    String _key = rs.getString("Key");

                    String importStr = getImportStr(rs);
                    if(importStr ! =null) {
                        importStrArray.add(importStr);
                    }

                    fieldStrArray.add((fieldStr == null)? _field +"Parsing failed" : fieldStr);
                    getterAndSetterArray.add(getterAndSetter(rs));
                    fields.add(HumpLineUtil.lineToHump(_field));

                    if ("PRI".equals(_key)) {
                        hasId = true;
                    }
                }

                String path = entitySavePath + "\ \" + className + fileSuffix;
                BufferedWriter out = new BufferedWriter(new FileWriter(path));

                // Output dependency packages
                out.write("package " + entityPackageName + "; \n\n");

                // Output reference dependency
                for (String s : importStrArray) {
                    out.write(s);
                    out.write("\n");
                }

                // Add the Entity, Table, Id, and Column dependencies
                out.write("import java.io.Serializable; \n");

                if (doEntity) {
                    out.write("import javax.persistence.Entity; \n");
                    out.write("import javax.persistence.Table; \n");
                    out.write("import javax.persistence.Column; \n");
                    if (hasId) {
                        out.write("import javax.persistence.Id; \n"); }}if (doSwagger) {
                    out.write("import io.swagger.annotations.ApiModelProperty; \n");
                }
                out.write("\n");

                // Output the class declaration
                if (doEntity) {
                    out.write("@Entity\n");
                    out.write("@Table(name = \"" + tableName + "\")\n");
                }
                out.write("public class " + className + " implements Serializable {");
                out.write("\n");

                // Output attribute variables
                for (String s : fieldStrArray) {
                    out.write(s);
                    out.write("\n");
                }
                out.write(" private static final long serialVersionUID = 1L; \n\n");

                // Prints the getter and setter methods
                for (String s : getterAndSetterArray) {
                    out.write(s);
                    out.write("\n");
                }

                out.write(getToString(fields));

                / / finishing
                out.write("}");
                out.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if(rs ! =null) {
                    try {
                        rs.close();
                        closeConnection(connection);
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    // Get the package to import for this attribute
    static String getImportStr(ResultSet rs) throws SQLException {
        String _type = rs.getString("Type");

        Map<String, String> map = getImportMap();

        String type = getType(_type);
        String str = null;

        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (key.equalsIgnoreCase(type)) {    // Lower case for comparison
                str = value;
                break; }}return str;
    }

    // Attribute variable declarations, such as: private Long ID;
    static String getFieldStr(ResultSet rs) throws SQLException {
        String _field = rs.getString("Field");
        String _type = rs.getString("Type");
        String _key = rs.getString("Key");
        String _comment = rs.getString("Comment");

        String str = "";

        if (doEntity) {
            if ("PRI".equals(_key)) {
                str += " @Id\n";
            }
            str += " @Column(name = \"" + _field + "\", columnDefinition = \"" + getColumnDefinition(rs) + "\")\n";
        }
        if (doSwagger) {
            str += " @ApiModelProperty(value = \"" + _comment + "\")\n";
        }

        String type = getType(_type);
        if (type == null) {
            return null;
        }
        _field = HumpLineUtil.lineToHump(_field); // Underline the hump
        str += " private " + type + "" + _field + "; \n";
        return str;
    }

    // Getter and setter methods for class attributes
    static String getterAndSetter(ResultSet rs) throws SQLException {
        String _field = rs.getString("Field");
        String _type = rs.getString("Type");

        String field = HumpLineUtil.lineToHump(_field); // Underline the hump
        String type = getType(_type);

        String str = "";
        str += " public " + type + " get" + upperFirstLetter(field) + "() {\n";
        str += " return " + field + "; \n";
        str += " }\n";

        str += " public void" + " set" + upperFirstLetter(field) + "(" + type + "" + field + ") {\n";
        str += " this." + field + "=" + field + "; \n";
        str += " }\n";

        return str;
    }

    / / the toString () method
    static String getToString(List<String> fields) {
        StringBuilder str = new StringBuilder();
        str.append(" @Override\n");
        str.append(" public String toString() {\n");
        str.append(" StringBuilder sb = new StringBuilder(); \n");
        str.append(" sb.append(getClass().getSimpleName()); \n");
        str.append(" sb.append(\" [\");\n");
        str.append(" sb.append(\"Hash = \").append(hashCode()); \n");

        for (String field : fields) {
            str.append(" sb.append(\", ").append(field).append("=\").append(").append(field).append("); \n");
        }

        str.append(" sb.append(\", serialVersionUID=\").append(serialVersionUID); \n");
        str.append(" sb.append(\"]\"); \n");
        str.append(" return sb.toString(); \n");
        str.append(" }\n");
        return str.toString();
    }

    // Get the variable type of the attribute, such as: Long
    private static String getType(String _type) {
        String[] a = _type.split("\\("); // Remove the parentheses and the string in parentheses
        _type = a[0];

        Map<String, String> map = getTypeMap();

        String type = null;
        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();
            if (key.equalsIgnoreCase(_type)) {
                type = value;
                break; }}return type;
    }

    // Capitalize the first letter of the string
    private static String upperFirstLetter(String name) {
        char[] cs = name.toCharArray();
        cs[0] - =32;
        return String.valueOf(cs);
    }

    // Retrieve the columnDefinition contents of @column (name = "username", columnDefinition = "")
    static String getColumnDefinition(ResultSet rs) throws SQLException {
        String _type = rs.getString("Type");
        String _null = rs.getString("Null");
        String _key = rs.getString("Key");
        String _default = rs.getString("Default");
        String _extra = rs.getString("Extra");
        String _comment = rs.getString("Comment");

        String columnDefinition = _type.toUpperCase();

        if ("UNI".equals(_key)) {
            columnDefinition += " UNIQUE";
        }
        if ("NO".equals(_null)) {
            columnDefinition += " NOT NULL";
        }
        if ("".equals(_default)) {
            columnDefinition += " DEFAULT ''";
        } else if(_default ! =null) {
            columnDefinition += " DEFAULT " + _default.toUpperCase();
        }

        if (!"".equals(_extra)) {
            columnDefinition += "" + _extra;
        }

        if (!"".equals(_comment)) {
            columnDefinition += " COMMENT '" + _comment + "'";
        }
        return columnDefinition;
    }

    / * * * hump - underline conversion tool, comes from: https://blog.csdn.net/turbo_sky/article/details/84814518 * /
    public static class HumpLineUtil {
        private static Pattern linePattern = Pattern.compile("(_)(\\w)");

        /** * Hump underlined, for example: TbUser -> _tb_user *@param str
         * @return* /
        public static String humpToLine(String str){
            return str.replaceAll("[A-Z]"."_ $0").toLowerCase();
        }

        /** * underline to hump, for example: tb_user -> tbUser *@param str
         * @return* /
        public static String lineToHump(String str){
            Matcher matcher = linePattern.matcher(str);
            StringBuffer sb = new StringBuffer();
            while(matcher.find()){
                matcher.appendReplacement(sb, matcher.group(2).toUpperCase());
            }
            matcher.appendTail(sb);
            returnsb.toString(); }}}Copy the code

Directions for use

You need to manually specify the absolute path to store the Entity class, and then declare whether you want the Entity annotation, Swagger annotation or not

On top of that I added a daoSavePath, the DAO layer that generates TkMybatis, which gives me the customization I want.