SpringBoot集成Mybatis-Plus

简介

MyBatis-Plus(简称 MP)是一个 MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

使用 MyBatis-Plus 时,它提供了许多内置的功能,如 CRUD 操作、分页插件、性能分析插件等,可以大大简化数据库操作代码。

因此,mybatis-plus包含mybatis的所有功能,因此无需再次引入mybatis。

MyBatis-Plus官网地址:https://baomidou.com

寄语

很多小伙伴在引入MyBatis后,发现在Controller层就能直接实现CRUD,于是就把所有代码都写在了Controller层中,这样写确实能达到目的,但还是要看情况;尽管 MyBatis-Plus 提供了很多便利的功能,但这并不意味着你可以完全抛弃 Service 层。Service 层在项目中扮演着非常重要的角色,它负责处理业务逻辑、封装服务、实现代码解耦等。即便使用 MyBatis-Plus,也建议根据项目实际情况和需求来决定是否使用 Service 层。在大多数情况下,使用 Service 层可以提高代码的可维护性、可读性和可扩展性。

需要 Service 层的情况

  1. 业务逻辑处理:即使使用了 MyBatis-Plus,业务逻辑仍然需要在 Service 层处理。这包括数据验证、业务规则检查、事务管理等。
  2. 服务封装:Service 层可以封装多个 Mapper 的操作,提供更高层次的服务接口,使得 Controller 层调用更加简单。
  3. 代码解耦:将业务逻辑放在 Service 层可以实现 Controller 层和 DAO 层的解耦,便于维护和扩展。
  4. 单元测试:Service 层更容易进行单元测试,因为你可以模拟依赖项并专注于业务逻辑的测试。

不需要 Service 层的情况

  1. 简单 CRUD 应用:如果你的应用非常简单,只涉及基本的 CRUD 操作,并且没有复杂的业务逻辑,那么可能不需要 Service 层。
  2. 快速原型开发:在快速原型开发阶段,为了加速开发过程,有时可能直接在 Controller 层调用 MyBatis-Plus 提供的 CRUD 方法。
  3. 代码量较小的项目:对于非常小的项目,为了简化代码结构,可能会选择不在 Service 层编写代码。

功能

无侵入

只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑

损耗小

启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作

强大的 CRUD 操作

内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求

支持 Lambda 形式调用

通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错

支持主键自动生成

支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题

支持 ActiveRecord 模式

支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作

支持自定义全局通用操作

支持全局通用方法注入( Write once, use anywhere )

内置代码生成器

采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用

内置分页插件

基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询

分页插件支持多种数据库

支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库

内置性能分析插件

可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询

内置全局拦截插件

提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

添加依赖

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.1</version>
</dependency>

添加配置

# Mybatis-plus配置
mybatis-plus:
  global-config:
    db-config:
      # 全局逻辑删除字段值,或在实体字段加上注解@TableLogic  都会当做逻辑删除字段,优先按照注解来判断
      logic-delete-field: delFlag
      logic-delete-value: 2  # 逻辑已删除值
      logic-not-delete-value: 0 # 逻辑未删除值
  # 配置mapper的扫描,找到所有的mapper.xml映射文件
  mapper-locations: classpath*:mapper/**/*Mapper.xml
  configuration:
    # 使全局的映射器启用或禁用缓存
    cache-enabled: true
    # 允许JDBC 支持自动生成主键
    use-generated-keys: true
    # 指定 MyBatis 所用日志的具体实现
    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
    # 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新
    default-executor-type: reuse
    # 使用驼峰命名法转换字段
    map-underscore-to-camel-case: true
  # 搜索指定包别名
  type-aliases-package: com.cn.**.domain

生成主键策略

全局id生成策略

mybatis-plus:
  global-config:
    db-config:
      #主键类型(auto:"自增id",assign_id:"全局唯一id(雪花算法,Long或者String类型)",assign_uuid:"全局唯一id(无中划线的uuid)",input:"自行设置id,默认null",none:"不设置主键id")
      id-type: assign_id

局部id生成策略

使用@TableId注解配置id生成类型

@TableId(type = IdType.AUTO)
private Long id;

注意事项:

  • 同时配置了这两种策略时,局部字段的ID生成策略优先级高于全局的id生成策略

  • 使用雪花算法生成ID后,再次切换为主键自增的ID生成策略后会导致起始序列过大(没有重置起始序列值)

  • 另外如果原先指定了@TableId(type = IdType.AUTO),然后去除这部分代码,会发生Tuncate操作(即清空表并重置ID起始值)

分页插件使用

/**
 * Mybatis-plus配置类
 */
@EnableTransactionManagement
@Configuration
// 根据实际情况修改扫描包路径规则
@MapperScan(basePackages = "com.cn.**.mapper)
public class MybatisPlusConfig {

    /**
     * Mybatis-Plus 3.5.1新版分页插件API(推荐)
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //乐观锁
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        //分页锁
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }
}

元数据处理

mybatis-plus处理公共字段-自定义元数据对象处理器。

@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        Timestamp time=new Timestamp(System.currentTimeMillis());
        this.setFieldValByName("createTime", time, metaObject);
        this.setFieldValByName("createBy", SecurityUtils.getUsername(), metaObject);
        this.setFieldValByName("delFlag", 0, metaObject);
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        Timestamp time=new Timestamp(System.currentTimeMillis());
        this.setFieldValByName("updateTime", time, metaObject);
        this.setFieldValByName("updateBy", SecurityUtils.getUsername(), metaObject);
    }
}

实体类对应的公共字段添加注解标注

public class BaseEntity{
    /**创建时间*/
    @TableField(fill = FieldFill.INSERT)
    private LocalDateTime createTime;
    /** 创建者 */
    @TableField(fill = FieldFill.INSERT)
    private String createBy;
    /**更新时间*/
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private LocalDateTime updateTime;
    /** 更新者 */
    @TableField(fill = FieldFill.INSERT_UPDATE)
    private String updateBy;
}

字段数据加密

添加数据库加解密处理类,指明加解密字段类型

package com.cn.handlers;

@MappedJdbcTypes(JdbcType.VARCHAR)
public class EncryptHandler extends BaseTypeHandler<String> {
    /**
     * 线上运行后勿修改,会影响已加密数据解密
     * AES密钥为对称密钥,密钥的长度可以为16字节、24字节、32字节
     */
    private static final byte[] KEYS = "shc987654321camp".getBytes(StandardCharsets.UTF_8);

    /**
     * 设置参数
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
        if (StringUtils.isEmpty(parameter)) {
            ps.setString(i, null);
            return;
        }
        AES aes = SecureUtil.aes(KEYS);
        String encrypt = aes.encryptHex(parameter);
        ps.setString(i, encrypt);
    }

    /**
     * 获取值
     */
    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return decrypt(rs.getString(columnName));
    }

    /**
     * 获取值
     */
    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return decrypt(rs.getString(columnIndex));
    }

    /**
     * 获取值
     */
    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return decrypt(cs.getString(columnIndex));
    }

    public String decrypt(String value) {
        if (null == value) {
            return null;
        }
        return SecureUtil.aes(KEYS).decryptStr(value);
    }
}

在需要加密存储的数据库表字段上添加typeHandler指定处理器,且必须开启autoResultMap = true

关于 autoResultMap 的说明
autoResultMap是mybatis中的一个配置项,当为true时,mybatis会根据查询结果的列名和结果对象的属性名进行自动映射。如果列名和属性名一致,那么mybatis会自动将查询结果的值赋给结果对象的对应属性。

MyBatis Plus 会自动构建一个 ResultMap 并注入到 mybatis 里(一般用不上)。
因为 MyBatis Plus 底层是 mybatis,所以一些 mybatis 的常识你要知道,MyBatis Plus 只是帮你注入了常用 crud 到 mybatis 里。注入之前可以说是动态的(根据你 entity 的字段以及注解变化而变化),但是注入之后是静态的(等于你写在 xml 的东西)而对于直接指定typeHandler,mybatis 只支持你写在2个地方:

1、定义在 resultMap 里,只作用于 select 查询的返回结果封装
2、定义在 insert 和 update sql 的 #{property} 里的 property 后面(例:#{property,typehandler=xxx.xxx.xxx}),只作用于设置值而除了这两种直接指定 typeHandler,mybatis 有一个全局的扫描你自己的 typeHandler 包的配置,这是根据你的 property的类型去找 typeHandler 并使用。

@TableName(value = "user", autoResultMap = true)
@Data
public class User implements Serializable {
    /**
     * 加密敏感信息-地址
     */
    @TableField(value = "address", typeHandler = EncryptHandler.class)
    private String address;
}

条件构造器使用

mybatis-plus中有查询条件构造器QueryWrapper,可以在对常见的CRUD条件进行一些常见的构造,真实API在AbstractWrapper类中(采用了工厂模式进行顶层API设计)。

可以封装sql对象,包括where条件,order by排序,select哪些字段等等 查询包装类,可以封装多数查询条件,泛型指定返回的实体类。

public class Test{
    /**
     *  条件构造器使用
     */
    @DeleteMapping("/delete")
    public void delUser(){
        // 1. 根据ID删除
        userMapper.deleteById(6);
        userMapper.deleteBatchIds(Collections.singleton(7));
        // 2. 根据map中的参数作为条件删除
        Map<String, Object> map = new HashMap<>();
        map.put("name", "testIdType");
        map.put("id", 7);
        userMapper.deleteByMap(map);
        // 3. 条件构造器为参数的进行删除
        // 3.1 普通条件构造器(注意不要添加<>,Entity转Object会报错)
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("id",6);
        userMapper.delete(wrapper);
        // 3.2 lmbda表达式条件构造器
        LambdaQueryWrapper<User> lambdaQuery = Wrappers.lambdaQuery();
        lambdaQuery.eq(User::getId, 7).or().eq(User::getName, "testIdType");
        userMapper.delete(lambdaQuery);
    }
}

实现逻辑删除之后怎么实现物理删除

切换物理删除方式:把实体类中的逻辑删除字段删掉即可

1、直接去手动写sql去实现

2、写一个公共的MyBaseMapper去继承BaseMapper,然后定义一个deleteAbsoluteById()方法。后面各个业务的mapper可以通过继承MyBaseMapper来使用。

public interface MyBaseMapper<T> extends BaseMapper<T> {
    /**
     * 物理删除
     *
     * @param id
     * @return
     */
    int deleteAbsoluteById(Serializable id);
    /**
     * 批量物理删除
     *
     * @param idList
     * @return
     */
    int deleteAbsoluteByIds(@Param(Constants.COLL) Collection<?> idList);
    /**
    * 查询包含被逻辑删除的数据
    * @param queryWrapper
    * @return
    */
    List<T> selectListData(@Param("ew") Wrapper<T> queryWrapper);
}

然后建一个实现类继承AbstractMethod,去实现相关逻辑

public class DeleteAbsoluteById extends AbstractMethod {

    public DeleteAbsoluteById() {
        super(SqlMethod.DELETE_BY_ID.getMethod());
    }

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        String method = "deleteAbsoluteById";
        SqlMethod sqlMethod = SqlMethod.DELETE_BY_ID;
        String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), tableInfo.getKeyColumn(), tableInfo.getKeyProperty());
        SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, Object.class);
        return this.addDeleteMappedStatement(mapperClass, method, sqlSource);
    }
}

public class DeleteAbsoluteByIds extends AbstractMethod {

    public DeleteAbsoluteById() {
        super(SqlMethod.DELETE_BATCH_BY_IDS.getMethod());
    }

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        String method = "deleteAbsoluteByIds";
        SqlMethod sqlMethod = SqlMethod.DELETE_BATCH_BY_IDS;
        String sql = String.format(sqlMethod.getSql(), tableInfo.getTableName(), tableInfo.getKeyColumn(), SqlScriptUtils.convertForeach(SqlScriptUtils.convertChoose("@org.apache.ibatis.type.SimpleTypeRegistry@isSimpleType(item.getClass())", "#{item}", "#{item." + tableInfo.getKeyProperty() + "}"), "coll", (String) null, "item", ","));
        SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, Object.class);
        return this.addDeleteMappedStatement(mapperClass, method, sqlSource);
    }
}

public class SelectListData extends AbstractMethod {
    public SelectListData(){
        super(SqlMethod.SELECT_LIST.getMethod());
    }

    @Override
    public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
        String method = "selectListData";
        SqlMethod sqlMethod = SqlMethod.SELECT_LIST;
        String sqlWhere = sqlWhereEntityWrapper(true, tableInfo).replaceAll("del_flag='0'", "1=1");
        String sql = String.format(sqlMethod.getSql(), sqlFirst(), sqlSelectColumns(tableInfo, true), tableInfo.getTableName(), sqlWhere, sqlOrderBy(tableInfo), sqlComment());
        SqlSource sqlSource = this.languageDriver.createSqlSource(this.configuration, sql, modelClass);
        return this.addSelectMappedStatementForTable(mapperClass, method, sqlSource, tableInfo);
    }
}

再自定义一个sql注入器继承DefaultSqlInjector,把DeleteAbsoluteById(),DeleteAbsoluteByIds()方法加入进去就大功告成。

public class CustomSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
        methodList.add(new DeleteAbsoluteById());
        methodList.add(new DeleteAbsoluteByIds());
        methodList.add(new SelectListData());
        return methodList;
    }
}

代码生成器使用

说明:freemarker是作为代码生成器的模板依赖,必须存在;而knife4j是兼容生成的代码带Swagger注释

引入依赖

<!-- mybatis-plus代码生成器 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.5.1</version>
</dependency>
<!--velocity代码生成使用模板 -->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity</artifactId>
    <version>1.7</version>
</dependency>
<!-- swagger依赖 -->
<dependency>
    <groupId>com.github.xiaoymin</groupId>
    <artifactId>knife4j-spring-boot-starter</artifactId>
    <version>3.0.3</version>
</dependency>

代码实现

注意
适用版本:mybatis-plus-generator 3.5.1 及其以上版本,对历史版本不兼容!3.5.1 以下的请参考 代码生成器旧

public class MybatisPlusGenerator {

    /**
     * 执行 run
     */
    public static void main(String[] args) {
        String packageName = "com.cn",author = "hviger";
        generateConfig("test","user",author,packageName);
    }

    private static void generateConfig(String context,String tableName,String author,String packageName){
        FastAutoGenerator.create(DATA_SOURCE_CONFIG.getUrl(),DATA_SOURCE_CONFIG.getUsername(),DATA_SOURCE_CONFIG.getPassword())
                // 全局配置
                .globalConfig(builder -> {
                    builder // (重要)配置后再次执行覆盖原有文件,建议配置
                            .fileOverride()
                            // (重要)配置输出的文件夹,springboot项目可以使用如下方式
                            .outputDir(System.getProperty("user.dir") + "/src/main/java")
                            // (重要)时间类型
                            .dateType(DateType.TIME_PACK)
                            // 配置生成文件中的author
                            .author(author)
                            // 是否启用kotlin单例模式
                            // .enableKotlin()
                            // 是否启用swagger,比如启用后会在entity中自动生成字段ApiModel注释等等
                            .enableSwagger()
                            // 注释日期的格式
                            .commentDate("yyyy-MM-dd")
                            // 禁止打开目录
                            .disableOpenDir()
                            .build();
                })
                // 包配置
                .packageConfig(builder -> {
                    builder.parent(packageName)   // 设置父包名
                            .moduleName(null)  // 设置父包模块名
                            .controller("controller")
                            .entity("entity")
                            .service("service")
                            .serviceImpl("service.impl")
                            // .xml("mapper.xml")  //默认方式是存储在mapper/xml目录
                            .pathInfo(Collections.singletonMap(OutputFile.mapperXml, System.getProperty("user.dir") + "/src/main/resources/mapper")) // 设置mapperXml生成路径
                            .mapper("mapper");
                })
                // 策略配置
                .strategyConfig(builder -> {
                    builder
                            // 表名,多个英文逗号分隔?所有输入 all
                            .addInclude(tableName)
                            // .addTablePrefix("t_", "c_") // 设置过滤表前缀
                            // 跳过视图的生成
                            .enableSkipView()
                            .entityBuilder()
                            .enableLombok()
                            // (重要)主键模式,这里设置自动模式,配合mysql的自增主键
                            .idType(IdType.AUTO)
                            // entity文件名,可以配置统一后缀:%sEntity
                            .formatFileName("%s")
                            // activeRecord模式,可以直接在entity对象上执行insert、update等操作
                            .enableActiveRecord()
                            .build();
                    // builder.entityBuilder().superClass(BaseEntity.class).addSuperEntityColumns("createBy","createTime","update_by","update_time");
                    builder.mapperBuilder().enableMapperAnnotation().build();// 为mapper添加mapper注释
                    builder.controllerBuilder().enableHyphenStyle().enableRestStyle();//开启驼峰转连字符,开启@restController控制器
                })
                // 注入配置
                .injectionConfig((builder -> {
                    //自定义对象,如果配置自定义模板就通过这样传参
                    Map<String,Object> map = new HashMap<>();
                    map.put("packageName",packageName);
                    map.put("datetime", DateTime.now());
                    map.put("context", context);         //@RequestMapping("test")
                    // 排除父类字段
                    map.put("list", new String[]{"create_by","create_time","update_by","update_time"});

                    setAttr(tableName, map);

                    builder.customMap(map);
                }))
                /*
                    模板引擎配置,默认 Velocity(vm) 可选模板引擎 Beetl(btl) 或 Freemarker(ftl) 或 Enjoy(html)
                    还需要引用相关的依赖
                   .templateEngine(new BeetlTemplateEngine())
                   .templateEngine(new FreemarkerTemplateEngine())
                   .templateEngine(new EnjoyTemplateEngine())
                 */
                .templateEngine(new VelocityTemplateEngine())
                .templateConfig(builder -> {
                    builder
                            .controller("vm/java/controller.java.vm")
                            .entity("vm/java/entity.java.vm")
                            .service("vm/java/service.java.vm")
                            .serviceImpl("vm/java/serviceImpl.java.vm")
                            .mapper("vm/java/mapper.java.vm")
                            .mapperXml("vm/xml/mapper.xml.vm");
                })
                .execute();
    }
    /**
     * 数据源配置
     */
    private static final DataSourceConfig DATA_SOURCE_CONFIG = new DataSourceConfig
            .Builder("jdbc:mysql://localhost:3306/user_service?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8","root","123456")
            .build();
    /**
     * 组装模板属性
     *
     * @param tableName  表名
     * @param map        模板里面 自定义的属性
     */
    private static void setAttr(String tableName,Map<String, Object> map ){
        List<Map<String, Object>> columns = new ArrayList<>();
        // 获取表信息sql
        String tableSql = "select table_name , table_comment from information_schema.tables where table_schema = (select database()) and table_name = '" + tableName + "'";
        // 获取字段信息sql
        String columnSql = "select column_name , data_type ,column_key, column_comment from information_schema.columns " +
                "where table_name = '" + tableName + "' and table_schema = (select database()) and column_name != 'id_new'";
        // 利用现有的dataSourceConfig来获取数据库连接,查询表字段及备注等信息
        try(
                Connection conn = DATA_SOURCE_CONFIG.getConn();
                PreparedStatement psTable = conn.prepareStatement(tableSql);
                ResultSet rsTable = psTable.executeQuery();
                PreparedStatement pscolumns= conn.prepareStatement(columnSql);
                ResultSet rscolumns = pscolumns.executeQuery();
        ){
            if(rsTable.next()){
                String table_name = rsTable.getString("table_name");
                map.put("tableName",table_name);
                map.put("modelName",rsTable.getString("table_comment"));
                // 类名 大驼峰
                map.put("ClassName", StrUtil.upperFirst(StrUtil.toCamelCase(table_name)));
                // 对象名 小驼峰
                map.put("className",StrUtil.toCamelCase(table_name));
            }
            while (rscolumns.next()){
                Map<String, Object> columnMap = new HashMap<>();
                // 列名字、数据类型、java属性名字、java属性类型、备注
                columnMap.put("name",rscolumns.getString("column_name"));
                columnMap.put("dataType",rscolumns.getString("data_type"));
                columnMap.put("javaField",StrUtil.toCamelCase(rscolumns.getString("column_name")));
                columnMap.put("javaType",columnTypeToJavaType(rscolumns.getString("data_type")));
                columnMap.put("comment", rscolumns.getString("column_comment"));
                columns.add(columnMap);

                Map<String, Object> pkColumn = new HashMap<>();
                String columnKey = rscolumns.getString("column_key");
                if("PRI".equals(columnKey)){
                    pkColumn.put("javaField",columnMap.get("javaField"));
                    pkColumn.put("javaType",columnMap.get("javaType"));
                    map.put("pkColumn", pkColumn);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        map.put("columns",columns);
    }

    /**
     * 数据库类型转换为java类型
     *
     * @param columnType 数据库类型
     * @return java类型
     */
    private static String columnTypeToJavaType(String columnType) {
        if(StrUtil.isNotEmpty(columnType)){
            if(Arrays.asList(GenerateConstant.COLUMN_TYPE_STR).contains(columnType)){
                return GenerateConstant.TYPE_STRING;
            }
            if(Arrays.asList(GenerateConstant.COLUMN_TYPE_TIME).contains(columnType)){
                return GenerateConstant.TYPE_DATE;
            }
            if (Arrays.asList(GenerateConstant.COLUMN_TYPE_NUMBER).contains(columnType)) {
                return GenerateConstant.TYPE_INTEGER;
            }
            if (Arrays.asList(GenerateConstant.COLUMN_TYPE_BIGINT).contains(columnType)) {
                return GenerateConstant.TYPE_LONG;
            }
            if (Arrays.asList(GenerateConstant.COLUMN_TYPE_FLOAT).contains(columnType)) {
                return GenerateConstant.TYPE_DOUBLE;
            }
            if (Arrays.asList(GenerateConstant.COLUMN_TYPE_DOUBLE).contains(columnType)) {
                return GenerateConstant.TYPE_DOUBLE;
            }
            if (Arrays.asList(GenerateConstant.COLUMN_TYPE_DECIMAL).contains(columnType)) {
                return GenerateConstant.TYPE_BIGDECIMAL;
            }
        }
        return  null;
    }
}
public class GenerateConstant {
    /**
     * 数据库字符串类型
     */
    public static final String[] COLUMN_TYPE_STR =  {"char", "varchar", "nvarchar", "varchar2", "tinytext", "text", "mediumtext", "longtext"};
    /**
     * 数据库时间类型
     */
    public static final String[] COLUMN_TYPE_TIME = {"datetime", "time", "date", "timestamp"};
    /**
     * 数据库数字类型
     */
    public static final String[] COLUMN_TYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "number", "integer", "bit"};
    /**
     * 数据库bigint类型
     */
    public static final String[] COLUMN_TYPE_BIGINT = {"bigint"};
    /**
     * 数据库float类型
     */
    public static final String[] COLUMN_TYPE_FLOAT = {"float"};
    /**
     * 数据库double类型
     */
    public static final String[] COLUMN_TYPE_DOUBLE = {"double"};
    /**
     * 数据库decimal类型
     */
    public static final String[] COLUMN_TYPE_DECIMAL = {"decimal"};

    /**
     * 字符串类型
     */
    public static final String TYPE_STRING = "String";

    /**
     * 整型
     */
    public static final String TYPE_INTEGER = "Integer";

    /**
     * 长整型
     */
    public static final String TYPE_LONG = "Long";

    /**
     * 浮点型
     */
    public static final String TYPE_DOUBLE = "Double";

    /**
     * 高精度计算类型
     */
    public static final String TYPE_BIGDECIMAL = "BigDecimal";

    /**
     * 时间类型
     */
    public static final String TYPE_DATE = "Date";
}

VM模板地址

下载VM模板

生成的包结构

image

image

posted @ 2022-09-26 10:52  zhαojh  阅读(223)  评论(0编辑  收藏  举报