备份代码

This commit is contained in:
Superdandan 2024-05-05 10:47:44 +08:00
parent 4e8ffb47bc
commit 27e398ac73
9 changed files with 211 additions and 10 deletions

View File

@ -1,6 +1,11 @@
val ktor_version: String by project
val kotlin_version: String by project
val logback_version: String by project
val exposed_version: String by project
val h2_version: String by project
val hikaricp_version: String by project
val ehcache_version: String by project
val mysql_driver_version: String by project
plugins {
kotlin("jvm") version "1.9.23"
@ -29,7 +34,22 @@ dependencies {
implementation("io.ktor:ktor-server-freemarker-jvm")
implementation("io.ktor:ktor-server-netty-jvm")
implementation("ch.qos.logback:logback-classic:$logback_version")
implementation("io.ktor:ktor-server-config-yaml:2.3.10")
// Exposed
implementation("org.jetbrains.exposed:exposed-core:$exposed_version")
implementation("org.jetbrains.exposed:exposed-dao:$exposed_version")
implementation("org.jetbrains.exposed:exposed-jdbc:$exposed_version")
implementation("org.jetbrains.exposed:exposed-java-time:$exposed_version")
implementation("com.h2database:h2:$h2_version")
//pool
implementation("com.zaxxer:HikariCP:$hikaricp_version")
implementation("org.ehcache:ehcache:$ehcache_version")
//mysql
implementation("mysql:mysql-connector-java:$mysql_driver_version")
testImplementation("io.ktor:ktor-server-tests-jvm")
testImplementation("org.jetbrains.kotlin:kotlin-test-junit:$kotlin_version")
}

View File

@ -2,3 +2,8 @@ ktor_version=2.3.10
kotlin_version=1.9.23
logback_version=1.4.14
kotlin.code.style=official
exposed_version = 0.41.1
h2_version = 2.2.224
hikaricp_version = 5.1.0
ehcache_version = 3.10.8
mysql_driver_version = 8.0.32

View File

@ -1,7 +1,13 @@
package echo.org
import echo.org.plugins.*
import com.zaxxer.hikari.HikariDataSource
import echo.org.instructure.DatabaseSingleton
import echo.org.plugins.configureRouting
import echo.org.plugins.configureSecurity
import echo.org.plugins.configureSerialization
import echo.org.plugins.configureTemplating
import io.ktor.server.application.*
import org.jetbrains.exposed.sql.Database
fun main(args: Array<String>) {
io.ktor.server.netty.EngineMain.main(args)
@ -12,4 +18,17 @@ fun Application.module() {
configureSerialization()
configureTemplating()
configureRouting()
initDatabase()
}
fun Application.initDatabase() {
val config = environment.config.config("storage")
val dateSourceConfig = DatabaseSingleton.createHikariDataSource(
url = config.property("jdbcURL").getString(),
driver = config.property("driverClassName").getString(),
usernameInput = config.property("username").getString(),
passwordInput = config.property("password").getString()
)
val dataSource = HikariDataSource(dateSourceConfig)
Database.connect(dataSource)
}

View File

@ -1,9 +1,28 @@
package echo.org.domain
data class Document(val id: Long, val content: String,val name: String)
import echo.org.instructure.Documents
import org.jetbrains.exposed.dao.LongEntity
import org.jetbrains.exposed.dao.LongEntityClass
import org.jetbrains.exposed.dao.id.EntityID
import java.time.LocalDateTime
val Documents : MutableList<Document> = mutableListOf(
Document(1,"测试1","测试名称1"),
Document(2,"测试2","测试名称2"),
Document(3,"测试3","测试名称3"),
)
class Document(id: EntityID<Long>) : LongEntity(id) {
companion object : LongEntityClass<Document>(Documents)
var title: String by Documents.title
var content: String by Documents.content
var authorId: String by Documents.authorId
var createdAt: LocalDateTime by Documents.createdAt
var updatedAt: LocalDateTime by Documents.updatedAt
var fileSize: String by Documents.fileSize
}
interface DocumentRepository {
suspend fun save(document: Document): Document?
suspend fun findById(id: Long): Document?
suspend fun deleteById(id: Long): Boolean
suspend fun pageQuery(documentQueryParam:DocumentQueryParam): PageResult<Document>
}
data class DocumentQueryParam(var title: String? = null,
var authorId: String? = null) : BasePageQueryParm()

View File

@ -24,3 +24,16 @@ data class Result<T>(
}
}
}
data class PageResult<T>(
val results: List<T>, // 查询结果列表
val totalCount: Long // 总记录数
) {
// companion object {
// fun <T> of(results: List<T>,totalCount: Long ): PageResult<T> {
// return PageResult()
// }
// }
}
open class BasePageQueryParm(var pageNum: Int = 1, var pageSize: Int = 10)

View File

@ -0,0 +1,36 @@
package echo.org.instructure
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import io.ktor.server.config.*
import kotlinx.coroutines.Dispatchers
import org.jetbrains.exposed.sql.transactions.experimental.newSuspendedTransaction
object DatabaseSingleton {
fun init(config: ApplicationConfig) {
val driverClassName = config.property("storage.driverClassName").getString()
val jdbcURL = config.property("storage.jdbcURL").getString() +
config.propertyOrNull("storage.database")?.getString()
}
fun createHikariDataSource(
url: String,
driver: String,
usernameInput: String,
passwordInput: String
) = HikariDataSource(HikariConfig().apply {
driverClassName = driver
jdbcUrl = url
username = usernameInput
password = passwordInput
maximumPoolSize = 30
isAutoCommit = false
transactionIsolation = "TRANSACTION_REPEATABLE_READ"
validate()
})
suspend fun <T> dbQuery(block: suspend () -> T): T =
newSuspendedTransaction(Dispatchers.IO) { block() }
}

View File

@ -0,0 +1,81 @@
package echo.org.instructure
import echo.org.domain.Document
import echo.org.domain.DocumentQueryParam
import echo.org.domain.DocumentRepository
import echo.org.domain.PageResult
import echo.org.instructure.DatabaseSingleton.dbQuery
import org.jetbrains.exposed.dao.id.LongIdTable
import org.jetbrains.exposed.sql.Column
import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq
import org.jetbrains.exposed.sql.andWhere
import org.jetbrains.exposed.sql.deleteWhere
import org.jetbrains.exposed.sql.javatime.datetime
import org.jetbrains.exposed.sql.selectAll
import java.time.LocalDateTime
object Documents : LongIdTable() {
val title: Column<String> = varchar("title", 255)
val content: Column<String> = text("content")
val authorId: Column<String> = varchar("author_id", 50)
val createdAt: Column<LocalDateTime> = datetime("created_at")
val updatedAt: Column<LocalDateTime> = datetime("updated_at")
val fileSize: Column<String> = varchar("file_size", 255)
}
class DocumentRepositoryImpl : DocumentRepository {
override suspend fun save(document: Document): Document = dbQuery {
// 检查文档是否有有效的ID
val existingDocument = document.id.let {
Document.findById(it)
}
// 如果文档存在,则更新,否则创建新文档
existingDocument?.apply {
title = document.title
content = document.content
authorId = document.authorId
createdAt = document.createdAt
updatedAt = LocalDateTime.now() // 更新时间应为当前时间
fileSize = document.fileSize
} ?: Document.new {
title = document.title
content = document.content
authorId = document.authorId
createdAt = document.createdAt
updatedAt = document.updatedAt
fileSize = document.fileSize
}
}
override suspend fun findById(id: Long): Document? = dbQuery {
Document.find { Documents.id eq id }.firstOrNull()
}
override suspend fun deleteById(id: Long): Boolean {
Document.find { Documents.id eq id }
.firstOrNull()?.delete()
return Documents.deleteWhere { Documents.id eq id } > 0
}
override suspend fun pageQuery(documentQueryParam: DocumentQueryParam): PageResult<Document> {
// 构建查询条件
val query = Documents.selectAll().apply {
documentQueryParam.authorId?.let {
andWhere { Documents.authorId eq documentQueryParam.authorId!! }
}
documentQueryParam.title?.let {
andWhere { Documents.title like "%${documentQueryParam.title}%" }
}
}
val pageSize = documentQueryParam.pageSize ?: 10 // 默认页面大小
val pageIndex = documentQueryParam.pageNum ?: 0 // 默认页码
val offset = pageSize * pageIndex.toLong()
// 执行查询
val count = query.count()
val documentList = query.limit(pageSize, offset).map { Document.wrapRow(it) }
return PageResult(documentList, count)
}
}

View File

@ -1,7 +1,7 @@
package echo.org.plugins
import echo.org.domain.Documents
import echo.org.domainDocuments
import echo.org.domain.Result
import io.ktor.http.content.*
import io.ktor.server.application.*
@ -17,7 +17,7 @@ fun Application.configureRouting() {
staticResources("/files", "files")
route("/documents") {
get("") {
val model = mapOf("Documents" to Documents)
call.respond(FreeMarkerContent("index.ftl", model, "e"))
}
post("/add") {

View File

@ -4,3 +4,11 @@ ktor:
- echo.org.ApplicationKt.module
deployment:
port: 8080
storage:
driverClassName: "com.mysql.cj.jdbc.Driver"
jdbcURL: "jdbc:mysql://47.97.21.20:3306/"
database: "document"
username: "documentAdmin"
password: "123456"