下面讲一下高级部分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;
建立一个工程叫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());
}
}
看到没有在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的操作。
其它具体还是看帮助文档吧。^_^