我一直在寻找一些用于映射object-object的scala流畅API,类似于AutoMapper。 Scala中有这样的工具吗?
答案 0 :(得分:12)
我认为在Scala中不太需要类似AutoMapper的东西,因为如果使用惯用的Scala模型更容易编写和操作,并且因为您可以使用隐式转换轻松定义自动展平/投影。
例如,这里是AutoMapper flattening example的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:我不应该使用Double来赚钱...
答案 1 :(得分:4)
我同意@paradigmatic,使用Scala的代码确实更干净,但有时您可以发现自己在看起来非常相似的案例类之间进行映射,而这只是浪费击键。
我已经开始研究解决问题的项目,你可以在这里找到它:https://github.com/bfil/scala-automapper
它使用宏为您生成映射。
目前,它可以将案例类映射到原始案例类的子集,它可以处理选项,可选字段以及其他小事。
我仍在试图弄清楚如何设计api以支持使用自定义逻辑重命名或映射特定字段,任何想法或输入都会非常有用。
它现在可以用于一些简单的情况,当然如果映射变得非常复杂,可能更好地手动定义映射。
该库还允许在任何情况下在案例类之间手动定义Mapping
类型,可以作为AutoMapping.map(sourceClass)
或sourceClass.mapTo[TargetClass]
方法的隐式参数提供。
<强>更新强>
我刚刚发布了一个处理Iterables,Maps并允许传递动态映射的新版本(例如,支持重命名和自定义逻辑)
答案 2 :(得分:2)
对于复杂映射,可能需要考虑基于Java的映射器,如
可以从Java访问Scala对象:
对于复杂对象的隐式转换实现,声明映射比手工制作映射更顺畅。
在此处找到更长的列表:
http://www.javacodegeeks.com/2013/10/java-object-to-object-mapper.html