ScalaからHibernateを使ってみる。
利用するライブラリ
利用するライブラリは以下
- antlr-2.7.6.jar
- commons-collections-3.1.jar
- commons-lang-2.4.jar
- dom4j-1.6.1.jar
- ejb3-persistence.jar
- h2-1.1.117.jar
- hibernate3.jar
- hibernate-annotations.jar
- hibernate-commons-annotations.jar
- javassist-3.9.0.GA.jar
- jta-1.1.jar
- slf4j-api-1.5.8.jar
- slf4j-jdk14-1.5.8.jar
ライブラリが依存関係を含めて不足していると、Scalaコンパイルが通らないことがあるので注意
Entityの作成
ポイントはアノテーションの属性名としてvalを付けて記述すること。
import javax.persistence._ @Entity @Table{ val name="product" } class Product(n: String) { def this() = this("") @Id @GeneratedValue{ val strategy=GenerationType.IDENTITY } var id : Int = _ var name : String = n override def toString = "Product: " + id + " " + name }
hibernate.cfg.xml
ソースフォルダ直下にhibernate.cfg.xmlを作成(Eclipse使用)
例によって、hibernate.hbm2ddl.autoでDDL自動実行
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="connection.driver_class">org.h2.Driver</property> <property name="connection.url">jdbc:h2:tcp://localhost:9092/hibernate</property> <property name="connection.username">sa</property> <property name="connection.password"></property> <property name="dialect">org.hibernate.dialect.H2Dialect</property> <property name="current_session_context_class">thread</property> <property name="hibernate.hbm2ddl.auto">create</property> <property name="hibernate.show_sql">true</property> <mapping class="etc9.Product"/> </session-factory> </hibernate-configuration>
実行オブジェクト
H2を起動し、DB操作を行う。
import scala.xml._ import org.hibernate._ import org.hibernate.cfg._ object ProductTest { def main(args : Array[String]) : Unit = { val tcpServer = org.h2.tools.Server.createTcpServer( Array("-baseDir", "db\\h2", "-tcpPort", "9092")) tcpServer.start operateDb tcpServer.shutdown } lazy val sessionFactory = (new AnnotationConfiguration).configure.buildSessionFactory def operateDb = { withTxSession(session => { val p1 = new Product("Scala1") session.save(p1) val p2 = new Product("Scala2") session.save(p2) val eIter = session.createQuery("from Product").list.iterator while (eIter.hasNext) { val p = eIter.next.asInstanceOf[Product] println(p) } }) } def withTxSession(f:(Session) => Any) = { val s = sessionFactory.getCurrentSession val t = s.beginTransaction val r = f(s) t.commit r } }
実行結果は、
Hibernate: insert into product (id, name) values (null, ?) Hibernate: insert into product (id, name) values (null, ?) Hibernate: select product0_.id as id0_, product0_.name as name0_ from product product0_ Product: 1 Scala1 Product: 2 Scala2
hibernate.cfg.xmlファイル無し
ScalaはXMLをリテラルで扱えるので、ソースファイルにHibernate設定を記述してみる。
package etc9 import scala.xml._ import org.hibernate._ import org.hibernate.cfg._ object ProductTest { def main(args : Array[String]) : Unit = { val tcpServer = org.h2.tools.Server.createTcpServer( Array("-baseDir", "db\\h2", "-tcpPort", "9092")) tcpServer.start operateDb tcpServer.shutdown } lazy val sessionFactory = (new AnnotationConfiguration).configure.buildSessionFactory def operateDb = { withTxSession(session => { val p1 = new Product("Scala1") session.save(p1) val p2 = new Product("Scala2") session.save(p2) val eIter = session.createQuery("from Product").list.iterator while (eIter.hasNext) { val p = eIter.next.asInstanceOf[Product] println(p) } }) } def withTxSession(f:(Session) => Any) = { val s = sessionFactory.getCurrentSession val t = s.beginTransaction val r = f(s) t.commit r } lazy val parseDocFactory = javax.xml.parsers.DocumentBuilderFactory.newInstance def parseDoc(x: Node) = { import org.xml.sax.InputSource import java.io.StringReader parseDocFactory.newDocumentBuilder.parse(new InputSource(new StringReader(x.toString))) } def configDoc = parseDoc(configXML) def configXML = <hibernate-configuration> <session-factory> <property name="connection.driver_class">org.h2.Driver</property> <property name="connection.url">jdbc:h2:tcp://localhost:9092/hibernate</property> <property name="connection.username">sa</property> <property name="connection.password"></property> <property name="dialect">org.hibernate.dialect.H2Dialect</property> <property name="current_session_context_class">thread</property> <property name="hibernate.hbm2ddl.auto">create</property> <property name="hibernate.show_sql">true</property> <mapping class="etc9.Product"/> </session-factory> </hibernate-configuration> }