Kotlin学习笔记(13)--搭建Kotlin+SpringBoot项目
创建项目
使用 Spring Boot Starter 创建项目,创建地址:https://start.spring.io/。
配置如下:

pom.xml 文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.3.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>kotlin-spring-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>kotlin-spring-demo</name>
<description>Demo project for Spring Boot and Kotlin</description>
<properties>
<java.version>17</java.version>
<kotlin.version>1.9.25</kotlin.version>
<jackson.version>2.17.2</jackson.version>
</properties>
<repositories>
<repository>
<id>spring-repo</id>
<url>https://repo.spring.io/release</url>
</repository>
</repositories>
<dependencies>
<!-- spring boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- kotlin -->
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
<!-- jackson -->
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
<version>${jackson.version}</version>
</dependency>
<!-- mysql -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- test -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-test-junit5</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
<plugin>jpa</plugin>
<plugin>all-open</plugin>
</compilerPlugins>
<pluginOptions>
<option>all-open:annotation=jakarta.persistence.Entity</option>
<option>all-open:annotation=jakarta.persistence.MappedSuperclass</option>
<option>all-open:annotation=jakarta.persistence.Embeddable</option>
</pluginOptions>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-noarg</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
配置 MySQL 和 Redis 连接
在 src/main/resources/application.yml 中配置 MySQL 和 Redis 连接。
spring:
datasource:
url: jdbc:mysql://localhost:13306/test_db?useSSL=false&serverTimezone=UTC
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
properties:
hibernate:
format_sql: true
redis:
host: localhost
port: 6379
cache:
type: redis
# 服务器端口
server:
port: 8080
编写主应用程序类
在 src/main/kotlin/demo 目录下创建 DemoApplication.kt:
package demo
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.cache.annotation.EnableCaching
@SpringBootApplication
@EnableCaching
class DemoApplication
fun main(args: Array<String>) {
runApplication<DemoApplication>(*args)
}
配置缓存
在 src/main/kotlin/demo 目录下创建 CacheConfig.kt:
package demo
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.module.SimpleModule
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer
import com.fasterxml.jackson.module.kotlin.registerKotlinModule
import org.springframework.cache.CacheManager
import org.springframework.cache.annotation.EnableCaching
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.data.redis.cache.RedisCacheConfiguration
import org.springframework.data.redis.cache.RedisCacheManager
import org.springframework.data.redis.connection.RedisConnectionFactory
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer
import org.springframework.data.redis.serializer.RedisSerializationContext
import org.springframework.data.redis.serializer.StringRedisSerializer
import java.time.Duration
@Configuration
@EnableCaching
class CacheConfig {
@Bean
fun cacheManager(redisConnectionFactory: RedisConnectionFactory): CacheManager {
val objectMapper = ObjectMapper().registerKotlinModule()
// 创建 Jackson 序列化器
val jackson2JsonRedisSerializer = Jackson2JsonRedisSerializer(objectMapper, User::class.java)
val cacheConfig = RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(60)) // 缓存有效期
.disableCachingNullValues()
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
return RedisCacheManager.builder(redisConnectionFactory)
.cacheDefaults(cacheConfig)
.build()
}
}
- 设置 Redis 作为缓存管理器,并将缓存的默认过期时间设置为 60 分钟。
创建实体类
在 src/main/kotlin/demo 目录下创建 User.kt:
package demo
import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
@Entity
data class User(
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0,
val name: String,
val email: String
)
创建仓库接口
在 src/main/kotlin/demo 目录下创建 UserRepository.kt:
package demo
import com.example.entity.User
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.stereotype.Repository
@Repository
interface UserRepository : JpaRepository<User, Long> {
fun findByEmail(email: String): User?
}
创建服务类并使用缓存
在 src/main/kotlin/demo 目录下创建 UserService.kt:
package demo
import com.example.entity.User
import com.example.repository.UserRepository
import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
@Service
class UserService(private val userRepository: UserRepository) {
@Cacheable(value = ["users"], key = "#email")
fun getUserByEmail(email: String): User? {
println("Fetching user from database for email: $email")
return userRepository.findByEmail(email)
}
@Transactional
fun createUser(name: String, email: String): User {
val user = User(name = name, email = email)
return userRepository.save(user)
}
}
@Cacheable注解用于将getUserByEmail方法的结果缓存到 Redis 中。首次调用时会从数据库获取数据并缓存,之后相同的请求会直接从缓存中获取。value = ["users"]指定了缓存的名称。
创建控制器
在 src/main/kotlin/demo 目录下创建 UserController.kt:
package demo
import com.example.service.UserService
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/users")
class UserController(private val userService: UserService) {
@GetMapping("/{email}")
fun getUser(@PathVariable email: String): ResponseEntity<Any> {
val user = userService.getUserByEmail(email)
return if (user != null) {
ResponseEntity.ok(user)
} else {
ResponseEntity.notFound().build()
}
}
@PostMapping
fun createUser(@RequestParam name: String, @RequestParam email: String): ResponseEntity<Any> {
val user = userService.createUser(name, email)
return ResponseEntity.ok(user)
}
}
初始化数据库
在 MySQL 创建数据库:
CREATE DATABASE test_db CHARACTER SET utf8 COLLATE utf8_general_ci;
在 src/main/resources 目录下创建 schema.sql 文件
CREATE TABLE IF NOT EXISTS user (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE
);
- Spring Boot 的
spring.jpa.hibernate.ddl-auto=update属性会自动创建和更新表结构。
运行项目
确保 MySQL 和 Redis 服务正在运行,然后在项目根目录下执行以下命令来构建和运行项目:·
mvn clean install
mvn spring-boot:run
测试接口
创建用户:
POST http://localhost:8080/users?name=Jacob&email=jacob@example.com
获取用户:
GET http://localhost:8080/users/jacob@example.com
验证数据库数据:
mysql> select * from user;
+----+-------------------+-------+
| id | email | name |
+----+-------------------+-------+
| 1 | jacob@example.com | Jacob |
+----+-------------------+-------+
1 row in set (0.00 sec)
- 数据库有了新增数据。
验证缓存数据:
get users::jacob@example.com
"\"User(id=1, name=Jacob, email=jacob@example.com)\""

浙公网安备 33010602011771号