powerdee.com
Google
 
このサイト内 Web
 
カウンタ

STEP2.永続化層

INDEX

1.Entityクラスの作成

まず、書籍情報テーブルの1件分のレコード情報を保持するEntityクラスを作成します。

package com.powerdee.entity;

import java.util.Date;

public class BookInfo {
    
    // 各レコードのフィールド値を格納するためのプライベート変数
    private String isbn;
    private String title;
    private String authorName;
    private Integer price;
    private String publish;
    private Date publicationDay;
    
    // コンストラクタ
    public BookInfo() {
    }

    /**
     * 全てのプロパティを受け取るコンストラクタ
     */
    public BookInfo(final String isbn, final String title, final String authorName,
            final Integer price, final String publish, final Date publicationDay) {
        this.setIsbn(isbn);
        this.setTitle(title);
        this.setAuthorName(authorName);
        this.setPrice(price);
        this.setPublish(publish);
        this.setPublicationDay(publicationDay);
    }

    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public Date getPublicationDay() {
        return publicationDay;
    }

    public void setPublicationDay(Date publicationDay) {
        this.publicationDay = publicationDay;
    }

    public String getPublish() {
        return publish;
    }

    public void setPublish(String publish) {
        this.publish = publish;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthorName() {
        return authorName;
    }

}

2.Hibernateマッピング定義ファイルの作成

先ほど作成した、Entityクラス(BookInfo)と、BOOK_INFO_TBLテーブルの各カラム属性との対応付けする定義ファイルを作成します。 ファイルは、com/powerdee/entity/BookInfo.hbm.xml です。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN" 
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
    <class
        name="com.powerdee.entity.BookInfo"
        table="BOOK_INFO_TBL"
    >

        <id
            name="isbn"
            column="ISBN"
            type="java.lang.String"
        >
            <generator class="assigned" />
        </id>

        <property
            name="title"
            type="java.lang.String"
            update="true"
            insert="true"
            column="TITLE"
            not-null="true"
            length="50"
        />

        <property
            name="authorName"
            type="java.lang.String"
            update="true"
            insert="true"
            column="AUTHOR_NAME"
            not-null="true"
            length="50"
        />

        <property
            name="price"
            type="java.lang.Integer"
            update="true"
            insert="true"
            column="PRICE"
            not-null="true"
        />

        <property
            name="publish"
            type="java.lang.String"
            update="true"
            insert="true"
            column="PUBLISH"
            not-null="false"
            length="50"
        />

        <property
            name="publicationDay"
            type="java.util.Date"
            update="true"
            insert="true"
            column="PUBLICATION_DAY"
            not-null="false"
        />

    </class>

</hibernate-mapping>

3.DAOインターフェイスの作成

DAOの実装を行う前に、インターフェイスを作成します。 例えば、実装方式がHibernate以外になっても影響をうけなくなるからです。 書籍情報テーブルに対して、以下のメソッドを定義します。

  • 書籍情報をキー(ISBN)で取得する
  • 書籍情報を保存、更新する
  • 書籍情報を削除する
  • 書籍情報の一覧を取得する
package com.powerdee.dao;

import java.util.List;

import org.springframework.dao.DataAccessException;
import com.powerdee.entity.BookInfo;

public interface IBookInfoDao {
    public BookInfo getBookInfo(String isbn) throws DataAccessException;
    public String saveBookInfo(BookInfo bookInfo) throws DataAccessException;
    public void deleteBookInfo(String isbn) throws DataAccessException;
    public List selectAllBookInfo() throws DataAccessException;
}

4.DAOのテストケースの作成

テストケースを先に作成しておきましょう。 DAOの実装はまだですよ!

package com.powerdee.dao;

import java.text.SimpleDateFormat;
import java.util.List;

import junit.framework.TestCase;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.dao.DataAccessException;

import com.powerdee.entity.BookInfo;

public class BookInfoDaoImplTest extends TestCase {
    
    private IBookInfoDao dao = null;

    protected void setUp() throws Exception {
        super.setUp();
        ApplicationContext ctx = new ClassPathXmlApplicationContext(
                                 "/WEB-INF/applicationContext*.xml");
        dao = (IBookInfoDao) ctx.getBean("bookInfoDao");
    }

    public void testSaveBookInfo() throws Exception {
        BookInfo bookInfo = new BookInfo();
        bookInfo.setIsbn("4-9999-9999-9");
        bookInfo.setAuthorName("テスト 太郎");
        bookInfo.setTitle("実践 SpringFramework");
        bookInfo.setPrice(new Integer(3800));
        bookInfo.setPublish("日経BP");

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        String date = "2005/05/23";
        bookInfo.setPublicationDay(sdf.parse(date));
        
        dao.saveBookInfo(bookInfo);
        
        BookInfo newBookInfo = dao.getBookInfo("4-9999-9999-9");

        assertEquals("4-9999-9999-9", newBookInfo.getIsbn());
    }
    
    public void testGetBookInfo() throws Exception {
        BookInfo bookInfo = dao.getBookInfo("4-9999-9999-9");
        assertEquals("テスト 太郎", bookInfo.getAuthorName());
        assertEquals("実践 SpringFramework", bookInfo.getTitle());
        assertEquals("日経BP", bookInfo.getPublish());
        assertEquals(3800, bookInfo.getPrice().intValue());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
        assertEquals("2005/05/23", sdf.format(bookInfo.getPublicationDay()));
    }
    
    public void testSelectAllBookInfo() throws Exception {
        List bookInfoList;
        int count = 0;
        bookInfoList = dao.selectAllBookInfo();
        count = bookInfoList.size();
        
        BookInfo bookInfo = new BookInfo();
        bookInfo.setIsbn("4-8888-8888-8");
        bookInfo.setAuthorName("テスト 次郎");
        bookInfo.setTitle("テストタイトル");
        bookInfo.setPrice(new Integer(200));
        dao.saveBookInfo(bookInfo);
        bookInfoList = dao.selectAllBookInfo();
        assertEquals("総件数", count + 1, bookInfoList.size());
    }

    public void testDeleteBookInfo() throws Exception {
        dao.deleteBookInfo("4-9999-9999-9");
        dao.deleteBookInfo("4-8888-8888-8");

        try {
            dao.getBookInfo("4-9999-9999-9");
            dao.getBookInfo("4-8888-8888-8");
            fail("BookInfo found in database");
        } catch (DataAccessException dae) {
            assertNotNull(dae);
        }
    }

}

5.DAO用のBean定義ファイル

[APPHOME]/WEB-INF/applicationContext-dao.xml を作成します。 さきほど作成したマッピングファイル(BookInfo.hbm.xml)をsessionFactoryのbeanタグに登録してます。複数の指定もできるようです。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
    "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

  <bean id="sessionFactory" 
      class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
    <property name="dataSource"><ref bean="dataSource"/></property>
    <property name="mappingResources">
      <list>
        <value>com/powerdee/entity/BookInfo.hbm.xml</value>
      </list>
    </property>
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>
      </props>
    </property>
  </bean>

  <bean id="bookInfoDao" class="com.powerdee.dao.hibernate.BookInfoDaoImpl">
    <property name="sessionFactory"><ref local="sessionFactory"/></property>
  </bean>

</beans>

6.DAOの作成

O/RマッピングツールのHibernate用のDataAccessObjectを作成します。 SpringFrameworkのHibernateサポート機能をつかってますので、かなりシンプルに実装できます。

package com.powerdee.dao.hibernate;

import java.util.List;

import org.springframework.orm.hibernate.support.HibernateDaoSupport;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.DataRetrievalFailureException;
import com.powerdee.entity.BookInfo;
import com.powerdee.dao.IBookInfoDao;

public class BookInfoDaoImpl extends HibernateDaoSupport implements IBookInfoDao {
    
    public BookInfo getBookInfo(String isbn) throws DataAccessException {
        BookInfo bookInfo 
            = (BookInfo) getHibernateTemplate().get(BookInfo.class, isbn);
        
        if (bookInfo == null) {
            throw new DataRetrievalFailureException
              ("Failed to get bookInfo: isbn=(" + isbn + ")");
        }
        return bookInfo;
    }
    
    public String saveBookInfo(BookInfo bookInfo) throws DataAccessException {
        BookInfo newBookInfo 
            = (BookInfo) getHibernateTemplate().saveOrUpdateCopy(bookInfo);
        return newBookInfo.getIsbn();
    }
    
    public void deleteBookInfo(String isbn) throws DataAccessException {
        getHibernateTemplate().delete(getBookInfo(isbn));
    }
    
    public List selectAllBookInfo() throws DataAccessException {
        return getHibernateTemplate().loadAll(BookInfo.class);
    }

}

7.テスト実行!

さて、以上でテスト実行に必要なファイルができました。クラスパスを適切に設定して、動作確認をしてみます。 eclipseを利用すれば、簡単だと思います。 "com.powerdee.dao.BookInfoDaoImplTest" を JUnitテストで実行します。


おすすめ書籍


SpringによるWebアプリケーションスーパーサンプル

著者:村山 雅彦、阪田 浩一、奥 清隆
出版社:ソフトバンククリエイティブ(2006-07-29)
価格:¥3,990(税込)
Light Weight Java―JSF/Hibernate/SpringによるフレームワークでWebアプリケーションの開発効率向上

著者:岡本 隆史、金子 崇之、吉田 英嗣、権藤 夏男
出版社:毎日コミュニケーションズ(2005-04)
価格:¥3,360(税込)
Apache Maven 2.0入門 Java・オープンソース・ビルドツール

著者:野瀬 直樹、横田 健彦
出版社:技術評論社(2006-12-13)
価格:¥2,499(税込)
Spring2.0入門 Java・オープンソース・Web開発自由自在

著者:株式会社豆蔵、長谷川 裕一、岩永 寿来、伊藤 清人、大野 渉、麻野 耕一
出版社:技術評論社(2006-12-28)
価格:¥3,654(税込)


ページTopへ / ▲Homeへ