Giter VIP home page Giter VIP logo

Comments (9)

jiaojing avatar jiaojing commented on August 17, 2024 1

嗯,我看到了,可以这样写。但是这个db是通过threadlocal的方式传递给map的。如果不用这个db{}包裹代码块,容易有坑(代码也不会提示不可以不包裹),比如在多线程执行的时候。 另外,把query定义为一个SQL构造器,而不直接map执行。用类似这样的方式进行绑定,个人认为代码风格更好些。

db.from(Employees)
    .where { e -> (e.organizationId ne null) and (e.name eq "John Doe") }
    .groupBy { e -> e.name }
    .having { e -> e.id ne null }
    .orderBy { e -> e.name.asc .. e.id.desc }
    .limit { 10 }
    .offset { 10 }
    .select { e -> e.id .. e.name }

或者类似slick这样:

val setup = DBIO.seq(
  // Create the tables, including primary and foreign keys
  (suppliers.schema ++ coffees.schema).create,

  // Insert some suppliers
  suppliers += (101, "Acme, Inc.",      "99 Market Street", "Groundsville", "CA", "95199"),
  suppliers += ( 49, "Superior Coffee", "1 Party Place",    "Mendocino",    "CA", "95460"),
  suppliers += (150, "The High Ground", "100 Coffee Lane",  "Meadows",      "CA", "93966"),
  // Equivalent SQL code:
  // insert into SUPPLIERS(SUP_ID, SUP_NAME, STREET, CITY, STATE, ZIP) values (?,?,?,?,?,?)

  // Insert some coffees (using JDBC's batch insert feature, if supported by the DB)
  coffees ++= Seq(
    ("Colombian",         101, 7.99, 0, 0),
    ("French_Roast",       49, 8.99, 0, 0),
    ("Espresso",          150, 9.99, 0, 0),
    ("Colombian_Decaf",   101, 8.99, 0, 0),
    ("French_Roast_Decaf", 49, 9.99, 0, 0)
  )
  // Equivalent SQL code:
  // insert into COFFEES(COF_NAME, SUP_ID, PRICE, SALES, TOTAL) values (?,?,?,?,?)
)

val setupFuture = db.run(setup)
  1. data class -> entity
  2. object table -> table schema 定义
  3. query表达式构造
  4. db.run

前3步都是和执行环境无关的,抽离之后,后续切换到coroutine 执行,只需要改进第4部分。

from ktorm.

vincentlauvlwj avatar vincentlauvlwj commented on August 17, 2024 1

谢谢你的建议,把 query 表达式的构造与执行环境分离确实有很大的意义,我会考虑如何改进

from ktorm.

vincentlauvlwj avatar vincentlauvlwj commented on August 17, 2024

这是可以的,看看这段代码是不是你想要的效果?

val db = Database.connect(url = "jdbc:h2:mem:ktorm;DB_CLOSE_DELAY=-1", driver = "org.h2.Driver")

val names = db {
    Employees
        .select(Employees.name)
        .where { Employees.departmentId eq 1 }
        .orderBy(Employees.salary.desc())
        .map { it.getString(1) }
}

assert(names.size == 2)
assert(names[0] == "vince")
assert(names[1] == "marry")

from ktorm.

jiaojing avatar jiaojing commented on August 17, 2024

我们刚开始在服务端使用kotlin,评估下来,ktorm是orm这块做的比较好的,也感谢你对项目的付出。

from ktorm.

785172550 avatar 785172550 commented on August 17, 2024

@jiaojing 我也在尝试用coroutine来执行sql, 但是感觉需要用异步的DB调用,而不是JDBC这种会阻塞线程的才有效,要不然也只是相当于在一个线程池里面做DB调用(这样同时的并发数,就是线程池数量与数据库连接池数量的两者最小值),我找到了这个数据库driver,
https://github.com/eclipse-vertx/vertx-sql-client
但是现在和ktorm不能结合,因为它不是JDBC协议的,我觉的能将构造sql表达和执行分离,就能用ktorm构造sql和将rowset转换为entity, 然后用vertx-sql-client 来执行数据库调用了,这样ORM框架就彻底和数据库driver层面解耦了

from ktorm.

jiaojing avatar jiaojing commented on August 17, 2024

我看了一下这个 rm-global-database-object分支的代码,非常赞。关于coroutine这块:
目前数据库的异步的驱动,也就jasync-sql这一个库,执行SQL以后返回的是CompletableFuture。这个很容易就可以转换成suspend函数。
Ktorm要支持的话,目前这个结构可能还需要修改。
目前Ktorm的query最终会在map,count等iterator的方法调用的时候,lazy 初始化一个iterator,这时会执行数据库查询操作。
image
但是底层用jasync-sql的话,database.executeExpression这个函数签名肯定就是suspend的了,就会传染整个调用链路。从这个作为突破口,可能会比较容易支持coroutine。有一个不成熟的建议是:query构造和db彻底解耦。db.run(query),或者asyncdb.run(query).后者方法签名是suspend的。

from ktorm.

vincentlauvlwj avatar vincentlauvlwj commented on August 17, 2024

是这样的,异步和同步是两个完全不一样的世界,很多库都没办法做到完美地同时支持两者。

我的想法是,与 Database 对应,增加一个 AsyncDatabase,它们分别支持异步和同步。但是这样的话 database.from(..)database.sequenceOf(..) 就要改,增加 AsyncQueryAsyncEntitySequenceAsyncSequenceGrouping 等一系列的 counterpart,这样一套下来,几乎所有的代码我们都要写两遍。

所以,与其这么做,我觉得还不如另外建一个 ktorm-async 的项目,一个支持异步的专门的 Ktorm 版本。反正代码都要重新写一遍,我不如直接把同步的 Ktorm 和异步的 Ktorm 分为两个项目,它们之间顶多就共享 SqlExpressionSqlFormatter 之类的这些代码,也就是你说的 query 构造部分。

你看看这个思路如何?

from ktorm.

jiaojing avatar jiaojing commented on August 17, 2024

嗯,也是一种方案。核心的就是SqlExpresion。然后DB执行他。

我去看了一下slick的方式。他是把query的拼接,数据库的其他操作,都和执行环境全部分离出来。 然后DB.run(DBIOAction)-> future 这种方式把所有最终的执行几乎都放到这一个函数里去了。这个函数返回的是future,也就是底层是同步(那就得自己用线程池转成异步的)或者异步的驱动都可以。所有的terminal 函数,最终调用这个run得到一个future。然后future就可以很简单转成suspend了。

不过这个我感觉不着急,kotlin目前还不成熟。我估计得等1.4以后,看看哪个版本kotlin的 multi-platform做好以后,coroutine的使用场景才会出来吧。目前也就Android下能用。服务端基本上都是spring的生态,基本用不到。

from ktorm.

jiaojing avatar jiaojing commented on August 17, 2024

最近翻了一下代码,其实query本身的构造,是不会suspend的。就是一个普通的函数。database.run(query)这个涉及到网络io,肯定是suspend的。之后获得一个QueryResult,然后再这个之后所有的数据结果的处理,变换按照我的理解,也是一个普通函数,不会suspend。也就是说整个coroutine控制在db的run方法上。这个database根据底层driver情况,提供两套执行的api其实就是suspend runAsync(query),runSync(query).然后使用者自行选择就行。

`kotlin
public suspend fun Database.run(query: Query): QueryResult = QueryResult(this, query)

public suspend fun Query.runBy(database: Database): QueryResult = QueryResult(database, this)

`

from ktorm.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.