Compassラーニングドキュメント(3)


次に、上級部分のCompassとHibernate、Springの統合について説明します.Compass内部にはHibernate,Springへのサポートがあり,構成が整っていれば,インデックスの作成と更新の際にCompassでコードを書かなくてもよい.さわやかでしょう!~しかし、それらを統合するのは面倒です.では、私の一歩一歩を見てみましょう.まずHibernateとSpringを統合します.
次に、データベース・スクリプト(MySql)を見てみましょう.
CREATE TABLE `article` (

 `Id` int(11) NOT NULL auto_increment,

 `title` varchar(40) NOT NULL default '',

 `author` int(11) default '0',

 `publish_date` date NOT NULL default '0000-00-00',

 PRIMARY KEY (`Id`)

) TYPE=MyISAM;

 

CREATE TABLE `author` (

 `Id` int(11) NOT NULL auto_increment,

 `username` varchar(20) NOT NULL default '',

 `password` varchar(20) NOT NULL default '',

 `age` smallint(6) default '0',

 PRIMARY KEY (`Id`)

) TYPE=MyISAM;

 
CompassHibernateSpringというプロジェクトを構築します
開発環境について説明する:eclipse 3.2+myeclipse5.0+springtide+middlegen(MyEcilpseのHibernateとSpring能力をエンジニアリングに組み込むことに注意.
そしてHibernateで組み立てる、Hibernateには3つのプロファイルがある:hibernate.cfg.xml, Article.hbm.xml,Author.hbm.xml
具体的な仕組みはcfg.xml:
<?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="dialect">org.hibernate.dialect.MySQLDialect</property>

        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>

        <property name="connection.username">root</property>

        <property name="connection.password">java</property>

        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>

        <property name="show_sql">true</property>

        <mapping resource="org/li/compass/shibernate/Article.hbm.xml" />

        <mapping resource="org/li/compass/shibernate/Author.hbm.xml" />

    </session-factory>

</hibernate-configuration>

Article.hbm.xml:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>

<!-- 

    Created by the Middlegen Hibernate plugin 2.2

    http://boss.bekk.no/boss/middlegen/

    http://www.hibernate.org/

-->

<class 

    name="org.li.compass.shibernate.Article" 

    table="article"

    lazy="false"

> 

    <id

        name="id"

        type="java.lang.Integer"

        column="Id"

    >

            <meta attribute="field-description" inherit="false">

               auto_increment

            </meta>

        <generator class="increment" />

    </id>

    <property

        name="title"

        type="java.lang.String"

        column="title"

        not-null="true"

        length="40"

    />

    <property

        name="author"

        type="java.lang.String"

        column="author"

        length="11"

    />

    <property

        name="publishDate"

        type="java.util.Date"

        column="publish_date"

        not-null="true"

        length="10"

    />

    <!-- Associations -->

 

</class>

</hibernate-mapping>

Author.hbm.xml:

<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC

    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >

<hibernate-mapping>

<!-- 

    Created by the Middlegen Hibernate plugin 2.2

    http://boss.bekk.no/boss/middlegen/

    http://www.hibernate.org/

-->

<class 

    name="org.li.compass.shibernate.Author" 

    table="author"

    lazy="false"

> 

    <id

        name="id"

        type="java.lang.Integer"

        column="Id"

    >

            <meta attribute="field-description" inherit="false">

               auto_increment

            </meta>

    

        <generator class="increment" />

    </id>

    <property

        name="username"

        type="java.lang.String"

        column="username"

        not-null="true"

        length="20"

    />

    <property

        name="password"

        type="java.lang.String"

        column="password"

        not-null="true"

        length="20"

    />

    <property

        name="age"

        type="java.lang.Short"

        column="age"

        length="6"

    />

    <!-- Associations -->


</class>

</hibernate-mapping>

具本のPOJO類はソースコードを見ましょう:
ここはCompassなので、HibernateやSpringに関する内容はネット上で中国語の資料がたくさんあるので、ここでは紹介しません.
次は私について一歩一歩SpringでHibernateとCompassを統合します.
アプリケーションContext.xml:
<bean id="sessionFactory"

        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

        <property name="dataSource">

            <ref local="dataSource" />

        </property>

        <property name="hibernateProperties">

            <props>

                <prop key="dialect">

                    org.hibernate.dialect.MySQLDialect

                </prop>

                <prop key="show_sql">true</prop>

            </props>

        </property>

        <property name="mappingDirectoryLocations">

            <list>

                <value>org/li/compass/shibernate</value>

            </list>

        </property>

    </bean>

<bean id="dataSource"

        class="org.springframework.jdbc.datasource.DriverManagerDataSource">

        <property name="driverClassName">

            <value>com.mysql.jdbc.Driver</value>

        </property>

        <property name="url">

            <value>jdbc:mysql://localhost:3306/test</value>

        </property>

        <property name="username">

            <value>root</value>

        </property>

        <property name="password">

            <value>java</value>

        </property>

    </bean>

    <bean id="hibernateTemplate"

        class="org.springframework.orm.hibernate3.HibernateTemplate">

        <property name="sessionFactory">

            <ref local="sessionFactory" />

        </property>

    </bean>

<bean id="articleDAO" class="org.li.compass.shibernate.dao.ArticleDAO">

        <property name="hibernateTemplate">

            <ref local="hibernateTemplate"/>

        </property>

    </bean>

    <bean id="authorDAO" class="org.li.compass.shibernate.dao.AuthorDAO">

        <property name="hibernateTemplate">

            <ref local="hibernateTemplate"/>

        </property>

    </bean>

<bean id="transactionManager"

        class="org.springframework.orm.hibernate3.HibernateTransactionManager">

        <property name="sessionFactory">

            <ref local="sessionFactory" />

        </property>

    </bean>

以上の構成はSpringとHibernateを統合したものです.
次にCompassの構成を追加します.
私たちは文章だけを検索するので、文章だけをインデックス化します.
      Article.cpm.xml:
<!DOCTYPE compass-core-mapping PUBLIC 

    "-//Compass/Compass Core Mapping DTD 1.0//EN"

    "http://www.opensymphony.com/compass/dtd/compass-core-mapping.dtd">

<compass-core-mapping package="org.li.compass.shibernate">

    <class name="Article" alias="article">

        <!--        -->

        <id name="id"/>

        <!--                      Field("type","java") -->

        <constant>

            <meta-data>type</meta-data>

            <meta-data-value>java</meta-data-value>

        </constant>

        <!--        -->

        <property name="title">

            <meta-data>titleIndex</meta-data>

        </property>

        <property name="publishDate">

            <meta-data>publishDateIndex</meta-data>

        </property>

        <property name="author">

            <meta-data>author</meta-data>

        </property>

    </class>

</compass-core-mapping>

次にアプリケーションContextに戻ります.xml:
統合方法を見てみましょう.Compassにorgがあります.compass.gps.impl.SingleCompassGpsはCompassをリアルタイムで更新し、org.compass.spring.device.hibernate.SpringHibernate3GpsDevice
これはHibernateと統合され、Hibernateのinsert、delete、updateを自動的に更新するので、そうではありません.
私たちはCompassのためにコードを書きました.しかし、この2つのクラスのCompassとHibernateに対するリアルタイム機能もSpringのAOPで実現できる(ここでも議論しない).残りはSpringのIoCでCompassの初期化機能をサポートして注入し、1つ目は:
<bean id="compassConfiguration"

        class="org.compass.core.config.CompassConfiguration" />

2つ目は
<bean id="compass" class="org.compass.spring.LocalCompassBean">

        <!--               -->

        <property name="classMappings">

            <list>

                <value>org.li.compass.shibernate.Article</value>

            </list>

        </property>


        <property name="resourceDirectoryLocations">

            <list>

                <value>org/li/compass/shibernate</value>

            </list>

        </property>

        <property name="compassConfiguration"

            ref="compassConfiguration" />

        <property name="compassSettings">

            <props>

                <prop key="compass.engine.connection">target/test</prop>

                <prop key="compass.transaction.factory">

                    org.compass.spring.transaction.SpringSyncTransactionFactory

                </prop>

            </props>

        </property>

        <property name="transactionManager" ref="transactionManager" />

    </bean>

インデックスを作成するクラスとしてのみ使用できるように構成します.
また、HibernateやSpringとの統合とはあまり差がありません.CompassTemplateのDAOテンプレートも注入します
<bean id="compassTemplate" class="org.compass.core.CompassTemplate">

        <property name="compass">

            <ref local="compass"/>

        </property>

    </bean>

重要な2つのクラスの注入もあります.
<bean id="hibernateGpsDevice"

        class="org.compass.spring.device.hibernate.SpringHibernate3GpsDevice">

        <property name="name">

            <value>hibernateDevice</value>

        </property>

        <property name="sessionFactory" ref="sessionFactory" />

    </bean>

<bean id="compassGps" class="org.compass.gps.impl.SingleCompassGps"

        init-method="start" destroy-method="stop">

        <property name="compass" ref="compass" />

        <property name="gpsDevices">

            <list>

                <ref local="hibernateGpsDevice" />

            </list>

        </property>

    </bean>

最後にarticleDAOにCompassTemplateを注入します.私たちが検索するときにCompassTemplateを使いますから(CompassTemplateはトランザクションをサポートしています)
<property name="compassImplements">

            <ref local="compassImplements"/>

        </property>

これで構成OK
次にテストしてみましょう.
新規JUnitテストケース:
public class TestCompass extends TestCase

{

    private ClassPathXmlApplicationContext context = null;

    protectedvoid setUp() throws Exception

    {

        context = new ClassPathXmlApplicationContext("applicationContext.xml");

    }

    protected void tearDown() throws Exception

    {

    }

    public void insertTest()

    {

        ArticleDAO articleDao = (ArticleDAO) context.getBean("articleDAO");

        AuthorDAO authorDao = (AuthorDAO) context.getBean("authorDAO");

        Article article = new Article();

        Author author = new Author();

        author.setAge((short)21);

        author.setUsername("javafish");

        author.setPassword("java");

        article.setTitle("Compass    ");

        article.setPublishDate(new Date());

        article.setAuthor("javafish");

        authorDao.save(author);

        articleDao.save(article);

        

    }

    public void find()

    {

        ArticleDAO articleDao = (ArticleDAO) context.getBean("articleDAO");

        Article article = articleDao.find("  ");

        System.out.println(article.getPublishDate());

    }

}

InsertTest()にはCompassでHibernateとSpringのコードばかりが見えない.
articleやauthorのようなデータベースに書き込むと同時に、articleもインデックスに書き込まれます.
CompassとHibernate、Springを統合した威力を見たでしょう.
Luceneでテストしてもいいです.
publicvoid lucene() throws IOException, ParseException

    {

        IndexSearcher indexSearcher = new IndexSearcher("D:""workspace""CompassSpringHibernate""target""test""index""article");

        QueryParser queryParser = new QueryParser("titleIndex",new StandardAnalyzer());

        Query query = queryParser.parse("  ");

        Hits hits = indexSearcher.search(query);

        Document doc = null;

        for(int i=0;i<hits.length();i++)

        {

            doc=hits.doc(i);

            System.out.println(doc.get("titleIndex"));

            System.out.println(doc.get("publishDateIndex"));

        }

    }

結果検索に成功しました~~
私たちが検索すると、DAOクラスにCompassQueryの操作をカプセル化することができます.
その他具体的にはヘルプドキュメントを見てみましょう.^^;