1. What is Kotlin?
Kotlin is a new JVA-BASED programming language developed in 2010 by JetBrains, the company behind IntelliJ IDEA, and has been open source since 2012.
Kotlin can be compiled to Java bytecode or JavaScript, making it easy to run on devices without a JVM.
Kotlin is a general-purpose, open source, static, utility programming language for both the JVM and Android with object-oriented and functional programming capabilities. It focuses on interactivity, security, and clarity and tool support.
2. Characteristics of Kotlin
1. Simplicity: Greatly reduce the amount of boilerplate code.
2, security: avoid null pointer exceptions and other errors of the whole class.
Interoperability: Take advantage of existing libraries in the JVM, Android, and browsers.
4. Tool-friendly: Use any Java IDE or use the command line to build.
3, MybatisPlus
MyBatisPlus (MP for short) is a MyBatis enhancement tool, on the basis of MyBatis only do enhancement do not change, to simplify the development and improve efficiency.
4. Features of MybatisPlus
No intrusion: only enhancements are made, no changes are made, and its introduction will not affect the existing project, as smooth as silk
Low loss: Basic CURD will be injected automatically upon startup, with basically no loss in performance and direct object-oriented operation
Powerful CRUD operations: built-in universal Mapper, universal Service, only through a small amount of configuration can achieve a single table most CRUD operations, more powerful condition constructor, to meet all types of use requirements
Support Lambda form call: through Lambda expressions, it is convenient to write all kinds of query conditions, without worrying about field write errors
Support automatic generation of primary keys: support up to four primary key policies (including distributed unique ID generator – Sequence), can be freely configured, perfect solution to the primary key problem
Support for ActiveRecord mode: Support for ActiveRecord form calls, entity classes only need to inherit from Model classes to perform powerful CRUD operations
Support custom global universal operations: support Write once (use anywhere)
Built-in code generator: using * code or Maven plug-in can quickly generate Mapper, Model, Service, Controller layer code, support template engine, more than a lot of custom configuration you to use
Built-in paging plug-in: Based on MyBatis physical paging, developers do not need to care about specific operations, after configuring the plug-in, write paging is equal to ordinary List query
The paging plug-in supports a variety of databases: MySQL, MariaDB, Oracle, DB2, H2, HSQL, SQLite, Postgre, SQLServer, etc
Built-in performance analysis plug-in: outputs Sql statements and their execution time. It is recommended to enable this function during development and testing to quickly find out slow queries
Built-in global interception plug-in: provides intelligent analysis and blocking of delete and UPDATE operations on all tables, and can customize interception rules to prevent misoperations
5. Use Kotlin code generation
The first is the dependency of Mybatis – Plus:
< the dependency > < groupId > com. Baomidou < / groupId > < artifactId > mybatis - plus - generator < / artifactId > < version > 3.3.2 rainfall distribution on 10-12 < / version > </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency>Copy the code
Let’s get down to business:
Key points on the website:
Effect:
Code examples:
GeneratorFactory.kt
Funmain (args: Array<String>) {generator()} fun generator(){println("begin generating") val projectPath = System.getproperty ("user.dir") var MPG = AutoGenerator() var globalConfig = globalConfig () globalconfig.iskotlin Author = "XXXXXX" // author Globalconfig. isOpen = false globalconfig.outputDir = System. GetProperty (" user. Dir ") + "/ SRC/main/kotlin" / / create address 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(" module name ")); PC. The parent = "com. Example. Kotlin01. Kotlinns" MPG. PackageInfo = PC / / custom configuration 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? {/ / custom input file name return (projectPath. The toString () + "/ SRC/main/resources/mapper/" + tableInfo. GetEntityName () +" mapper "+ DOT_XML)}}) //config xmlTemplate and outpath cfg.fileOutConfigList = focList MPG = 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(); }Copy the code
6. On custom templates
Custom templates can be found to modify the official!
The first step is to find the Mybatis- Plus package
Copy and modify it
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} object ", description="${table.comment! }") </#if> <#if superEntityClass?? > class ${entity} : ${superEntityClass}<#if activeRecord><${entity}></#if> { <#elseif activeRecord> class ${entity} : Model<${entity}>() { <#else> class ${entity} : Serializable {< / # if > < # -- -- -- -- -- -- -- -- -- -- -- BEGIN field to iterate over -- -- -- -- -- -- -- -- -- -- > < # list table. The fields as field > < # if field. KeyFlag > <#assign keyPropertyName="${field.propertyName}"/> </#if> <#if field.comment! ? length gt 0> <#if swagger2> @ApiModelProperty(value = "${field.comment}") <#else> /** * ${field.comment} */ </#if> < / # if > < # if field. KeyFlag > < # - primary key - > < # if field. KeyIdentityFlag > @ TableId (value = "${field. AnnotationColumnName}", type = IdType.AUTO) <#elseif idType ??> @TableId(value = "${field.annotationColumnName}", Type = IdType ${IdType}) < # elseif field. The convert > @ TableId (" ${field. AnnotationColumnName} ") < / # if > < # - ordinary field - > < # elseif Field. The fill?? > < # -- -- -- -- -- -- there is the fields Settings -- -- -- -- - > < # if field. The convert > @ TableField (value = "${field. AnnotationColumnName}", fill = FieldFill.${field.fill}) <#else> @TableField(fill = FieldFill.${field.fill}) </#if> <#elseif field.convert> @ TableField (" ${field. AnnotationColumnName} ") < / # if > < # - optimistic locking annotations - > < # if (versionFieldName!" ") == field.name> @version </#if> <#-- logicDeleteFieldName! ") == field.name> @TableLogic </#if> <#if field.propertyType == "Integer"> var ${field.propertyName}: Int? = null <#else> var ${field.propertyName}: ${field. PropertyType}? = null < / # if > < / # list > < # -- -- -- -- -- -- -- -- -- -- -- END field to iterate over -- -- -- -- -- -- -- -- -- -- > < # if entityColumnConstant > companion object { <#list table.fields as field> const val ${field.name?upper_case} : String = "${field.name}" </#list> } </#if> <#if activeRecord> override fun pkVal(): Serializable? { <#if keyPropertyName??> return ${keyPropertyName} <#else> return null </#if> } </#if> 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> </#list> "}" } }Copy the code
mapper.java.ftl
package ${package.Mapper}; import ${package.Entity}.${entity}; import ${superMapperClassPackage}; import org.apache.ibatis.annotations.Mapper /** * <p> * ${table.comment! } Mapper interface ${table. MapperName} : ${superMapperClass}<${entity}> <#else> public interface ${table.mapperName} extends ${superMapperClass}<${entity}> { } </#if>Copy the code
Conclusion shows that
DbType = dbType.MYSQL as needed
For a postgresQL database, if the schema is not public, you need to specify schemaName. If you do not specify schemaName, the default schema is 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"
Copy the code
Globalconfig. author = “loulvlin” author needs its own name (for comment)
If you don’t want to generate XML, just comment out the following two lines of code:
//config xmltemplate and outpath cfg.fileOutConfigList = focList mpg. CFG = CFGCopy the code
If you do not want to generate a Controller Service serviceImpl mapper Entity, set the TemplateConfig set method to NULL as follows
mpg.template = TemplateConfig().setXml(null)
.setController(null)
.setService(null)
.setServiceImpl(null)
.setMapper(null)
.setEntity(null)
.setEntityKt(null)
Copy the code
Configure the table and prefix that need to be automatically generated. If the prefix is configured, no prefix will appear in the generated Entity name
sc.setTablePrefix("sys")
sc.setInclude("sys_case_dict")
Copy the code
Configure tables that require automatic code generation (multiple)
sc.setTablePrefix("sys")
sc.setInclude("sys_case_dict","sys_case_dict1","sys_case_dict2","sys_case_dict3")
Copy the code
Define a base class for a Service or Controller (as needed)
sc.superControllerClass = "com.aos.base.controller.BaseController"
sc.superServiceClass = "com.aos.base.service.BaseService"
Copy the code
The generated entity needs to be preceded by an Open keyword, for redis serialization
Generated Entity field type LocalDateTime change to Date(java.util)
@TableName("sys_case_dict") open class Xxxxxx : Serializable {/** * primary key (generated by autoincrement) */ @tableId (value = "id", type = idtype.auto) var id: Int? = null /** * createTime */ var createTime: Date? = null /** * modifyTime: Date? = null }Copy the code
end~