Scala 有类似 AutoMapper 的东西吗?

发布于 2024-11-27 06:46:23 字数 115 浏览 3 评论 0原文

我一直在寻找一些用于映射对象到对象的 scala 流畅 API,类似于 AutoMapper。 Scala中有这样的工具吗?

I have been looking for some scala fluent API for mapping object-object, similar to AutoMapper.
Are there such tools in Scala?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

初见终念 2024-12-04 06:46:23

我认为 Scala 中不太需要像 AutoMapper 这样的东西,因为如果您使用惯用的 Scala 模型,则更容易编写和操作,并且您可以使用隐式转换轻松定义自动展平/投影。

例如,这里是 AutoMapper 的 Scala 扁平化示例 中的等效项:

// The full model

case class Order( customer: Customer, items: List[OrderLineItem]=List()) {
  def addItem( product: Product, quantity: Int ) = 
    copy( items = OrderLineItem(product,quantity)::items )
  def total = items.foldLeft(0.0){ _ + _.total }
}

case class Product( name: String, price: Double )

case class OrderLineItem( product: Product, quantity: Int ) {
  def total = quantity * product.price
}

case class Customer( name: String )

case class OrderDto( customerName: String, total: Double )


// The flattening conversion

object Mappings {
  implicit def order2OrderDto( order: Order ) = 
    OrderDto( order.customer.name, order.total )
}


//A working example

import Mappings._

val customer =  Customer( "George Costanza" )
val bosco = Product( "Bosco", 4.99 )
val order = Order( customer ).addItem( bosco, 15 )

val dto: OrderDto = order // automatic conversion at compile-time !

println( dto ) // prints: OrderDto(George Costanza,74.85000000000001)

PS:我不应该使用金额翻倍...

I think there's less need of something like AutoMapper in Scala, because if you use idiomatic Scala models are easier to write and manipulate and because you can define easily automatic flattening/projection using implicit conversions.

For example here is the equivalent in Scala of AutoMapper flattening example:

// The full model

case class Order( customer: Customer, items: List[OrderLineItem]=List()) {
  def addItem( product: Product, quantity: Int ) = 
    copy( items = OrderLineItem(product,quantity)::items )
  def total = items.foldLeft(0.0){ _ + _.total }
}

case class Product( name: String, price: Double )

case class OrderLineItem( product: Product, quantity: Int ) {
  def total = quantity * product.price
}

case class Customer( name: String )

case class OrderDto( customerName: String, total: Double )


// The flattening conversion

object Mappings {
  implicit def order2OrderDto( order: Order ) = 
    OrderDto( order.customer.name, order.total )
}


//A working example

import Mappings._

val customer =  Customer( "George Costanza" )
val bosco = Product( "Bosco", 4.99 )
val order = Order( customer ).addItem( bosco, 15 )

val dto: OrderDto = order // automatic conversion at compile-time !

println( dto ) // prints: OrderDto(George Costanza,74.85000000000001)

PS: I should not use Double for money amounts...

皓月长歌 2024-12-04 06:46:23

我同意@paradigmatic,确实使用 Scala 代码会更干净,但有时您会发现自己在看起来非常相似的案例类之间进行映射,这只是浪费按键。

我已经开始开发一个项目来解决这些问题,您可以在这里找到它:https://github。 com/bfil/scala-automapper

它使用宏为您生成映射。

目前,它可以将案例类映射到原始案例类的子集,它处理可选值、可选字段以及其他次要事物。

我仍在尝试弄清楚如何设计 api 以支持使用自定义逻辑重命名或映射特定字段,任何想法或输入都会非常有帮助。

它现在可以用于一些简单的情况,当然,如果映射变得非常复杂,那么手动定义映射可能会更好。

该库还允许在任何情况下手动定义案例类之间的 Mapping 类型,这些类型可以作为隐式参数提供给 AutoMapping.map(sourceClass)sourceClass .mapTo[TargetClass] 方法。

更新

我刚刚发布了一个新版本,可以处理 Iterables、Maps 并允许传递动态映射(例如支持重命名和自定义逻辑)

I agree with @paradigmatic, it's true that the code will be much cleaner using Scala, but sometimes you can find yourself mapping between case classes that look very similar, and that's just a waste of keystrokes.

I've started working on a project to address the issues, you can find it here: https://github.com/bfil/scala-automapper

It uses macros to generate the mappings for you.

At the moment it can map a case class to a subset of the original case class, it handles optionals, and optional fields as well as other minor things.

I'm still trying to figure out how to design the api to support renaming or mapping specific fields with custom logic, any idea or input on that would be very helpful.

It can be used for some simple cases right now, and of course if the mapping gets very complex it might just be better defining the mapping manually.

The library also allows to manually define Mapping types between case classes in any case that can be provided as an implicit parameter to a AutoMapping.map(sourceClass) or sourceClass.mapTo[TargetClass] method.

UPDATE

I've just released a new version that handles Iterables, Maps and allows to pass in dynamic mappings (to support renaming and custom logic for example)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文