add mybatis-flex-codegen module

This commit is contained in:
开源海哥 2023-03-24 16:22:26 +08:00
parent 4ff783e849
commit b59157f143
13 changed files with 1434 additions and 0 deletions

View File

@ -16,4 +16,78 @@
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>com.mybatis-flex</groupId>
<artifactId>mybatis-flex-core</artifactId>
<version>1.0.3</version>
</dependency>
<!--使用 enjoy 模板引擎-->
<dependency>
<groupId>com.jfinal</groupId>
<artifactId>enjoy</artifactId>
<version>5.0.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>4.0.3</version>
<scope>compile</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<!-- **/* 打包代码生成器的模板文件 -->
<include>**/*.tpl</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
<excludes>
<exclude>
*.properties
</exclude>
</excludes>
</resource>
</resources>
</build>
</project>

View File

@ -0,0 +1,189 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.mybatisflex.codegen.dialect.IDialect;
import com.mybatisflex.codegen.entity.Column;
import com.mybatisflex.codegen.entity.Table;
import com.mybatisflex.codegen.template.ITemplate;
import javax.sql.DataSource;
import java.io.File;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Generator {
protected DataSource dataSource;
protected GlobalConfig globalConfig;
protected IDialect dialect = IDialect.MYSQL;
protected Connection conn = null;
protected DatabaseMetaData dbMeta = null;
public Generator(DataSource dataSource, GlobalConfig globalConfig) {
this.dataSource = dataSource;
this.globalConfig = globalConfig;
}
public Generator(DataSource dataSource, GlobalConfig globalConfig, IDialect dialect) {
this.dataSource = dataSource;
this.globalConfig = globalConfig;
this.dialect = dialect;
}
public void generate() {
try {
conn = dataSource.getConnection();
dbMeta = conn.getMetaData();
List<Table> tables = buildTables();
ITemplate templateEngine = globalConfig.getTemplateEngine();
for (Table table : tables) {
String entityPackagePath = globalConfig.getEntityPackage().replace(".", "/");
File entityJavaFile = new File(globalConfig.getSourceDir(), entityPackagePath + "/" + table.buildEntityClassName() + ".java");
if (!entityJavaFile.getParentFile().exists()) {
if (!entityJavaFile.getParentFile().mkdirs()) {
throw new IllegalStateException("Can not mkdirs by dir: " + entityJavaFile.getParentFile());
}
}
templateEngine.generateEntity(globalConfig, table, entityJavaFile);
if (globalConfig.isMapperGenerateEnable()) {
String mapperPackagePath = globalConfig.getMapperPackage().replace(".", "/");
File mapperJavaFile = new File(globalConfig.getSourceDir(), mapperPackagePath + "/" + table.buildEntityClassName() + "Mapper.java");
if (!mapperJavaFile.getParentFile().exists()) {
if (!mapperJavaFile.getParentFile().mkdirs()) {
throw new IllegalStateException("Can not mkdirs by dir: " + mapperJavaFile.getParentFile());
}
}
templateEngine.generateMapper(globalConfig, table, mapperJavaFile);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
protected void buildPrimaryKey(Table table) throws SQLException {
try (ResultSet rs = dbMeta.getPrimaryKeys(conn.getCatalog(), null, table.getName())) {
while (rs.next()) {
String primaryKey = rs.getString("COLUMN_NAME");
table.addPrimaryKey(primaryKey);
}
}
}
private void buildTableColumns(Table table) throws SQLException {
Map<String, String> columnRemarks = buildColumnRemarks(table);
String sql = dialect.forBuildColumns(table.getName());
try (Statement stm = conn.createStatement(); ResultSet rs = stm.executeQuery(sql)) {
ResultSetMetaData columnMetaData = rs.getMetaData();
int columnCount = columnMetaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
Column column = new Column();
column.setName(columnMetaData.getColumnName(i));
column.setPropertyType(columnMetaData.getColumnClassName(i));
column.setAutoIncrement(columnMetaData.isAutoIncrement(i));
//主键
if (table.getPrimaryKeys() != null && table.getPrimaryKeys().contains(column.getName())) {
column.setPrimaryKey(true);
}
//注释
column.setRemarks(columnRemarks.get(column.getName()));
column.setColumnConfig(globalConfig.getColumnConfig(table.getName(), column.getName()));
table.addColumn(column);
}
}
}
private Map<String, String> buildColumnRemarks(Table table) throws SQLException {
Map<String, String> columnRemarks = new HashMap<>();
ResultSet colRs = null;
try {
colRs = dbMeta.getColumns(conn.getCatalog(), null, table.getName(), null);
while (colRs.next()) {
columnRemarks.put(colRs.getString("COLUMN_NAME"), colRs.getString("REMARKS"));
}
} catch (Exception e) {
System.err.println("无法获取字段的备注内容:" + e.getMessage());
} finally {
if (colRs != null) {
colRs.close();
}
}
return columnRemarks;
}
private List<Table> buildTables() throws SQLException {
List<Table> tables = new ArrayList<>();
try (ResultSet rs = getTablesResultSet()) {
while (rs.next()) {
String tableName = rs.getString("TABLE_NAME");
if (!globalConfig.isSupportGenerate(tableName)) {
continue;
}
Table table = new Table();
table.setGlobalConfig(globalConfig);
table.setTableConfig(globalConfig.getTableConfig(tableName));
table.setName(tableName);
String remarks = rs.getString("REMARKS");
table.setRemarks(remarks);
buildPrimaryKey(table);
buildTableColumns(table);
tables.add(table);
}
}
return tables;
}
protected ResultSet getTablesResultSet() throws SQLException {
if (globalConfig.isGenerateForView()) {
return dialect.getTablesResultSet(dbMeta, conn, new String[]{"TABLE", "VIEW"});
} else {
return dialect.getTablesResultSet(dbMeta, conn, new String[]{"TABLE"});
}
}
}

View File

@ -0,0 +1,149 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen.config;
import com.mybatisflex.annotation.KeyType;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import java.io.Serializable;
public class ColumnConfig implements Serializable {
private String columnName;
private String onInsertValue;
private String onUpdateValue;
private Boolean isLarge;
private Boolean isLogicDelete;
private Boolean version;
private JdbcType jdbcType;
private Class<? extends TypeHandler> typeHandler;
private String mask;
private boolean isPrimaryKey = false;
private KeyType keyType;
private String keyValue;
private Boolean keyBefore;
public String getColumnName() {
return columnName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public String getOnInsertValue() {
return onInsertValue;
}
public void setOnInsertValue(String onInsertValue) {
this.onInsertValue = onInsertValue;
}
public String getOnUpdateValue() {
return onUpdateValue;
}
public void setOnUpdateValue(String onUpdateValue) {
this.onUpdateValue = onUpdateValue;
}
public Boolean getLarge() {
return isLarge;
}
public void setLarge(Boolean large) {
isLarge = large;
}
public Boolean getLogicDelete() {
return isLogicDelete;
}
public void setLogicDelete(Boolean logicDelete) {
isLogicDelete = logicDelete;
}
public Boolean getVersion() {
return version;
}
public void setVersion(Boolean version) {
this.version = version;
}
public JdbcType getJdbcType() {
return jdbcType;
}
public void setJdbcType(JdbcType jdbcType) {
this.jdbcType = jdbcType;
}
public Class<? extends TypeHandler> getTypeHandler() {
return typeHandler;
}
public void setTypeHandler(Class<? extends TypeHandler> typeHandler) {
this.typeHandler = typeHandler;
}
public String getMask() {
return mask;
}
public void setMask(String mask) {
this.mask = mask;
}
public boolean isPrimaryKey() {
return isPrimaryKey;
}
public void setPrimaryKey(boolean primaryKey) {
isPrimaryKey = primaryKey;
}
public KeyType getKeyType() {
return keyType;
}
public void setKeyType(KeyType keyType) {
this.keyType = keyType;
}
public String getKeyValue() {
return keyValue;
}
public void setKeyValue(String keyValue) {
this.keyValue = keyValue;
}
public Boolean getKeyBefore() {
return keyBefore;
}
public void setKeyBefore(Boolean keyBefore) {
this.keyBefore = keyBefore;
}
}

View File

@ -0,0 +1,288 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen.config;
import com.mybatisflex.codegen.template.EnjoyTemplate;
import com.mybatisflex.codegen.template.ITemplate;
import com.mybatisflex.core.util.StringUtil;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class GlobalConfig {
private String sourceDir;
private String entityPackage;
private Boolean entityWithLombok = false;
//是否生成 mapper 文件
private boolean mapperGenerateEnable = false;
private String mapperPackage;
private String tablePrefix;
private String logicDeleteColumn;
private String versionColumn;
//是否支持生成视图映射
private boolean generateForView = false;
private Map<String, TableConfig> tableConfigMap;
private Map<String, ColumnConfig> defaultColumnConfigMap;
private Set<String> generateTables;
private Set<String> unGenerateTables;
protected ITemplate templateEngine;
public String getSourceDir() {
if (sourceDir == null || sourceDir.trim().length() == 0) {
return System.getProperty("user.dir") + "/src/main/java";
}
return sourceDir;
}
public void setSourceDir(String sourceDir) {
this.sourceDir = sourceDir;
}
public String getEntityPackage() {
if (StringUtil.isBlank(entityPackage)) {
throw new IllegalStateException("entityPackage can not be null or blank in GlobalConfig.");
}
return entityPackage;
}
public void setEntityPackage(String entityPackage) {
this.entityPackage = entityPackage.trim();
}
public Boolean getEntityWithLombok() {
return entityWithLombok;
}
public void setEntityWithLombok(Boolean entityWithLombok) {
this.entityWithLombok = entityWithLombok;
}
public boolean isMapperGenerateEnable() {
return mapperGenerateEnable;
}
public void setMapperGenerateEnable(boolean mapperGenerateEnable) {
this.mapperGenerateEnable = mapperGenerateEnable;
}
public String getMapperPackage() {
if (StringUtil.isBlank(mapperPackage)) {
throw new IllegalStateException("mapperPackage can not be null or blank in GlobalConfig.");
}
return mapperPackage;
}
public void setMapperPackage(String mapperPackage) {
this.mapperPackage = mapperPackage;
}
public String getTablePrefix() {
return tablePrefix;
}
public void setTablePrefix(String tablePrefix) {
this.tablePrefix = tablePrefix;
}
public String getLogicDeleteColumn() {
return logicDeleteColumn;
}
public void setLogicDeleteColumn(String logicDeleteColumn) {
this.logicDeleteColumn = logicDeleteColumn;
}
public String getVersionColumn() {
return versionColumn;
}
public void setVersionColumn(String versionColumn) {
this.versionColumn = versionColumn;
}
public Map<String, TableConfig> getTableConfigMap() {
return tableConfigMap;
}
public void setTableConfigMap(Map<String, TableConfig> tableConfigMap) {
this.tableConfigMap = tableConfigMap;
}
public void addTableConfig(TableConfig tableConfig) {
if (tableConfigMap == null) {
tableConfigMap = new HashMap<>();
}
tableConfigMap.put(tableConfig.getTableName(), tableConfig);
}
public TableConfig getTableConfig(String tableName) {
return tableConfigMap == null ? null : tableConfigMap.get(tableName);
}
public Map<String, ColumnConfig> getDefaultColumnConfigMap() {
return defaultColumnConfigMap;
}
public void setDefaultColumnConfigMap(Map<String, ColumnConfig> defaultColumnConfigMap) {
this.defaultColumnConfigMap = defaultColumnConfigMap;
}
public void addColumnConfig(ColumnConfig columnConfig) {
if (defaultColumnConfigMap == null) {
defaultColumnConfigMap = new HashMap<>();
}
defaultColumnConfigMap.put(columnConfig.getColumnName(), columnConfig);
}
public void addColumnConfig(String tableName, ColumnConfig columnConfig) {
TableConfig tableConfig = getTableConfig(tableName);
if (tableConfig == null) {
tableConfig = new TableConfig();
tableConfig.setTableName(tableName);
addTableConfig(tableConfig);
}
tableConfig.addColumnConfig(columnConfig);
}
public ColumnConfig getColumnConfig(String tableName, String columnName) {
ColumnConfig columnConfig = null;
TableConfig tableConfig = getTableConfig(tableName);
if (tableConfig != null) {
columnConfig = tableConfig.getColumnConfig(columnName);
}
if (columnConfig == null && defaultColumnConfigMap != null) {
columnConfig = defaultColumnConfigMap.get(columnName);
}
if (columnConfig == null) {
columnConfig = new ColumnConfig();
}
//全局配置的逻辑删除
if (columnName.equals(logicDeleteColumn) && columnConfig.getLogicDelete() == null) {
columnConfig.setLogicDelete(true);
}
//全部配置的乐观锁版本
if (columnName.equals(versionColumn) && columnConfig.getVersion() == null) {
columnConfig.setVersion(true);
}
return columnConfig;
}
public boolean isGenerateForView() {
return generateForView;
}
public void setGenerateForView(boolean generateForView) {
this.generateForView = generateForView;
}
public Set<String> getGenerateTables() {
return generateTables;
}
public void setGenerateTables(Set<String> generateTables) {
this.generateTables = generateTables;
}
public void addGenerateTable(String... tables) {
if (generateTables == null) {
generateTables = new HashSet<>();
}
for (String table : tables) {
if (table != null && table.trim().length() > 0) {
generateTables.add(table.trim());
}
}
}
public Set<String> getUnGenerateTables() {
return unGenerateTables;
}
public void setUnGenerateTables(Set<String> unGenerateTables) {
this.unGenerateTables = unGenerateTables;
}
public void addUnGenerateTable(String... tables) {
if (unGenerateTables == null) {
unGenerateTables = new HashSet<>();
}
for (String table : tables) {
if (table != null && table.trim().length() > 0) {
unGenerateTables.add(table.trim());
}
}
}
public boolean isSupportGenerate(String table) {
if (unGenerateTables != null && unGenerateTables.contains(table)) {
return false;
}
//不配置指定比表名的情况下支持所有表
if (generateTables == null || generateTables.isEmpty()) {
return true;
}
for (String generateTable : generateTables) {
if (generateTable.equals(table)) {
return true;
}
}
return false;
}
public ITemplate getTemplateEngine() {
if (templateEngine == null) {
templateEngine = new EnjoyTemplate();
}
return templateEngine;
}
public void setTemplateEngine(ITemplate templateEngine) {
this.templateEngine = templateEngine;
}
}

View File

@ -0,0 +1,81 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen.config;
import java.util.HashMap;
import java.util.Map;
public class TableConfig {
private String tableName;
/**
* 数据库的 schema
*/
private String schema;
/**
* 默认为 驼峰属性 转换为 下划线字段
*/
private Boolean camelToUnderline;
private Map<String,ColumnConfig> columnConfigMap;
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
}
public Boolean getCamelToUnderline() {
return camelToUnderline;
}
public void setCamelToUnderline(Boolean camelToUnderline) {
this.camelToUnderline = camelToUnderline;
}
public Map<String, ColumnConfig> getColumnConfigMap() {
return columnConfigMap;
}
public void setColumnConfigMap(Map<String, ColumnConfig> columnConfigMap) {
this.columnConfigMap = columnConfigMap;
}
public void addColumnConfig(ColumnConfig columnConfig){
if (columnConfigMap == null){
columnConfigMap = new HashMap<>();
}
columnConfigMap.put(columnConfig.getColumnName(), columnConfig);
}
public ColumnConfig getColumnConfig(String columnName){
return columnConfigMap == null ? null: columnConfigMap.get(columnName);
}
}

View File

@ -0,0 +1,57 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen.dialect;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.SQLException;
public interface IDialect {
IDialect MYSQL = new IDialect() {
@Override
public String forBuildColumns(String tableName) {
return "SELECT * FROM `" + tableName + "` WHERE 1 = 2";
}
@Override
public ResultSet getTablesResultSet(DatabaseMetaData dbMeta, Connection conn, String[] types) throws SQLException {
return dbMeta.getTables(conn.getCatalog(), null, null, types);
}
};
IDialect ORACLE = new IDialect() {
@Override
public String forBuildColumns(String tableName) {
return "SELECT * FROM \"" +tableName+ "\" WHERE rownum < 1";
}
@Override
public ResultSet getTablesResultSet(DatabaseMetaData dbMeta, Connection conn, String[] types) throws SQLException {
return dbMeta.getTables(conn.getCatalog(), dbMeta.getUserName(), null, types);
}
};
String forBuildColumns(String tableName);
ResultSet getTablesResultSet(DatabaseMetaData dbMeta, Connection conn, String[] types) throws SQLException;
}

View File

@ -0,0 +1,260 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen.entity;
import com.mybatisflex.annotation.ColumnMask;
import com.mybatisflex.annotation.Id;
import com.mybatisflex.annotation.KeyType;
import com.mybatisflex.codegen.config.ColumnConfig;
import com.mybatisflex.core.util.StringUtil;
import java.util.ArrayList;
import java.util.List;
public class Column {
private String name;
private String property;
private String propertyType;
private String remarks;
private boolean isPrimaryKey = false;
private Boolean isAutoIncrement;
private ColumnConfig columnConfig;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
this.property = buildPropertyName();
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public String getPropertyType() {
return propertyType;
}
public String getPropertySimpleType() {
return propertyType.substring(propertyType.lastIndexOf(".") + 1);
}
public void setPropertyType(String propertyType) {
this.propertyType = propertyType;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public boolean isPrimaryKey() {
return isPrimaryKey;
}
public void setPrimaryKey(boolean primaryKey) {
isPrimaryKey = primaryKey;
}
public Boolean getAutoIncrement() {
return isAutoIncrement;
}
public void setAutoIncrement(Boolean autoIncrement) {
isAutoIncrement = autoIncrement;
}
public ColumnConfig getColumnConfig() {
return columnConfig;
}
public void setColumnConfig(ColumnConfig columnConfig) {
this.columnConfig = columnConfig;
}
public String buildGetter() {
return "get" + StringUtil.firstCharToUpperCase(property);
}
public String buildSetter() {
return "set" + StringUtil.firstCharToUpperCase(property);
}
public String buildPropertyName() {
String entityJavaFileName = name;
return StringUtil.firstCharToLowerCase(StringUtil.underlineToCamel(entityJavaFileName));
}
public String buildAnnotations() {
StringBuilder annotations = new StringBuilder();
//@Id 的注解
if (isPrimaryKey || columnConfig.isPrimaryKey()) {
annotations.append("@Id(");
boolean needComma = false;
if (isAutoIncrement) {
annotations.append("keyType=KeyType.Auto");
needComma = true;
} else if (columnConfig.getKeyType() != null) {
annotations.append("keyType=KeyType." + columnConfig.getKeyType().name());
needComma = true;
}
if (columnConfig.getKeyValue() != null) {
addComma(annotations, needComma);
annotations.append("value=\"" + columnConfig.getKeyValue() + "\"");
needComma = true;
}
if (columnConfig.getKeyBefore() != null) {
addComma(annotations, needComma);
annotations.append("before=" + columnConfig.getKeyBefore());
}
annotations.append(")");
}
//@Column 注解
if (columnConfig.getOnInsertValue() != null
|| columnConfig.getOnUpdateValue() != null
|| columnConfig.getLarge() != null
|| columnConfig.getLogicDelete() != null
|| columnConfig.getVersion() != null
|| columnConfig.getJdbcType() != null
|| columnConfig.getTypeHandler() != null
) {
annotations.append("@Column(");
boolean needComma = false;
if (columnConfig.getOnInsertValue() != null) {
annotations.append("onInsertValue=\"" + columnConfig.getOnInsertValue() + "\"");
needComma = true;
}
if (columnConfig.getOnUpdateValue() != null) {
addComma(annotations, needComma);
annotations.append("onUpdateValue=\"" + columnConfig.getOnUpdateValue() + "\"");
needComma = true;
}
if (columnConfig.getLarge() != null) {
addComma(annotations, needComma);
annotations.append("isLarge=" + columnConfig.getLarge());
needComma = true;
}
if (columnConfig.getLogicDelete() != null) {
addComma(annotations, needComma);
annotations.append("isLogicDelete=" + columnConfig.getLogicDelete());
needComma = true;
}
if (columnConfig.getVersion() != null) {
addComma(annotations, needComma);
annotations.append("version=" + columnConfig.getVersion());
needComma = true;
}
if (columnConfig.getJdbcType() != null) {
addComma(annotations, needComma);
annotations.append("jdbcType=JdbcType." + columnConfig.getJdbcType().name());
needComma = true;
}
if (columnConfig.getTypeHandler() != null) {
addComma(annotations, needComma);
annotations.append("typeHandler=" + columnConfig.getTypeHandler().getSimpleName() + ".class");
}
annotations.append(")");
}
//@ColumnMask 注解
if (columnConfig.getMask() != null) {
annotations.append("@ColumnMask(\"" + columnConfig.getMask() + "\")");
}
return annotations.toString();
}
private void addComma(StringBuilder annotations, boolean needComma) {
if (needComma) {
annotations.append(", ");
}
}
public List<String> getImportClasses() {
List<String> importClasses = new ArrayList<>();
//lang 包不需要显式导入
if (!propertyType.startsWith("java.lang.")) {
importClasses.add(propertyType);
}
if (isPrimaryKey || (columnConfig != null && columnConfig.isPrimaryKey())) {
importClasses.add(Id.class.getName());
if (isAutoIncrement || (columnConfig != null && columnConfig.getKeyType() != null)) {
importClasses.add(KeyType.class.getName());
}
}
if (columnConfig != null) {
if (columnConfig.getMask() != null) {
importClasses.add(ColumnMask.class.getName());
}
if (columnConfig.getJdbcType() != null) {
importClasses.add("org.apache.ibatis.type.JdbcType");
}
if (columnConfig.getTypeHandler() != null) {
importClasses.add(columnConfig.getTypeHandler().getName());
}
if (columnConfig.getOnInsertValue() != null
|| columnConfig.getOnUpdateValue() != null
|| columnConfig.getLarge() != null
|| columnConfig.getLogicDelete() != null
|| columnConfig.getVersion() != null
|| columnConfig.getJdbcType() != null
|| columnConfig.getTypeHandler() != null
) {
importClasses.add(com.mybatisflex.annotation.Column.class.getName());
}
}
return importClasses;
}
@Override
public String toString() {
return "Column{" +
"name='" + name + '\'' +
", className='" + propertyType + '\'' +
", remarks='" + remarks + '\'' +
", isAutoIncrement=" + isAutoIncrement +
'}';
}
}

View File

@ -0,0 +1,149 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen.entity;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.mybatisflex.codegen.config.TableConfig;
import com.mybatisflex.core.util.StringUtil;
import java.util.*;
import java.util.stream.Collectors;
public class Table {
private String name;
private String remarks;
private Set<String> primaryKeys;
private List<Column> columns = new ArrayList<>();
private GlobalConfig globalConfig;
private TableConfig tableConfig;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRemarks() {
return remarks;
}
public void setRemarks(String remarks) {
this.remarks = remarks;
}
public Set<String> getPrimaryKeys() {
return primaryKeys;
}
public void setPrimaryKeys(Set<String> primaryKeys) {
this.primaryKeys = primaryKeys;
}
public void addPrimaryKey(String primaryKey) {
if (primaryKeys == null) {
primaryKeys = new LinkedHashSet<>();
}
primaryKeys.add(primaryKey);
}
public List<Column> getColumns() {
return columns;
}
public void setColumns(List<Column> columns) {
this.columns = columns;
}
public void addColumn(Column column) {
columns.add(column);
}
public GlobalConfig getGlobalConfig() {
return globalConfig;
}
public void setGlobalConfig(GlobalConfig globalConfig) {
this.globalConfig = globalConfig;
}
public TableConfig getTableConfig() {
return tableConfig;
}
public void setTableConfig(TableConfig tableConfig) {
this.tableConfig = tableConfig;
}
public List<String> buildImports() {
Set<String> imports = new HashSet<>();
imports.add(com.mybatisflex.annotation.Table.class.getName());
for (Column column : columns) {
imports.addAll(column.getImportClasses());
}
return imports.stream().sorted(Comparator.naturalOrder()).collect(Collectors.toList());
}
/**
* 构建 entity Class 名称
*
* @return className
*/
public String buildEntityClassName() {
String entityJavaFileName = name;
String tablePrefix = globalConfig.getTablePrefix();
if (tablePrefix != null && name.startsWith(tablePrefix)) {
entityJavaFileName = name.substring(tablePrefix.length());
}
return StringUtil.firstCharToUpperCase(StringUtil.underlineToCamel(entityJavaFileName));
}
/**
* 构建 @Table(...) 注解
*/
public String buildTableAnnotation() {
StringBuilder tableAnnotation = new StringBuilder("@Table(");
tableAnnotation.append("value=\"").append(name).append("\"");
if (tableConfig != null) {
if (tableConfig.getSchema() != null) {
tableAnnotation.append(", schema=\"" + tableConfig.getSchema() + "\"");
}
if (tableConfig.getCamelToUnderline() != null) {
tableAnnotation.append(", camelToUnderline=\"" + tableConfig.getCamelToUnderline() + "\"");
}
}
return tableAnnotation.append(")").toString();
}
@Override
public String toString() {
return "Table{" +
"name='" + name + '\'' +
", remarks='" + remarks + '\'' +
", primaryKeys='" + primaryKeys + '\'' +
", columns=" + columns +
'}';
}
}

View File

@ -0,0 +1,61 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen.template;
import com.jfinal.template.Engine;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.mybatisflex.codegen.entity.Table;
import com.mybatisflex.core.util.StringUtil;
import java.io.File;
import java.io.FileOutputStream;
import java.util.HashMap;
import java.util.Map;
public class EnjoyTemplate implements ITemplate {
private Engine engine;
public EnjoyTemplate() {
engine = Engine.create("mybatis-flex", engine -> {
engine.setToClassPathSourceFactory();
engine.addSharedMethod(StringUtil.class);
});
}
@Override
public void generateEntity(GlobalConfig globalConfig, Table table, File entityJavaFile) throws Exception {
Map<String, Object> params = new HashMap<>();
params.put("globalConfig", globalConfig);
params.put("table", table);
FileOutputStream fileOutputStream = new FileOutputStream(entityJavaFile);
engine.getTemplate("/templates/enjoy/entity.tpl").render(params, fileOutputStream);
}
@Override
public void generateMapper(GlobalConfig globalConfig, Table table, File mapperJavaFile) throws Exception {
Map<String, Object> params = new HashMap<>();
params.put("globalConfig", globalConfig);
params.put("table", table);
FileOutputStream fileOutputStream = new FileOutputStream(mapperJavaFile);
engine.getTemplate("/templates/enjoy/mapper.tpl").render(params, fileOutputStream);
}
}

View File

@ -0,0 +1,28 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen.template;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.mybatisflex.codegen.entity.Table;
import java.io.File;
public interface ITemplate {
void generateEntity(GlobalConfig globalConfig, Table table, File entityJavaFile) throws Exception ;
void generateMapper(GlobalConfig globalConfig, Table table, File mapperJavaFile) throws Exception ;
}

View File

@ -0,0 +1,26 @@
package #(globalConfig.entityPackage);
#for(importClass:table.buildImports())
import #(importClass);
#end
#(table.buildTableAnnotation())
public class #(table.buildEntityClassName()) {
#for(column: table.columns) #(column.buildAnnotations())
private #(column.propertySimpleType) #(column.property);
#end
#for(column: table.columns)
public #(column.propertySimpleType) #(column.buildGetter())() {
return #(column.property);
}
public void #(column.buildSetter())(#(column.propertySimpleType) #(column.property)) {
this.#(column.property) = #(column.property);
}
#end
}

View File

@ -0,0 +1,8 @@
package #(globalConfig.mapperPackage);
import com.mybatisflex.core.BaseMapper;
import #(globalConfig.entityPackage).#(table.buildEntityClassName());
public interface #(table.buildEntityClassName())Mapper extends BaseMapper<#(table.buildEntityClassName())> {
}

View File

@ -0,0 +1,64 @@
/**
* Copyright (c) 2022-2023, Mybatis-Flex (fuhai999@gmail.com).
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mybatisflex.codegen.test;
import com.mybatisflex.codegen.Generator;
import com.mybatisflex.codegen.config.ColumnConfig;
import com.mybatisflex.codegen.config.GlobalConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.junit.Test;
public class GeneratorTest {
@Test
public void testGenerator() {
//配置数据源
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/jbootadmin?characterEncoding=utf-8");
dataSource.setUsername("root");
dataSource.setPassword("123456");
GlobalConfig globalConfig = new GlobalConfig();
//设置只生成哪些表
globalConfig.addGenerateTable("account", "account_session");
//设置 entity 的包名
globalConfig.setEntityPackage("com.test.test");
//是否生成 mapper 文件默认为 false
globalConfig.setMapperGenerateEnable(true);
//设置 mapper 文件的包名
globalConfig.setMapperPackage("com.test.mapper");
//可以单独配置某个列的数据
ColumnConfig columnConfig = new ColumnConfig();
columnConfig.setColumnName("tenant_id");
columnConfig.setLarge(true);
columnConfig.setVersion(true);
globalConfig.addColumnConfig("account",columnConfig);
//通过 datasource globalConfig 创建代码生成器
Generator generator = new Generator(dataSource, globalConfig);
//开始生成代码
generator.generate();
}
}