MybatisPlus—kotlin代码生成
javascript吧
全部回复
仅看楼主
level 1
1、什么是Kotlin?
Kotlin是一个基于JVM的新的编程语言,2010年由IntelliJ IDEA所在的JetBrains公司开发,自2012年以来一直开源。
Kotlin可以编译成Java字节码,也可以编译成JavaScript,方便在没有JVM的设备上运行。
Kotlin是面向对象和功能编程功能的JVM和Android的通用、开源、静态的实用的编程语言。它专注于交互性、安全性及清晰度和工具的支持。
2、Kotlin特点
1、简洁: 大大减少样板代码的数量。
2、安全: 避免空指针异常等整个类的错误。
3、互操作性: 充分利用 JVM、Android 和浏览器的现有库。
4、工具友好: 可用任何 Java IDE 或者使用命令行构建。
3、MybatisPlus
MyBatisPlus(简称 MP)是一个MyBatis的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
4、MybatisPlus的特点
无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作
5、使用Kotlin代码生成
首先是mybatis-plus的依赖:
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.3.2</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>
下面进入正题:
看官网上的关键点:
效果图:
代码示例:
GeneratorFactory.kt
//程序入口 fun main(args: Array<String>) { generator() } //代码生成方法 fun generator(){ println("begin generating") val projectPath = System.getProperty("user.dir") var mpg = AutoGenerator() //全局配置 var globalConfig = GlobalConfig() globalConfig.isKotlin = true //关键点使用kotlin globalConfig.author = "xxxxxx" //作者 globalConfig.isOpen = false globalConfig.outputDir = System.getProperty("user.dir") + "/src/main/kotlin" //创建地址 globalConfig.isFileOverride = true globalConfig.idType = IdType.AUTO globalConfig.xmlName = "%sMapper" globalConfig.mapperName = "%sMapper" globalConfig.serviceName="%sService" globalConfig.serviceImplName = "%sServiceImpl" globalConfig.controllerName = "%sController" globalConfig.isBaseColumnList = true globalConfig.isBaseResultMap = true globalConfig.dateType= DateType.ONLY_DATE mpg.globalConfig = globalConfig var dsc = DataSourceConfig() dsc.dbType = DbType.POSTGRE_SQL dsc.driverName = "org.postgresql.Driver" dsc.url = "jdbc:postgresql://10.4.2.6:15432/smartpark?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf8" dsc.username = "liantu" dsc.password = "liantu123456" dsc.schemaName = "vehicle" mpg.dataSource = dsc // 包配置 var pc = PackageConfig();// pc.setModuleName(scanner("模块名")); pc.parent="com.example.kotlin01.kotlinns" mpg.packageInfo=pc // 自定义配置 val cfg: InjectionConfig = object : InjectionConfig() { override fun initMap() { // to do nothing } } val focList: MutableList<FileOutConfig> = ArrayList() focList.add(object : FileOutConfig("/templates/mapper.xml.ftl") { override fun outputFile(tableInfo: TableInfo): String? { // 自定义输入文件名称 return (projectPath.toString() + "/src/main/resources/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML) } }) // config xml template and outpath cfg.fileOutConfigList = focList mpg.cfg = cfg //模板配置 val tc = TemplateConfig() tc.entityKt="/templates/entity.kt" tc.mapper="/templates/mapper.java" tc.controller="/templates/controller.java" mpg.template=tc var strategy=StrategyConfig() strategy.naming= NamingStrategy.underline_to_camel strategy.columnNaming=NamingStrategy.underline_to_camel strategy.isRestControllerStyle=true strategy.isControllerMappingHyphenStyle=true var sum=StringBuffer() sum.append(pc.moduleName).append("_") strategy.setTablePrefix(sum.toString()) mpg.strategy = strategy mpg.templateEngine = FreemarkerTemplateEngine() mpg.execute(); }6、关于自定义模板
自定义模板可以找官方的来修改!
首先要找到Mybatis-plus的包
复制过来修改
entity.kt.ftl
package ${package.Entity}<#list table.importPackages as pkg>import ${pkg}</#list>import com.baomidou.mybatisplus.annotation.*<#if swagger2>import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;</#if>/** * <p> * ${table.comment} * </p> * * @Author ${author} * @since${date} */@TableName("${table.name}")<#if swagger2>@ApiModel(value="${entity}对象", description="${table.comment!}")#if&gt;&lt;#if superEntityClass??>class ${entity} : ${superEntityClass}<#if activeRecord><${entity}>#if&gt; {&lt;#elseif activeRecord>class ${entity} : Model<${entity}>() {<#else>class ${entity} : Serializable {#if&gt;&lt;#-- ---------- BEGIN 字段循环遍历 ----------><#list table.fields as field><
#if field.keyFlag> <#
assign keyPropertyName="${field.propertyName}"/>#if&gt;&lt;#if field.comment!?length gt 0><#if swagger2> @ApiModelProperty(value = "${field.comment}")<#else> /** * ${field.comment} */#if&gt;&lt;#if field.keyFlag><#-- 主键 --><#if field.keyIdentityFlag> @TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)<#elseif idType ??> @TableId(value = "${field.annotationColumnName}", type = IdType.${idType})<#elseif field.convert> @TableId("${field.annotationColumnName}")#if&gt;&lt;#-- 普通字段 --><#elseif field.fill??><
#-- ----- 存在字段填充设置 -----><#
if field.convert> @TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})<#else> @TableField(fill = FieldFill.${field.fill})#if&gt;&lt;#elseif field.convert> @TableField("${field.annotationColumnName}")#if&gt;&lt;#-- 乐观锁注解 --><#if (versionFieldName!"") == field.name> @Version#if&gt;&lt;#-- 逻辑删除注解 --><#if (logicDeleteFieldName!"") == field.name> @TableLogic <#if field.propertyType == "Integer"> var ${field.propertyName}: Int? = null <#else> var ${field.propertyName}: ${field.propertyType}? = null #if&gt;&lt;/#list><#-- ---------- END 字段循环遍历 ----------><#if entityColumnConstant> companion object {<#list table.fields as field> const val ${field.name?upper_case} : String = "${field.name}" }#if&gt;&lt;#if activeRecord> override fun pkVal(): Serializable? {<#if keyPropertyName??> return ${keyPropertyName}<#else> return null } override fun toString(): String { return "${entity}{" +<#list table.fields as field><#if field_index==0> "${field.propertyName}=" + ${field.propertyName} +<#else> ", ${field.propertyName}=" + ${field.propertyName} +#if&gt;&lt;/#list> "}" }}
mapper.java.ftl
package ${package.Mapper};import ${package.Entity}.${entity};import ${superMapperClassPackage};import org.apache.ibatis.annotations.Mapper/** * * ${table.comment!} Mapper 接口 * * * @author ${author} * @since ${date} */@Mapper<#if kotlin>interface ${table.mapperName} : ${superMapperClass}<${entity}><#else>public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {}总结说明
数据源配置需要换成自己的,dsc.dbType = DbType.MYSQL按需切换
postgresql数据库,schema如果不是public,需要指定schemaName,如果不指定,则为默认的public,例子如下:
dsc.dbType = DbType.POSTGRE_SQL dsc.driverName = "org.postgresql.Driver" dsc.url = "jdbc:postgresql://ip:port/db" dsc.username = "aaaa" dsc.password = "bbbb" dsc.schemaName = "cccc"
globalConfig.author = “loulvlin” author需要换成自己的名字(for 注释)
如果不想生成xml,只需要注释下面两行代码:
// config xml template and outpath cfg.fileOutConfigList = focList mpg.cfg = cfg
如果不想生成controller service serviceImpl mapper entity,只需要配置TemplateConfig相应的set方法为null即可,如下
mpg.template = TemplateConfig().setXml(null) .setController(null) .setService(null) .setServiceImpl(null) .setMapper(null) .setEntity(null) .setEntityKt(null)
配置需要自动生成代码的表和前缀,如配置了前缀,生成的entity名称中不会出现前缀,不配置前缀也可以
sc.setTablePrefix("sys") sc.setInclude("sys_case_dict")
配置需要自动生成代码的表(多个)
sc.setTablePrefix("sys") sc.setInclude("sys_case_dict","sys_case_dict1","sys_case_dict2","sys_case_dict3")
定义service或controller的基类(按需配置)
sc.superControllerClass = "com.aos.base.controller.BaseController" sc.superServiceClass = "com.aos.base.service.BaseService"
生成的entity需要在类前加个open keyword,for redis序列化
生成的entity 字段类型 LocalDateTime改为 Date(java.util)
@TableName("sys_case_dict")open class Xxxxxx : Serializable { /** * 主键(通过自增生成) */ @TableId(value = "id", type = IdType.AUTO) var id: Int? = null /** * 创建时间 */ var createTime: Date? = null /** * 修改时间 */ var modifyTime: Date? = null}
end~
2021年08月31日 01点08分 1
1