目前大多数都在使用java集成 springboot
进行开发,本文演示仅仅将 java
换成 kotlin
,其他不变的情况下进行开发。
一、安装支持插件
在 idea
中安装 kotlin
插件(大多数情况下会默认安装了)
二、maven配置 注意
kotlin
目前不支持 lombok
所以不能使用或引用 lombok
相关的插件或依赖包,下面是一个排除示例,同时也不支持 maven-enforcer-plugin
1
2
3
4
5
6
7
8
9
10
11<dependency> <groupId>com.ayouran.common</groupId> <artifactId>a-common</artifactId> <version>1.0.0-SNAPSHOT</version> <exclusions> <exclusion> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclusion> </exclusions> </dependency>
maven
的属性配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> <kotlin.version>1.3.21</kotlin.version> <!--增量编译--> <kotlin.compiler.incremental>true</kotlin.compiler.incremental> <!--关闭协程编译警告--> <experimentalCoroutines>enable</experimentalCoroutines> <spring-boot.version>2.2.4.RELEASE</spring-boot.version> <spring-cloud.version>Hoxton.SR1</spring-cloud.version> <swagger.version>2.7.0</swagger.version> <main.class>com.lc.github.KotlinDemoApplication</main.class> <querydsl.version>4.2.1</querydsl.version> <mapstruct.version>1.3.1.Final</mapstruct.version> </properties>
必要的依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14<dependencies> <!--反射支持包,不需要可以去掉--> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-reflect</artifactId> <version>${kotlin.version}</version> </dependency> <!--jdk8下的 kotlin支持包--> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-stdlib-jdk8</artifactId> <version>${kotlin.version}</version> </dependency> </dependencies>
编译部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183<build> <plugins> <plugin> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-plugin</artifactId> <configuration> <correctErrorTypes>true</correctErrorTypes> <languageVersion>${kotlin.language.version}</languageVersion> </configuration> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-allopen</artifactId> <version>${kotlin.version}</version> </dependency> </dependencies> <executions> <execution> <id>kapt</id> <goals> <goal>kapt</goal> </goals> <configuration> <correctErrorTypes>true</correctErrorTypes> <sourceDirs> <sourceDir>src/main/kotlin</sourceDir> <sourceDir>src/main/java</sourceDir> </sourceDirs> <annotationProcessorPaths> <annotationProcessorPath> <groupId>com.google.dagger</groupId> <artifactId>dagger-compiler</artifactId> <version>2.9</version> </annotationProcessorPath> <annotationProcessorPath> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${querydsl.version}</version> <classifier>jpa</classifier> </annotationProcessorPath> <annotationProcessorPath> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> </annotationProcessorPath> </annotationProcessorPaths> </configuration> </execution> <execution> <id>compile</id> <goals> <goal>compile</goal> </goals> <configuration> <sourceDirs> <sourceDir>src/main/kotlin</sourceDir> <sourceDir>src/main/java</sourceDir> </sourceDirs> </configuration> </execution> <execution> <id>test-kapt</id> <goals> <goal>test-kapt</goal> </goals> <configuration> <sourceDirs> <sourceDir>src/test/kotlin</sourceDir> <sourceDir>src/test/java</sourceDir> </sourceDirs> <annotationProcessorPaths> <annotationProcessorPath> <groupId>com.google.dagger</groupId> <artifactId>dagger-compiler</artifactId> <version>2.9</version> </annotationProcessorPath> <annotationProcessorPath> <groupId>com.querydsl</groupId> <artifactId>querydsl-apt</artifactId> <version>${querydsl.version}</version> <classifier>jpa</classifier> </annotationProcessorPath> <annotationProcessorPath> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> </annotationProcessorPath> </annotationProcessorPaths> </configuration> </execution> <execution> <id>test-compile</id> <goals> <goal>test-compile</goal> </goals> <configuration> <sourceDirs> <sourceDir>src/test/kotlin</sourceDir> <sourceDir>src/test/java</sourceDir> <sourceDir>target/generated-sources/kapt/test</sourceDir> </sourceDirs> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <proc>none</proc> <source>${java.version}</source> <target>${java.version}</target> <annotationProcessorPaths> <path> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>${lombok.version}</version> </path> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> </path> </annotationProcessorPaths> <compilerArgs> <arg>-Amapstruct.suppressGeneratorTimestamp=true</arg> <arg>-Amapstruct.defaultComponentModel=spring</arg> </compilerArgs> </configuration> <executions> <!-- Replacing default-compile as it is treated specially by maven --> <execution> <id>default-compile</id> <phase>none</phase> </execution> <!-- Replacing default-testCompile as it is treated specially by maven --> <execution> <id>default-testCompile</id> <phase>none</phase> </execution> <execution> <id>java-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>java-test-compile</id> <phase>test-compile</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>2.6</version> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> <configuration> <archive> <manifest> <mainClass>${main.class}</mainClass> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> </configuration> </execution> </executions> </plugin> </plugins> </build>
有 java
与 kotlin
混合的情况,在上面的 <plugins>
下加入下面的编译插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <proc>none</proc> <source>${java.version}</source> <target>${java.version}</target> <annotationProcessorPaths> <path> <groupId>org.mapstruct</groupId> <artifactId>mapstruct-processor</artifactId> <version>${mapstruct.version}</version> </path> </annotationProcessorPaths> <compilerArgs> <arg>-Amapstruct.suppressGeneratorTimestamp=true</arg> <arg>-Amapstruct.defaultComponentModel=spring</arg> </compilerArgs> </configuration> <executions> <!-- Replacing default-compile as it is treated specially by maven --> <execution> <id>default-compile</id> <phase>none</phase> </execution> <!-- Replacing default-testCompile as it is treated specially by maven --> <execution> <id>default-testCompile</id> <phase>none</phase> </execution> <execution> <id>java-compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>java-test-compile</id> <phase>test-compile</phase> <goals> <goal>testCompile</goal> </goals> </execution> </executions> </plugin>
此 maven
配置集成了 querydsl
、mapstruct
、dagger2
的编译,基本上能满足常规的使用
三、创建入口函数类
四、编写入口函数
springboot
的启动方法及 swagger
的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33@EnableAsync @EnableSwagger2 @EnableScheduling @SpringBootApplication class KotlinDemoApplication : CommandLineRunner { companion object { @JvmStatic fun main(args: Array<String>) { SpringApplication.run(KotlinDemoApplication::class.java, *args) } } @Bean fun api(): Docket { return Docket(DocumentationType.SWAGGER_2) .ignoredParameterTypes(Session::class.java) .select() // .apis(RequestHandlerSelectors.any()) .apis(RequestHandlerSelectors.basePackage("com.ayouran.flow.controllers")) .paths(PathSelectors.any()) .build() .apiInfo(ApiInfoBuilder() .description("ayouram-flow相关API") .title("ayouram-flow") .version("1.0") .build()) .pathMapping("/") } override fun run(vararg args: String?) { println("*************************** ok ***********************************") } }
五、创建数据库对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55import com.fasterxml.jackson.annotation.JsonFormat import org.hibernate.annotations.DynamicInsert import org.hibernate.annotations.DynamicUpdate import java.util.* import javax.persistence.* /**** * 设备流量规则 */ @Entity @Table(name = "device_rules", indexes = [Index(name = "device_no", columnList = "device_no"), Index(name = "rules_no", columnList = "rules_no"), Index(name = "deleted", columnList = "deleted")], uniqueConstraints = [UniqueConstraint(name = "device_no_rules_no", columnNames = ["device_no", "rules_no"])]) @DynamicUpdate @DynamicInsert class DeviceRules { @Id @Column(name = "id", columnDefinition = "bigint(20) COMMENT 'ID,自增'") @GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long? = null @Column(name = "device_no", columnDefinition = "varchar(18) COMMENT '设备编号'") var deviceNo: String? = null @Column(name = "rules_no", columnDefinition = "varchar(18) COMMENT '规则编号'") var rulesNo: String? = null @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") @Column(name = "create_at", columnDefinition = "datetime COMMENT '创建时间'") var createAt: Date? = null @Column(name = "update_at", columnDefinition = "datetime COMMENT '修改时间'") var updateAt: Date? = null /** * 触发jpa update代码需要执行的逻辑 */ @PreUpdate fun preUpdate() { updateAt = Date() } /** * 自动设置必要字段的值 */ @PrePersist fun prePersist() { updateAt = Date() createAt = updateAt deleted = BaseEnum.NOT_REMOVE.index } }
注解使用了 hibernate
的功能主要用于自动创建/更新表结构以及索引的生成,如果需要 mybatis
版本的,只需要去掉这里面的注释就好。
六、创建仓库操作接口
基于 springboot-data-jpa
的 repository
1
2
3
4
5@Repository interface DeviceRulesRepository : JpaRepository<DeviceRules, Long>, JpaSpecificationExecutor<DeviceRules>, QuerydslPredicateExecutor<DeviceRules> { fun getAllByDeviceNoAndDeleted(deviceNo: String, deleted: Int): Optional<MutableList<DeviceRules>> }
七、创建一个业务接口来声明业务
1
2
3
4
5
6
7interface DeviceService { /** * 查询设备的路由规则 */ fun queryDeviceFlowRules(aPageRequest: APageRequest): PageResult<QueryDeviceFlowRulesVO> }
八、创建一个业务接口实现来实现声明的业务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28@Service class DeviceServiceImpl @Autowired constructor(private val deviceRepository: DeviceRepository, private val deviceRulesRepository: DeviceRulesRepository, private val querydslUtlis: QuerydslUtlis, private val deviceMapstruct: DeviceMapstruct) : DeviceService { private val logger = LoggerFactory.getLogger(javaClass) override fun queryDeviceFlowRules(aPageRequest: APageRequest): PageResult<QueryDeviceFlowRulesVO> { val qDeviceRules = QDeviceRules.deviceRules val qFlowRules = QFlowRules.flowRules var rredicate: Predicate? = null if (StringUtils.isNotBlank(aPageRequest.query)) rredicate = qDeviceRules.deviceNo.eq(aPageRequest.query) val exprs = arrayOf<Expression<*>>(qDeviceRules.deviceNo, qDeviceRules.deleted, qFlowRules.rulesNo, qFlowRules.flowMax, qFlowRules.startTime, qFlowRules.endTime) val results = querydslUtlis.getQueryFactory() .select(*exprs) .from(qDeviceRules) .where(ExpressionUtils.allOf(rredicate)) .leftJoin(qFlowRules) .on(qDeviceRules.rulesNo.eq(qFlowRules.rulesNo)) .orderBy(qDeviceRules.createAt.desc()) .offset((aPageRequest.pageIndex!! - 1) * aPageRequest.pageSize!!) .limit(aPageRequest.pageSize!!) .fetchResults() return PageUtlis.retPage(results, querydslUtlis.getCollection(results.results, exprs, QueryDeviceFlowRulesVO::class.java) as Collection<QueryDeviceFlowRulesVO>) } }
这里使用了 querydsl
来完成一个多表查询
九、创建一个 http服务接口
1
2
3
4
5
6
7
8
9
10
11
12
13@RestWrapper @RestController @RequestMapping("/device") @Api(value = "device", description = "设备相关接口", tags = ["device"]) class DeviceController @Autowired constructor(private val deviceService: DeviceService) { @GetMapping("/query_device") fun queryDevice(aPageRequest: APageRequest) = deviceService.queryDevice(aPageRequest) @GetMapping("/query_device_flow_rules") fun queryDeviceFlowRules(aPageRequest: APageRequest) = deviceService.queryDeviceFlowRules(aPageRequest) }
至此完成一个基本的开发过程,大多数情况下可以直接将 java
代码粘贴到 kotlin
文件中,会自动转换成合适的 kotlin
代码(偶尔需要自己调整,毕竟编辑器不是万能的)
到此这篇关于使用kotlin集成springboot开发的文章就介绍到这了,更多相关kotlin集成springboot开发内容请搜索靠谱客以前的文章或继续浏览下面的相关文章希望大家以后多多支持靠谱客!
最后
以上就是鲤鱼宝马最近收集整理的关于使用kotlin集成springboot开发的超详细教程的全部内容,更多相关使用kotlin集成springboot开发内容请搜索靠谱客的其他文章。
发表评论 取消回复