自定义Jpa代码生成器

实现方式就是使用freemarker模板技术,预先定义我们需要生成的文件,如entity,dto,dao,service,serviceImpl,controller,然后通过获取数据库中的表和列信息,填充模板中的参数内容最后输出java文件。

1、maven中引入相关依赖

    <properties>
        <lombok.version>1.18.16</lombok.version>
        <c3p0.version>0.9.5.2</c3p0.version>
        <freemarker.version>2.3.31</freemarker.version>
        <mysql.version>8.0.22</mysql.version>
        <junit.version>4.13.2</junit.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${lombok.version}</version>
        </dependency>
        <dependency>
            <groupId>com.mchange</groupId>
            <artifactId>c3p0</artifactId>
            <version>${c3p0.version}</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>${freemarker.version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2、定义一个数据基类和分页基类,基础类中定义了数据库表的共有列字段,如id,更新人,更新时间,审核人,审核时间,审核状态,通过使用@PrePersist注解修饰的方法,每次给更新时间和审核时间设置默认值,业务代码中不需要再做处理。

package com.yx.light.element.jpa.entity.base;

import io.swagger.annotations.ApiModelProperty;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Setter;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;

/**
 * 基础字段实体
 */
@Data
@MappedSuperclass
public class BaseModel implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GenericGenerator(name = "snowflakeId", strategy = "com.yx.light.element.jpa.config.SnowflakeIdGenerator")
    @GeneratedValue(generator = "snowflakeId")
    @ApiModelProperty(value = "id")
    private Long id;

    @Column(name = "update_by")
    @ApiModelProperty(value = "制作人(最后更新人)")
    private String updateBy;

    @Column(name = "update_time")
    @ApiModelProperty(value = "最后更新时间")
    @Setter(AccessLevel.NONE)
    private Date updateTime;

    @Column(name = "check_state")
    @ApiModelProperty(value = "审核状态,1-审核;0-未审核;")
    private Integer checkState;

    @Column(name = "check_by")
    @ApiModelProperty(value = "审核人")
    private String checkBy;

    @Column(name = "check_time")
    @ApiModelProperty(value = "审核时间")
    @Setter(AccessLevel.NONE)
    private Date checkTime;

    @PrePersist
    public void setDefaultTime() {
        this.updateTime = new Date();
        this.checkTime = new Date();
    }
}
package com.yx.limit.base.dto;

import lombok.Data;

/**
 * 分页查询基类
 */
@Data
public class PageDto {
    private int pageNum = 1;
    private int pageSize = 10;
}

准备一个表用于后面代码生成测试

CREATE TABLE `t_index_info` (
  `id` bigint NOT NULL COMMENT '主键id',
  `index_code` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '指标代码',
  `index_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '指标名称',
  `is_public` int NOT NULL DEFAULT '0' COMMENT '是否公共,0-否;1-是',
  `deploy_by` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '部署人',
  `deploy_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '部署时间',
  `index_funcodes` varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '指标触发位置',
  `version` int DEFAULT '1' COMMENT '版本',
  `install_state` int DEFAULT '3' COMMENT '指标部署状态:0 已卸载、1已启用、3 未启用',
  `risk_level` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'low' COMMENT '风险级别,high=高风险、middle=中风险、low=低风险(默认)',
  `remark` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '描述',
  `check_state` int DEFAULT '0' COMMENT '审核状态,1-审核;0-未审核;',
  `update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'SYS' COMMENT '制作人(最后更新人)',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '最后更新时间',
  `check_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT 'SYS' COMMENT '审核人',
  `check_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '审核时间',
  `limit_date` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '自然日' COMMENT '业务日期限制(默认)自然日,工作日,节假日',
  `deploy_desc` varchar(2000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT '' COMMENT '部署描述',
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE KEY `index_code_idx_u` (`index_code`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='指标信息表';

3、数据类型的枚举

import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * mysql数据类型枚举(mysql8部分类型)
 */
@AllArgsConstructor
public enum MySqlDataTypeEnum {

    INT("int"),
    BIGINT("bigint"),
    DECIMAL("decimal"),
    DOUBLE("double"),
    FLOAT("float"),
    DATE("date"),
    DATETIME("datetime"),
    TIME("time"),
    TIMESTAMP("timestamp"),
    CHAR("char"),
    VARCHAR("varchar"),
    TEXT("text"),
    BLOB("blob");

    @Getter
    private String value;
}

4,数据模型实体,表格信息和列信息

package com.yx.limit.jpa.helper.model;

import com.yx.limit.jpa.helper.enums.MySqlDataTypeEnum;
import lombok.*;

/**
 * 表格列模型
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ColumnModel {
    /**
     * 列名
     */
    private String columnName;
    /**
     * 驼峰列名
     */
    private String humpColumnName;
    /**
     * 列类型
     */
    private String columnType;
    /**
     * Java类型
     */
    @Setter(AccessLevel.NONE)
    private String javaType;
    /**
     * 列描述
     */
    private String columnDesc;
    /**
     * 是否主键
     */
    private boolean isPrimary;

    /**
     * 列类型转Java类型
     * @param dataType
     */
    public void setJavaType(String dataType) {
        MySqlDataTypeEnum mySqlDataTypeEnum = MySqlDataTypeEnum.valueOf(dataType.toUpperCase());
        switch (mySqlDataTypeEnum) {
            case INT:
                this.javaType = "Integer";
                break;
            case BIGINT:
                this.javaType = "Long";
                break;
            case DECIMAL:
                this.javaType = "BigDecimal";
                break;
            case DOUBLE:
                this.javaType = "Float";
                break;
            case FLOAT:
                this.javaType = "Double";
                break;
            case DATE:
            case DATETIME:
                this.javaType = "Date";
                break;
            case TIME:
                this.javaType = "Time";
                break;
            case TIMESTAMP:
                this.javaType = "Timestamp";
                break;
            case CHAR:
            case VARCHAR:
            case TEXT:
            case BLOB:
                this.javaType = "String";
                break;
            default:
                this.javaType = dataType;
                break;
        }
    }
}
package com.yx.limit.jpa.helper.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.List;

/**
 * 表格模型
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TableModel {
    /**
     * 表名
     */
    private String tableName;
    /**
     * 实体名
     */
    private String entityName;
    /**
     * 表描述
     */
    private String tableDesc;
    /**
     * 列信息集合
     */
    private List<ColumnModel> columnList;
}

5,使用c3p0编写一个数据库查询工具类

package com.yx.limit.jpa.helper.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mysql.cj.util.StringUtils;
import com.yx.limit.jpa.helper.model.ColumnModel;
import com.yx.limit.jpa.helper.model.TableModel;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

/**
 * 数据库表格生成工具类
 */
public class DbUtils {

    private DbUtils() {
    }

    private static ComboPooledDataSource cpds;
    private static Connection conn;
    private static Statement sta;
    private static ResultSet rs;

    /**
     * 构建数据库连接
     *
     * @return
     * @throws SQLException
     * @throws PropertyVetoException
     */
    private static Connection buildConnection() throws SQLException, PropertyVetoException {
        cpds = new ComboPooledDataSource();
        cpds.setDriverClass("com.mysql.cj.jdbc.Driver");
        cpds.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/limit-control?serverTimezone=GMT%2B8&characterEncoding=utf8&useSSL=false");
        cpds.setUser("root");
        cpds.setPassword("123456");
        // 得到一个Connection
        conn = cpds.getConnection();
        return conn;
    }

    /**
     * 执行sql脚本
     * @param sql
     * @return
     * @throws SQLException
     * @throws PropertyVetoException
     */
    private static ResultSet executeScript(String sql) throws SQLException, PropertyVetoException {
        conn = buildConnection();
        sta = conn.createStatement();
        rs = sta.executeQuery(sql);
        return rs;
    }

    /**
     * 关闭连接
     * @throws SQLException
     */
    private static void close() throws SQLException {
        rs.close();
        sta.close();
        conn.close();
        cpds.close();
    }

    /**
     * 封装表名、列名、列类型(初始化全量生成)
     * @param tablePrefix 表前缀,如传了表前缀生成的实体将忽略掉前缀部分
     * @return
     * @throws PropertyVetoException
     * @throws SQLException
     */
    public static List<TableModel> buildTableModelList(String tablePrefix) throws PropertyVetoException, SQLException {
        List<TableModel> tableList = new ArrayList<>();
        ResultSet rs = executeScript("show tables");
        while (rs.next()) {
            //表名
            String tableName = rs.getString(1);
            String entityName = tableName;
            if (!StringUtils.isNullOrEmpty(tablePrefix) && tablePrefix.startsWith(tablePrefix)) {
                entityName = entityName.substring(tablePrefix.length());
            }
            if ("hibernate_sequence".equals(tableName)) {
                continue;
            }
            tableList.add(new TableModel(tableName, toCamelCase(entityName, true), getTableComment(tableName), getColumnList(tableName)));
        }
        rs.close();
        close();
        return tableList;
    }

    /**
     * 根据表格名封装表名、列名、列类型
     * @param tablePrefix 表前缀,如传了表前缀生成的实体将忽略掉前缀部分
     * @param tableName 数据库表名称
     * @return
     * @throws PropertyVetoException
     * @throws SQLException
     */
    public static TableModel buildTableModel(String tablePrefix, String tableName) throws PropertyVetoException, SQLException {
        tableName = tableName.toLowerCase();
        String entityName = tableName;
        if (!StringUtils.isNullOrEmpty(tablePrefix) && tablePrefix.startsWith(tablePrefix)) {
            entityName = entityName.substring(tablePrefix.length());
        }
        String tableComment = getTableComment(tableName);
        List<ColumnModel> columnList = getColumnList(tableName);
        close();
        return new TableModel(tableName, toCamelCase(entityName, true), tableComment, columnList);
    }

    /**
     * 获取指定表格的描述
     *
     * @param tableName 数据库表名称
     * @return
     * @throws PropertyVetoException
     * @throws SQLException
     */
    private static String getTableComment(String tableName) throws PropertyVetoException, SQLException {
        String tableDesc = "";
        ResultSet rs = executeScript("SHOW TABLE STATUS WHERE Name = '" + tableName + "'");
        while (rs.next()) {
            //表名
            tableDesc = rs.getString("Comment");
        }
        rs.close();
        return tableDesc;
    }

    /**
     * 根据表名来返回该表对应列名和列类型
     *
     * @param tableName 数据库表名称
     * @return
     * @throws SQLException
     * @throws PropertyVetoException
     */
    private static List<ColumnModel> getColumnList(String tableName) throws PropertyVetoException, SQLException {
        List<ColumnModel> columnList = new ArrayList<>();
        ResultSet rs = executeScript("SELECT isc.COLUMN_NAME,isc.DATA_TYPE,isc.COLUMN_KEY,isc.COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS isc where isc.TABLE_NAME = '" + tableName + "'");
        while (rs.next()) {
            boolean isPrimary = false;
            String columnName = rs.getString("COLUMN_NAME").toLowerCase();
            String dataType = rs.getString("DATA_TYPE");
            String columnKey = rs.getString("COLUMN_KEY");
            if (!StringUtils.isNullOrEmpty(columnKey) && "PRI".equals(columnKey)) {
                isPrimary = true;
            }
            String columnComment = rs.getString("COLUMN_COMMENT");
            ColumnModel columnModel = new ColumnModel();
            columnModel.setColumnName(columnName);
            columnModel.setHumpColumnName(toCamelCase(columnName, false));
            columnModel.setColumnType(dataType);
            columnModel.setJavaType(dataType);
            columnModel.setColumnDesc(columnComment);
            columnModel.setPrimary(isPrimary);
            columnList.add(columnModel);
        }
        rs.close();
        return columnList;
    }

    /**
     * 数据库列名转驼峰命名
     *
     * @param fieldName 字段名称
     * @param allConvert 是否全部转换(控制首字母是否转大小写)
     * @return
     */
    private static String toCamelCase(String fieldName, boolean allConvert) {
        String[] words = fieldName.split("_");
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < words.length; i++) {
            if (i == 0 && !allConvert) {
                sb.append(words[i]);
            } else {
                String word = words[i].substring(0, 1).toUpperCase() + words[i].substring(1);
                sb.append(word);
            }
        }
        return sb.toString();
    }
}

6,代码生成工具类

package com.yx.limit.jpa.helper.utils;

import com.yx.limit.jpa.helper.model.ColumnModel;
import com.yx.limit.jpa.helper.model.TableModel;
import freemarker.template.Configuration;
import freemarker.template.Template;

import javax.swing.filechooser.FileSystemView;
import java.beans.PropertyVetoException;
import java.io.*;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * Jpa代码辅助工具类
 */
public class JpaAutoCodeUtils {
    //文件尾缀
    private final static String DTO_SUFFIX = "Dto";
    private final static String REPOSITORY_SUFFIX = "Repository";
    private final static String SERVICE_SUFFIX = "Service";
    private final static String SERVICE_IMPL_SUFFIX = "ServiceImpl";
    private final static String CONTROLLER_SUFFIX = "Controller";
    //模板名称
    private final static String ENTITY_FTL = "entity.ftl";
    private final static String DTO_FTL = "entity_dto.ftl";
    private final static String REPOSITORY_FTL = "repository.ftl";
    private final static String SERVICE_FTL = "service.ftl";
    private final static String SERVICE_IMPL_FTL = "service_impl.ftl";
    private final static String CONTROLLER_FTL = "controller.ftl";
    //过滤字段
    private final static String FILTER_FIELDS = "id,updateBy,updateTime,checkState,checkBy,checkTime";

    private JpaAutoCodeUtils() {
    }

    /**
     * 生成所有数据库表jpa代码
     *
     * @param tablePrefix 表格前缀
     * @throws PropertyVetoException
     * @throws SQLException
     */
    public static void allCodeGenerator(String tablePrefix) throws PropertyVetoException, SQLException {
        List<TableModel> tableList = DbUtils.buildTableModelList(tablePrefix);
        for (TableModel tableModel : tableList) {
            buildMetadata(tableModel);
        }
    }

    /**
     * 根据表名生成指定jpa代码
     *
     * @param tableName   表格名
     * @param tablePrefix 表格前缀
     * @throws PropertyVetoException
     * @throws SQLException
     */
    public static void codeGenerator(String tableName, String tablePrefix) throws PropertyVetoException, SQLException {
        TableModel tableModel = DbUtils.buildTableModel(tablePrefix, tableName);
        buildMetadata(tableModel);

    }

    /**
     * 构建元数据
     *
     * @param tableModel 表格模型
     */
    private static void buildMetadata(TableModel tableModel) {
        String entityName = tableModel.getEntityName();
        Map<String, Object> map = new HashMap<>();
        FileSystemView view = FileSystemView.getFileSystemView();
        String classPath = view.getHomeDirectory().getPath() + "\\autoCode";
        classPath = classPath.replace("C:\\", "").replace("\\", ".");
        Set<String> fieldTypes = tableModel.getColumnList().stream().map(ColumnModel::getJavaType).collect(Collectors.toSet());
        map.put("fieldTypes", fieldTypes);
        map.put("classPath", classPath);
        map.put("tableName", tableModel.getTableName());
        map.put("tableDesc", tableModel.getTableDesc());
        List<ColumnModel> fieldList = tableModel.getColumnList().stream().filter(column -> !FILTER_FIELDS.contains(column.getHumpColumnName())).collect(Collectors.toList());
        map.put("fieldList", fieldList);
        map.put("Entity", entityName);
        map.put(DTO_SUFFIX, entityName + DTO_SUFFIX);
        map.put(REPOSITORY_SUFFIX, entityName + REPOSITORY_SUFFIX);
        map.put(SERVICE_SUFFIX, entityName + SERVICE_SUFFIX);
        map.put(SERVICE_IMPL_SUFFIX, entityName + SERVICE_IMPL_SUFFIX);
        map.put(CONTROLLER_SUFFIX, entityName + CONTROLLER_SUFFIX);
        map.put("List", "List");
        map.put("PageVo", "PageVo");

        processTemplate(map, ENTITY_FTL, entityName + ".java");
        processTemplate(map, DTO_FTL, entityName + DTO_SUFFIX + ".java");
        processTemplate(map, REPOSITORY_FTL, entityName + REPOSITORY_SUFFIX + ".java");
        processTemplate(map, SERVICE_FTL, entityName + SERVICE_SUFFIX + ".java");
        processTemplate(map, SERVICE_IMPL_FTL, entityName + SERVICE_IMPL_SUFFIX + ".java");
        processTemplate(map, CONTROLLER_FTL, entityName + CONTROLLER_SUFFIX + ".java");
    }

    /**
     * 模板处理
     *
     * @param dataMap  模板中的参数键值
     * @param ftlName  模板ftl文件
     * @param fileName 生成的文件名称
     */
    private static void processTemplate(Map<String, Object> dataMap, String ftlName, String fileName) {
        //创建freeMarker配置实例
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_23);
        Writer out = null;
        try {
            //获取模版路径
            configuration.setDirectoryForTemplateLoading(new File("src/main/resources/ftl"));
            //加载模版文件
            Template template = configuration.getTemplate(ftlName);
            //生成数据
            FileSystemView view = FileSystemView.getFileSystemView();
            String classPath = view.getHomeDirectory().getPath() + "/autoCode";
            File newDir = new File(classPath);
            File newFile = new File(newDir, fileName);
            if (!newDir.exists()) {
                newDir.mkdirs();
                newFile.createNewFile();
            }
            out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(newFile)));
            //输出文件
            template.process(dataMap, out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != out) {
                    out.flush();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }
        }
    }
}

7,模板文件

controller

<#if classPath??>
package ${classPath};
</#if>

import com.yx.limit.base.vo.PageVo;
import com.yx.limit.base.vo.ResponseVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@Api(tags = {"${tableDesc}前端控制器"})
@RestController
public class ${Controller} {
    private final ${Service} ${Service ? uncap_first};

    public ${Controller}(${Service} ${Service ? uncap_first}) {
        this.${Service ? uncap_first} = ${Service ? uncap_first};
    }

    @ApiOperation(value = "查询所有${tableDesc}")
    @GetMapping("/findAll${Entity}")
    public ResponseVo<${List}<${Entity}>> findAll${Entity}() {
        List<${Entity}> allList = ${Service ? uncap_first}.findAll${Entity}();
        return ResponseVo.success(allList);
    }

    @ApiOperation(value = "分页查询${tableDesc}")
    @PostMapping("/find${Entity}ByPage")
    public ResponseVo<${PageVo}<${Entity}>> find${Entity}ByPage(@RequestBody ${Dto}  ${Dto ? uncap_first}) {
        PageVo<${Entity}> pageVo = ${Service ? uncap_first}.find${Entity}ByPage(${Dto ? uncap_first});
        return ResponseVo.success(pageVo);
    }

    @ApiOperation(value = "新增${tableDesc}")
    @PostMapping("/add${Entity}")
    public ResponseVo add${Entity}(@RequestBody ${Entity} ${Entity ? uncap_first}) {
        ${Service ? uncap_first}.add${Entity}(${Entity ? uncap_first});
        return ResponseVo.success();
    }

    @ApiOperation(value = "删除${tableDesc}")
    @PostMapping("/delete${Entity}")
    public ResponseVo delete${Entity}(@RequestBody ${Dto} ${Dto ? uncap_first}) {
        ${Service ? uncap_first}.delete${Entity}(${Dto ? uncap_first}.getIds());
        return ResponseVo.success();
    }
}

entity

<#if classPath??>
package ${classPath};
</#if>

import com.yx.light.element.jpa.entity.base.BaseModel;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Table;
<#list fieldTypes as m>
<#if m = "Date">
import java.util.Date;
</#if>
<#if m = "BigDecimal">
import java.math.BigDecimal;
</#if>
</#list>

@Data
@Entity
@Table(name = "${tableName}")
@ApiModel(value = "${Entity}对象", description = "${tableDesc}")
public class ${Entity} extends BaseModel {

<#list fieldList as m>
    @Column(name = "${m.columnName}")
    @ApiModelProperty(value = "${m.columnDesc}")
    private ${m.javaType} ${m.humpColumnName};

</#list>
}

dto

<#if classPath??>
package ${classPath};
</#if>

import com.yx.limit.base.dto.PageDto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
@ApiModel(value = "${Dto}对象", description = "${tableDesc}查询实体")
public class ${Dto} extends PageDto {

    @ApiModelProperty(value = "id串用,隔开")
    private String ids;

    @ApiModelProperty(value = "最后更新时间开始")
    private String updateTimeFrom;

    @ApiModelProperty(value = "最后更新时间截止")
    private String updateTimeTo;

    @ApiModelProperty(value = "审核时间开始")
    private String checkTimeFrom;

    @ApiModelProperty(value = "审核时间截止")
    private String checkTimeTo;
}

dao

<#if classPath??>
package ${classPath};
</#if>

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;

@Repository
public interface ${Repository} extends JpaRepository<${Entity}, Long>, JpaSpecificationExecutor<${Entity}> {
}

service

<#if classPath??>
package ${classPath};
</#if>

import com.yx.limit.base.vo.PageVo;

import java.util.List;

public interface ${Service} {

    List<${Entity}> findAll${Entity}();

    PageVo<${Entity}> find${Entity}ByPage(${Dto} ${Dto ? uncap_first});

    void add${Entity}(${Entity} ${Entity ? uncap_first});

    void edit${Entity}(${Entity} ${Entity ? uncap_first});

    void delete${Entity}(String ids);
}

serviceImpl

<#if classPath??>
package ${classPath};
</#if>

import com.yx.limit.base.vo.PageVo;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ${ServiceImpl} implements ${Service} {
    private final ${Repository} ${Repository ? uncap_first};

    public ${ServiceImpl}(${Repository} ${Repository ? uncap_first}) {
        this.${Repository ? uncap_first} = ${Repository ? uncap_first};
    }

    @Override
    public List<${Entity}> findAll${Entity}() {
        return ${Repository ? uncap_first}.findAll();
    }

    @Override
    public PageVo<${Entity}> find${Entity}ByPage(${Dto} ${Dto ? uncap_first}) {
        return null;
    }

    @Override
    public void add${Entity}(${Entity} ${Entity ? uncap_first}) {
        ${Repository ? uncap_first}.save(${Entity ? uncap_first});
    }

    @Override
    public void edit${Entity}(${Entity} ${Entity ? uncap_first}) {

    }

    @Override
    public void delete${Entity}(String ids) {
        String[] split = ids.split(ConstantEnum.COMMA.getValue());
        for (String id : split) {
            ${Repository ? uncap_first}.deleteById(Long.parseLong(id));
        }
    }
}

8,编写一个测试类

import com.yx.limit.jpa.helper.model.TableModel;
import com.yx.limit.jpa.helper.utils.DbUtils;
import com.yx.limit.jpa.helper.utils.JpaAutoCodeUtils;
import org.junit.Test;

import java.beans.PropertyVetoException;
import java.sql.SQLException;
import java.util.List;

/**
 * 测试类
 */
public class JpaHelperTest {

    @Test
    public void buildTableTest() throws PropertyVetoException, SQLException {
        List<TableModel> tableModelList = DbUtils.buildTableModelList("t_");
        TableModel tableModel = DbUtils.buildTableModel("t_", "t_port_info");
    }

    @Test
    public void codeGeneratorTest() throws PropertyVetoException, SQLException {
        JpaAutoCodeUtils.codeGenerator("t_index_info","t_");
//        JpaAutoCodeUtils.allCodeGenerator("t_");
    }
}

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OpenJPA 使用的是 JPA (Java Persistence API) 规范,因此可以使用 JPA 提供的 @GeneratedValue 注解来生成唯一 ID。 以下是一个示例代码: ``` import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "my_entity") public class MyEntity { @Id @GeneratedValue private Long id; // 其他属性和方法 } ``` 在上面的代码中,我们使用了 `@Id` 注解来指定 ID 字段,并使用 `@GeneratedValue` 注解来指示 ID 是由 JPA 自动生成的。 需要注意的是,OpenJPA 的实现可能会有所不同,因此最好参考 OpenJPA 的文档来了解更详细的信息。 ### 回答2: OpenJPAJava持久化API的一种实现,它提供了一种简便的方式来管理和操作数据库中的数据。 在OpenJPA中,如果我们希望在插入实体对象时自动生成唯一的ID,可以使用自定义的ID生成器代码。下面是一个示例: 1. 首先,我们需要创建一个实现OpenJPA `org.apache.openjpa.persistence.OpenJPAId`接口的ID生成器类。该接口要求实现`Object toOpenJPAId(String str)`方法和`String toStringId(Object obj)`方法。 ```java import org.apache.openjpa.persistence.OpenJPAId; public class CustomIdGenerator implements OpenJPAId { private Long id; public CustomIdGenerator(Long id) { this.id = id; } public static CustomIdGenerator fromOpenJPAId(String str) { Long id = Long.parseLong(str); return new CustomIdGenerator(id); } public String toOpenJPAId() { return id.toString(); } } ``` 2. 接下来,我们需要在实体类中使用自定义ID生成器。假设我们有一个名为`Person`的实体类。 ```java import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Person { @Id @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "custom-id") private CustomIdGenerator id; // Other fields and methods } ``` 在`@GeneratedValue`注解中,我们指定了使用`IDENTITY`策略,并且将生成器命名为"custom-id"。这样,当我们插入`Person`对象时,OpenJPA会调用`CustomIdGenerator`类的方法来生成唯一的ID。 3. 最后,我们需要在persistence.xml文件中配置自定义ID生成器。 ```xml <persistence-unit name="myPersistentUnit"> <properties> <property name="openjpa.Id" value="custom-id"/> </properties> </persistence-unit> ``` 在persistence.xml文件中,我们指定使用名为"custom-id"的ID生成器。 通过上述的代码和配置,我们可以实现自定义的ID生成器,并在OpenJPA中使用它来生成唯一的ID。 ### 回答3: 在OpenJPA中,可以使用唯一ID生成器来生成唯一的实体对象ID。以下是一个使用OpenJPA唯一ID生成器的示例代码: 首先,需要定义一个实体类,例如User: ```java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(generator = "uuid-gen") @Column(name = "id") private String id; // 其他属性和方法 } ``` 在上述代码中,使用`@GeneratedValue(generator = "uuid-gen")`注解来指定使用唯一ID生成器生成实体的ID。 然后,需要设置唯一ID生成器的配置。在持久化单元的配置文件(例如`persistence.xml`)中,添加如下代码: ```xml <persistence-unit name="myPersistenceUnit"> <!-- 其他配置 --> <properties> <property name="openjpa.Id" value="uuid-gen"/> <property name="openjpa.Id.UUID" value="true"/> </properties> </persistence-unit> ``` 在上述代码中,通过`<property name="openjpa.Id" value="uuid-gen"/>`将唯一ID生成器配置为使用UUID生成器。 最后,可以通过以下代码创建和保存实体对象: ```java EntityManagerFactory emf = Persistence.createEntityManagerFactory("myPersistenceUnit"); EntityManager em = emf.createEntityManager(); em.getTransaction().begin(); User user = new User(); // 设置其他属性 em.persist(user); em.getTransaction().commit(); em.close(); emf.close(); ``` 在上述代码中,通过`em.persist(user)`将实体对象保存到数据库中,此时会自动生成唯一的ID。 通过以上代码示例,您可以在OpenJPA中使用唯一ID生成器来生成实体对象的唯一ID。请注意,上述示例中使用了UUID生成器,您也可以尝试其他类型的唯一ID生成器,如自增长ID生成器等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值