2013-03-23 23 views
13

Có thể tự động tạo danh sách cho phương thức "bật" của anorm không?Tham số SQL động với Anorm và Scala Play Framework

Tôi có một biểu mẫu với các đầu vào tùy chọn và hiện tại tôi kiểm tra từng tùy chọn và tạo danh sách với các tùy chọn được xác định và đang cố gắng chuyển thông tin này đến dạng anorm. Hiện tại tôi nhận được lỗi biên dịch này

type mismatch; found : List[java.io.Serializable] required: (Any, anorm.ParameterValue[_]) 

Tôi không chắc chắn về cách tạo danh sách này. đang hiện tại:

val onList = List(
     'school_id = input.school, 
     if(input.rooms isDefined)  ('rooms -> input.rooms) else "None" , 
     if(input.bathrooms isDefined) ('bathrooms -> input.bathrooms) else "None" , 
     if(input.houseType isDefined) ('houseType -> input.houseType) else "None" , 
     if(input.priceLow isDefined) ('priceLow -> input.priceLow) else "None" , 
     if(input.priceHigh isDefined) ('priceHigh -> input.priceHigh) else "None" , 
     if(input.utilities isDefined) ('utilities -> input.utilities) else "None" 
).filter(_!="None") 
SQL("SELECT * FROM Houses WHERE " + whereString).on(onList).as(sqlToHouse *) 

Tôi đã cố gắng làm điều này vì ban đầu tôi nghĩ rằng nó sẽ được giống như

.on('rooms -> input.rooms, 'bathroom -> input.bathrooms... etc) 

EDIT:

Mã bây giờ là:

val onList = Seq(
     ('school_id -> input.school), 
     if(input.rooms isDefined)  ('rooms -> input.rooms.get)   else None , 
     if(input.bathrooms isDefined) ('bathrooms -> input.bathrooms.get) else None , 
     if(input.houseType isDefined) ('houseType -> input.houseType.get) else None , 
     if(input.priceLow isDefined) ('priceLow -> input.priceLow.get) else None , 
     if(input.priceHigh isDefined) ('priceHigh -> input.priceHigh.get) else None , 
     if(input.utilities isDefined) ('utilities -> input.utilities.get) else None 
).filter(_!=None).asInstanceOf[Seq[(Any,anorm.ParameterValue[_])]] 

sử dụng lệnh SQL:

SQL("SELECT * FROM Houses WHERE " + whereString).on(onList:_*).as(sqlToHouse *) 

Bây giờ nhận được ngoại lệ

[ClassCastException: java.lang.Integer cannot be cast to anorm.ParameterValue] 
+1

Tính năng này hoạt động như thế nào? 'WhereString' trông như thế nào? –

Trả lời

12

Điều quan trọng là bạn phải tạo giá trị loại ParameterValue. Việc này thường được thực hiện bằng chức năng toParameterValue().

Một cách sẽ được để tạo ra một chuỗi các lựa chọn mà bạn flatten:

val onList = Seq(
    Some('school_id -> input.school), 
    input.rooms.map('rooms -> _), 
    input.bathrooms.map('bathrooms -> _) 
).flatten 

chuỗi này sau đó có thể được ánh xạ để điều chỉnh giá trị:

SQL(
    "SELECT * FROM Houses WHERE " + whereString 
).on(
    onList.map(v => v._1 -> toParameterValue(v._2)): _* 
) 

Điều này có thể được đơn giản hóa như này:

val onList = Seq(
    Some('school_id -> input.school), 
    input.rooms.map('rooms -> _), 
    input.bathrooms.map('bathrooms -> _) 
).flatMap(_.map(v => v._1 -> toParameterValue(v._2))) 

SQL(
    "SELECT * FROM Houses WHERE " + whereString 
).on(
    onList: _* 
) 

Hoặc có thể là giải pháp đơn giản nhất sẽ là:

val onList = Seq(
    Some('school_id -> toParameterValue(input.school)), 
    input.rooms.map('rooms -> toParameterValue(_)), 
    input.bathrooms.map('bathrooms -> toParameterValue(_)) 
).flatten 

SQL(
    "SELECT * FROM Houses WHERE " + whereString 
).on(
    onList: _* 
) 
+0

Tuyệt vời! Tôi không biết về hàm toParameterValue. Cảm ơn – kingdamian42

1

Vì vậy, tôi đã kết thúc chỉ kêu gọi nhiều lần.

var query = SQL("SELECT * FROM Houses WHERE " + whereString).on('school_id -> input.school) 
if(input.rooms isDefined)  query= query.on('rooms -> input.rooms.get) 
if(input.bathrooms isDefined) query= query.on('bathrooms -> input.bathrooms.get) 
if(input.houseType isDefined) query= query.on('houseType -> input.houseType.get) 
if(input.priceLow isDefined) query= query.on('priceLow -> input.priceLow.get) 
if(input.priceHigh isDefined) query= query.on('priceHigh -> input.priceHigh.get) 
if(input.utilities isDefined) query= query.on('utilities -> input.utilities.get) 
query.as(sqlToHouse *) 
1

Bạn có thể có một cái nhìn tại tham số multivalue là Anorm tiếp theo (đến chơi 2.3/master).

Các vấn đề liên quan