ScalaでDDDを実践する③ Lift+Mybatis編


前回は、SBTプロジェクトでMavenのレポジトリを使用する方法とIntelliJを使用する方法を解説しました。

今回はいよいよLiftのMapperの代わりにMyBatisを使用します。

Modelは以下のように簡単なものを用意します。

Book.scala
[cc lang=”scala”]
package code.model

class Book(id:Int, name:BookName){
def this(id:Int)=this(id, null)

final val bookId = id

var bookName = name
}
[/cc]
BookName.scala
[cc lang=”scala”]
package code.model

case class BookName(final val name:String) {
}
[/cc]
本来であれば、hashcodeやequalsメソッドをoverrideしたりidをValueObjectにしたりとするべきなのですが、今回は省きました。

ポイントはDDDらしく、val・finalを使用している事。当然コンストラクタからのみこれらは生成するしかないわけですが、MyBatisの場合それが可能です。
また、ValueObjectはcaseクラスにしています。

Mybatisの設定ファイルは『main/resources』内にJavaと同じ用に記載します。
[cc lang=”xml”]







[/cc]
ResultMapは以下のように書きます。
[cc lang=”xml”]











INSERT INTO BOOK(NAME) VALUES(#{bookName.bookName})

[/cc]
ポイントはconstructorタグです。
これを指定することで、コンストラクタから値を設定することが可能になり、privateフィールドも使用可能になるのです。

また、_intですが、これはIntのエイリアスです。Integerと書くとMybatisは『java.lang.Integer』と解釈されてエラーになるのでScalaのIntと判断させるためにIntegerは使用しないことがポイントです。

もうひとつのポイントはconstructorタグには基本型しか使用できない事です。この点はMyBatisで改善して欲しいところですが(もしかしたら私の調査不足でできるかもしれません。その際はご指摘下さい。)
今のところはvalで指定した基本型のみを生成するコンストラクタをオーバーロードしておくしかないという制約が生じます。
しかし、これでフレームワークでのみ使用されるsetterを用意することはなくなり、よりDDDらしくなるのではと思っています。

これでJavaのMyBatisと同様の使い方ができます。
[cc lang=”scala”]
package code.model

import org.apache.ibatis.session.SqlSessionFactoryBuilder
import org.apache.ibatis.io.Resources;

class BookRepository{
val sqlMap = new SqlSessionFactoryBuilder().build(
Resources.getResourceAsReader(“mybatis-config.xml”))

def getBookById(id: Long):Book ={
val session = sqlMap.openSession()
try{
session.selectOne(“Book.getBook”, id).asInstanceOf[Book]
}finally {
session.close
}
}

def insertBook(book:Book)={
val session = sqlMap.openSession()

try{
session.insert(“Book.insertBook”, book)
session.commit
}finally {
session.close
}
}
}
[/cc]
後は普通にスニペット上からこのレポジトリを呼び出す事が可能です。
ただし、スニペットはApplication層でなく、Interface層に属すると個人的には思っているので実際はApplication層のサービスクラスを作成し、そこから使用するのがベストかと思っています。

次回はBeanValidationをLiftで使用してみます。

1件のコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です