在使用Hibernate的Lucene的时候,是通过事件监听器的方式来更新索引的。但是通常情况下,尤其是测试的时候,通过其他方式插入数据库,比如通过DbUnit。这个时候就需要同步的手动创建索引,我根据Hibernate Lucene的源代码,自己写了一个简单的程序。
原理很简单:先删除所有的索引,然后再添加。
我是对User这个实体进行索引的。
private static void remove(DocumentBuilder builder, Serializable id) { Term term = builder.getTerm( id ); try { IndexReader reader = IndexReader.open( builder.getFile() ); reader.delete( term ); reader.close(); } catch (IOException ioe) { ioe.printStackTrace(); } }
private static void add(final Object entity, final DocumentBuilder builder, final Serializable id) { Document doc = builder.getDocument( entity, id ); try { File file = builder.getFile(); IndexWriter writer = new IndexWriter( file, builder.getAnalyzer(), ! file.exists() ); writer.addDocument( doc ); writer.close(); } catch (IOException ioe) { ioe.printStackTrace(); } }
上面两个方法是直接拷贝了Hibernate Lucene 的LuceneEvent源代码中拷贝过来的。用来删除和添加索引。
protected static ApplicationContext ctx = null;
static { String[] path = { "applicationContext-hibernate.xml }; ctx = new FileSystemXmlApplicationContext(path); }
/** * @param args */ public static void main(String[] args) { UserManager userManager = null; userManager = (UserManager) ctx.getBean("userManager"); List<User> users = userManager.getAllUsers(); Analyzer analyzer = new CJKAnalyzer(); String indexDirName = "indexes"; File indexDir = indexDirName != null ? new File( indexDirName ) : new File( "." ); final DocumentBuilder documentBuilder = new DocumentBuilder( User.class, analyzer, indexDir ); for (int i = 0; i < users.size(); i++) { User user = (User) users.get(i); final Serializable id = user.getUsername(); remove( documentBuilder, id ); add( user, documentBuilder, id ); } }
由于我是用Spring来集成Hibernate的,首先从Spring中获取UserManager 这个Bean,获得所有的用户,然后构建DocumentBuilder 对每个User实体构建索引即可。 |