V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
爱意满满的作品展示区。
actar
V2EX  ›  分享创造

闲来无事,用 Kotlin 写了一个简单的 ORM

  •  
  •   actar ·
    actar233 · 2021-08-23 17:18:44 +08:00 · 1969 次点击
    这是一个创建于 977 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前主要支持单表的 CRUD 和 DML 的 DSL 语法。

    package io.github.zhaofanzhe.kom.example
    
    import io.github.zhaofanzhe.kom.Database
    import io.github.zhaofanzhe.kom.connection.ConnectionFactory
    import io.github.zhaofanzhe.kom.entity.Entity
    import io.github.zhaofanzhe.kom.express.Table
    import io.github.zhaofanzhe.kom.toolkit.eq
    import java.sql.Connection
    import java.sql.DriverManager
    
    fun main() {
        val database = getDatabase()
    
        // 创建表[目前不支持自动迁移]
        database.createTable(Users()).execute()
        database.createTable(Addresses()).execute()
    
        // 单表 CRUD
        // 目前插入数据,目前没有做主键的回填
        database.create(User(id = 1, username = "张三"))
        database.create(User(id = 2, username = "李四"))
        database.create(User(id = 3, username = "王五"))
        database.create(Address(address = "北京", userId = 1))
        database.create(Address(address = "上海", userId = 1))
        database.create(Address(address = "广州", userId = 2))
        database.create(Address(address = "深圳", userId = 3))
    
        val user = database.fetchOne(Users()) { it.username eq "王五" }
    
        // 根据主键更新
        user?.let {
            it.username = "王老五"
            database.save(it)
        }
    
        // 根据主键删除
        user?.let {
            database.delete(it)
        }
    
        // DSL 查询
    
        val users = Users()
    
        val addresses = Addresses()
    
        // 子查询
        val subQuery = database.selectFrom(users)
            .where(users.username eq "张三")
            .subQuery()
    
        // 左连接
        val express = database.select(users, addresses)
            .from(subQuery)
            .leftJoin(addresses).on(addresses.userId eq users.id)
    
        // 打印 SQL
        println(express)
    
        // 遍历获取数据
        express.fetchAll().forEach {
            println(it[users])
            println(it[addresses])
        }
    
        // 删除表
        database.dropTable(Users()).execute()
        database.dropTable(Addresses()).execute()
    
    }
    
    data class User(
        var id: Int = 0,
        var username: String = "",
    ) : Entity<Users>(Users::class) {
        constructor() : this(id = 0, username = "")
    }
    
    class Users : Table<User>(User::class) {
        val id = column(User::id).primaryKey().autoIncrement()
        val username = column(User::username).unique()
    }
    
    data class Address(
        var id: Int = 0,
        var address: String = "",
        var userId: Int = 0,
    ) : Entity<Addresses>(Addresses::class) {
        constructor() : this(id = 0, address = "", userId = 0)
    }
    
    class Addresses : Table<Address>(Address::class) {
        var id = column(Address::id).primaryKey().autoIncrement()
        var address = column(Address::address)
        var userId = column(Address::userId)
    }
    
    fun getDatabase(): Database {
        return Database(object : ConnectionFactory {
            override fun getConnection(): Connection {
                return DriverManager.getConnection("{url}", "{user}", "{password}")
            }
        })
    }
    

    Github 地址: Kom

    另外,求个 star~

    7 条回复    2021-08-30 15:53:55 +08:00
    xmt328
        1
    xmt328  
       2021-08-24 11:52:31 +08:00
    插眼等完善,写脚本可以用的上
    thetbw
        2
    thetbw  
       2021-08-24 14:20:53 +08:00
    已 start ,其实对于这种小框架,感觉支持 sqlite 或者 h2 还是蛮不错了,毕竟都很轻量
    xgfan
        3
    xgfan  
       2021-08-24 14:48:08 +08:00
    好奇和 exposed 相比,有啥卖点吗?
    actar
        4
    actar  
    OP
       2021-08-24 15:20:36 +08:00
    @thetbw 可以考虑
    actar
        5
    actar  
    OP
       2021-08-24 15:25:50 +08:00
    原来我是使用 JPA + QueryDSL 的,然后使用有些地方不顺手。本来是打算包装一下 QueryDSL 方便自己用的。看了一部分代码,然后产生了我上我也行的错觉。 😂
    coderwl
        6
    coderwl  
       2021-08-25 20:15:24 +08:00
    直接 ktorm 不香吗
    VincentLau
        7
    VincentLau  
       2021-08-30 15:53:55 +08:00
    赞,不错
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2519 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 15:53 · PVG 23:53 · LAX 08:53 · JFK 11:53
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.