Last active
August 29, 2015 14:18
-
-
Save KentaKomai/d2e72b272b4c756cc562 to your computer and use it in GitHub Desktop.
anormで汎用的なモデル考えてみた
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package models | |
import java.sql.Connection | |
import anorm._ | |
import anorm.SqlParser._ | |
import play.api.Play.current | |
import play.api.db.DB | |
/** 性別を表すクラス(本来は別ファイルにしたほうがいいかも) */ | |
sealed abstract class Gender(val code:Int) | |
object Gender{ | |
case object Unknown extends Gender(0) | |
case object Male extends Gender(1) | |
case object Female extends Gender(2) | |
def all:Set[Gender] = Set(Unknown, Male, Female) | |
def apply(code:Int):Gender = all.find( t => code == t.code ).getOrElse(Unknown) | |
} | |
/** ユーザの週別を表すクラス(本来は別ファイルにしたほうがいいかも) */ | |
sealed abstract class UserType(val code:Int) | |
object UserType{ | |
case object SuperAdmin extends UserType(1) | |
case object Admin extends UserType(2) | |
case object Normal extends UserType(3) | |
case object Invalid extends UserType(0) | |
def all:Set[UserType] = Set(SuperAdmin, Admin, Normal) | |
def apply(code:Int):UserType = all.find( t => code == t.code ).getOrElse(Invalid) | |
} | |
/** Userテーブル */ | |
case class User(id:Long, name:String, gender:Gender, age:Int, profile:Option[String], userTYpe:UserType) | |
object User { | |
/** テーブル名 */ | |
protected[models] val tableName = "user" | |
/** 各カラム名 */ | |
protected[models] object ColumnNames{ | |
val id = "id" | |
val name = "name" | |
val gender = "gender" | |
val age = "age" | |
val profile = "profile" | |
val userType = "user_type" | |
} | |
private val userParser = long(ColumnNames.id) ~ str(ColumnNames.name) ~ int(ColumnNames.gender) ~ int(ColumnNames.age) ~ get[Option[String]](ColumnNames.profile) ~ int(ColumnNames.userType) | |
private val userMapper = userParser.map({ | |
case id ~ name ~ gender ~ age ~ profile ~ userTypeCode => | |
User(id, name, Gender(gender), age, profile, UserType(userTypeCode)) | |
}) | |
private def userValues(implicit user:User) = { | |
Seq[NamedParameter]( | |
ColumnNames.name -> user.name, | |
ColumnNames.gender -> user.gender.code, | |
ColumnNames.age -> user.age, | |
ColumnNames.profile -> user.profile, | |
ColumnNames.userType -> user.userTYpe.code | |
) | |
} | |
/** ID検索 */ | |
def findById(id:Long):Option[User] = DB.withConnection { implicit con => | |
SQL(s""" | |
SELECT * FROM $tableName WHERE ${ColumnNames.id} = {${ColumnNames.id}} | |
""" | |
).on(ColumnNames.id -> id).as(userMapper.singleOpt) | |
} | |
/** 汎用的な検索 */ | |
def find(whereConditions:String*):List[User] = DB.withConnection { implicit con => | |
SQL(s""" | |
SELECT * FROM $tableName WHERE ${assembleWhereSentence(whereConditions)} | |
""" | |
).as(userMapper.*) | |
} | |
/** 更新 */ | |
def update(user:User):Int = DB.withConnection { implicit con => | |
SQL(s""" | |
UPDATE $tableName SET | |
${ColumnNames.name} = {${ColumnNames.name}}, | |
${ColumnNames.gender} = {${ColumnNames.gender}}, | |
${ColumnNames.age} = {${ColumnNames.age}}, | |
${ColumnNames.profile} = {${ColumnNames.profile}}, | |
${ColumnNames.userType} = {${ColumnNames.userType}} | |
WHERE ${ColumnNames.id} = ${ColumnNames.id} | |
""" | |
).on( (userValues(user) ++: Seq[NamedParameter](ColumnNames.id -> user.id) ): _* ).executeUpdate() | |
} | |
/** 挿入 SQL Interpolation使ったほうがいいかな・・・ */ | |
def insert(user:User):Option[Long] = DB.withConnection { implicit con => | |
SQL(s""" | |
INSERT INTO $tableName ( | |
${ColumnNames.name}, | |
${ColumnNames.gender}, | |
${ColumnNames.age}, | |
${ColumnNames.profile}, | |
${ColumnNames.userType}, | |
) VALUE ( | |
{${ColumnNames.name}}, | |
{${ColumnNames.gender}}, | |
{${ColumnNames.age}}, | |
{${ColumnNames.profile}}, | |
{${ColumnNames.userType}}, | |
) | |
""" | |
).on(userValues(user): _*).executeInsert() | |
} | |
/** 削除 */ | |
def delete(id:Long):Int = DB.withConnection { implicit con => | |
SQL(s""" | |
DELETE FROM $tableName WHERE ${ColumnNames.id} = {${ColumnNames.id}} | |
""" | |
).on(ColumnNames.id -> id).executeUpdate() | |
} | |
/** WHERE文を組み立てて文字列を返す関数 */ | |
private def assembleWhereSentence(conditions:Seq[String]):String = { | |
val wherePrefix = "WHERE 1" | |
conditions.foldLeft(wherePrefix) { | |
(acc, sentence) => acc + "AND " + sentence | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment