下面講一下高級部分Compass與Hibernate,Spring的集成。Compass內部有對Hibernate,Spring的支持,如果配置好了,可以在建立和更新索引的時候不用Compass寫一句代碼。爽吧!~不過集成它們比較麻煩那就看我一步一步的來吧:
1.首先把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;
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
說明一下開發環境:eclipse3.2+myeclipse5.0+springtide+middlegen(注意要在工程上加入MyEcilpse的Hibernate和Spring能力。
然後用Hibernate進行裝配,Hibernate有三個配置文件:hibernate.cfg.xml, Article.hbm.xml,Author.hbm.xml
具體的結構請看Hibernate.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集成起來。
在applicationContext.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>
然後回到applicationContext.xml裏:
看看怎麼集成的,在Compass中有個org.compass.gps.impl.SingleCompassGps是對Compass進行實時更新的,而org.compass.spring.device.hibernate.SpringHibernate3GpsDevice
它是和Hibernate集成並且對Hibernate的insert,delete,update進行自動的更新,所以說這樣就不
我們爲Compass寫一句代碼了。不過這兩個類對Compass和Hibernate的實時功能也可以用Spring的AOP來實現(這裏也不討論了)。剩下的就是用Spring的IoC來支Compass的初始化功能進行注入,第一個是:
- <bean id="compassConfiguration"
- class="org.compass.core.config.CompassConfiguration" />
第二個是:
- <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>
還有關鍵的兩個類的注入:
- <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());
- }
- }
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"));
- }
- }
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的操作。
其它具體還是看幫助文檔吧。^_^