程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 詳解Java的Hibernate框架中的搜刮對象的應用

詳解Java的Hibernate框架中的搜刮對象的應用

編輯:關於JAVA

詳解Java的Hibernate框架中的搜刮對象的應用。本站提示廣大學習愛好者:(詳解Java的Hibernate框架中的搜刮對象的應用)文章只能為提供參考,不一定能成為您想要的結果。以下是詳解Java的Hibernate框架中的搜刮對象的應用正文


hibernate供給了全文索引功效,異常棒,這裡扼要引見下它的用法,
1. 在pom.xml引入包依附

<dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-search-orm</artifactId>
      <version>${hibernate-search.version}</version>
    </dependency>

    <dependency>
      <groupId>org.apache.lucene</groupId>
      <artifactId>lucene-analyzers-smartcn</artifactId>
      <version>${lucene.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.lucene</groupId>
      <artifactId>lucene-queryparser</artifactId>
      <version>${lucene.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.lucene</groupId>
      <artifactId>lucene-analyzers-phonetic</artifactId>
      <version>${lucene.version}</version>
    </dependency>

hibernate設置裝備擺設 search index保留途徑

 <bean id="sessionFactory"
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"
    destroy-method="destroy">
    <property name="dataSource" ref="poolingDataSource" />
    <property name="configLocation">
      <value> classpath:hibernate.cfg.xml </value>
    </property>
    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">${hibernate.dialect}</prop>
        <!-- Booleans can be easily used in expressions by 
           declaring HQL query substitutions in Hibernate configuration -->
        <prop key="hibernate.query.substitutions">true 'Y', false 'N'</prop>
        <!-- http://ehcache.org/documentation/integrations/hibernate -->
        <!-- http://www.tutorialspoint.com/hibernate/hibernate_caching.htm -->
        <prop key="hibernate.cache.use_second_level_cache">true</prop>
        <!-- org.hibernate.cache.ehcache.EhCacheRegionFactory -->
        <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
        <!-- hibernate只會緩存應用load()辦法取得的單個耐久化對象,假如想緩存應用findall()、 list()、Iterator()、createCriteria()、createQuery()
                等辦法取得的數據成果集的話,就須要設置hibernate.cache.use_query_cache true -->
        <prop key="hibernate.cache.use_query_cache">true</prop>
        <prop key="net.sf.ehcache.configurationResourceName">ehcache-hibernate.xml</prop>
        <!-- Hibernate Search index directory -->
        ***<prop key="hibernate.search.default.indexBase">indexes/</prop>*** 
      </props>
    </property>
  </bean> 

對須要搜刮的類加上Indexed Annotation,然後對類中可以被搜刮的字段加上@Field Annotation,平日Enum字段不須要Analyzer停止詞法剖析,其他字段則須要,關於不須要Projection(前往部門字段)的情形下,不須要在index中存儲現實數據。可以經由過程AnalyzerDef來界說分歧的詞法剖析器和關於的特別詞過濾器

@Indexed
@AnalyzerDef(
    name="enTopicAnalyzer",
    charFilters={
      @CharFilterDef(factory=HTMLStripCharFilterFactory.class)
    },
    tokenizer=@TokenizerDef(factory=StandardTokenizerFactory.class),
    filters={
      @TokenFilterDef(factory=StandardFilterFactory.class),
      @TokenFilterDef(factory=StopFilterFactory.class),
      @TokenFilterDef(factory=PhoneticFilterFactory.class,
        params = {
          @Parameter(name="encoder", value="DoubleMetaphone")
        }),
      @TokenFilterDef(factory=SnowballPorterFilterFactory.class,
        params = {
          @Parameter(name="language", value="English")
        })
      }
  )
public class Topic {

  ......
  @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
  @Analyzer(definition = "enTopicAnalyzer")
  private String title;
  ......
  @Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
  @Analyzer(definition = "enTopicAnalyzer")
  private String content;
  ......  
  @Enumerated(EnumType.STRING)
  @Field(index=Index.YES, analyze=Analyze.NO, store=Store.NO, bridge=@FieldBridge(impl=EnumBridge.class))
  private TopicStatus status;
  ...
  }

經由過程代碼對已稀有據創立index

ApplicationContext context = new ClassPathXmlApplicationContext("spring-resources.xml");

    SessionFactory sessionFactory = (SessionFactory) context.getBean("sessionFactory");

    Session sess = sessionFactory.openSession();
    FullTextSession fullTextSession = Search.getFullTextSession(sess);
    try {
      fullTextSession.createIndexer().startAndWait();
    } catch (InterruptedException e) {
       LOG.error(e.getMessage(), e);
    } finally {
      fullTextSession.close();
    }
    ((AbstractApplicationContext)context).close();

創立查詢fulltextsession,依照query前提獲得成果

 FullTextSession fullTextSession = Search
        .getFullTextSession(getSession());

    QueryBuilder queryBuilder = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity(Show.class).get();
    org.apache.lucene.search.Query luceneQuery = null;

      luceneQuery = queryBuilder.keyword()// .wildcard()
          .onFields("title", "content").matching(query.getKeyword())
          // .matching("*" + query.getKeyword() + "*")
          .createQuery();

    FullTextQuery hibernateQuery = fullTextSession.createFullTextQuery(
        luceneQuery, Show.class);
    return hibernateQuery.list();

note:
1. 在一次測試進程中,修正了value object,添加了新的index,忘卻了rebuildIndex,成果unit test沒成績,生成情況就失足了。
2. 搜刮還不是很壯大,好比搜刮測,含有測試的成果能夠就搜刮不出來

中文詞法剖析

hibernate search底層應用Lucene,所以Lucene可使用的中文分詞,hibernate search都可以用來支撐中文詞法剖析,比擬經常使用的詞法剖析器包含paoding,IKAnalyzer,mmseg4j 等等。詳細可以參考分詞剖析 比來剖析。hibernate search默許的分詞器是org.apache.lucene.analysis.standard.StandardAnalyzer,中文按字分詞,明顯不相符我們的需求。
這裡引見一下若何在hibernate中設置裝備擺設中文分詞,選擇的是Lucene自帶的中文分詞–。應用可以經由過程3種方法,一種是在hibernate的設置裝備擺設文件設置詞法剖析辦法,別的一種是在每一個須要被搜刮的類中界說分詞辦法,最初一種是對單個字段設置裝備擺設。這裡引見下前2種的設置裝備擺設方法。
hibernate設置裝備擺設方法:

<property name="hibernate.search.analyzer"> org.apache.lucene.analysis.cn.smart.SmartChineseAnalyzer</property>

被搜刮類設置裝備擺設中文分詞:

@Indexed
@Analyzer(impl=SmartChineseAnalyzer.class)

同時須要在maven中引入相干包依附

<dependency>
      <groupId>org.apache.lucene</groupId>
      <artifactId>lucene-analyzers-smartcn</artifactId>
      <version>${lucene.version}</version>
    </dependency>

多前提查詢
hibernate search可以經由過程多組合前提來完成多前提查詢,這裡簡略引見一下多前提查詢的一個理論。
假如只是單個前提查詢,那末這個查詢便可以很簡略

luceneQuery = queryBuilder.keyword().onFields("title", "content").matching(query.getKeyword()).createQuery()

假如是多前提並查詢,那末就須要應用到Must Join,假如是多前提或查詢,就須要應用should Join,這裡舉個Must Join的例子

//must true
MustJunction term = queryBuilder.bool().must(queryBuilder.keyword()
          .onFields("title", "content")   .matching(query.getKeyword()).createQuery());
//must false
 term.must(queryBuilder.keyword()
              .onField("status")             .matching(query.getExcludeStatus()).createQuery()).not();

完全例子:

private FullTextQuery findByKeywordQuery(TopicQuery query) {
    FullTextSession fullTextSession = Search
        .getFullTextSession(getSession());


    QueryBuilder queryBuilder = fullTextSession.getSearchFactory()
        .buildQueryBuilder().forEntity(Topic.class).get();
    org.apache.lucene.search.Query luceneQuery = null;
    if (null == query.getStatus() && null == query.getUsername() && null == query.getExcludeStatus()) {
      luceneQuery = queryBuilder.keyword()// .wildcard()
          .onFields("title", "content").matching(query.getKeyword())
          // .matching("*" + query.getKeyword() + "*")
          .createQuery();
      if(LOG.isDebugEnabled()){
        LOG.debug("create clean keyword search query: " + luceneQuery.toString());
      }
    } else {
      MustJunction term = queryBuilder.bool().must(queryBuilder.keyword()
          .onFields("title", "content")   .matching(query.getKeyword()).createQuery());
      if(null != query.getStatus()){
        term.must(queryBuilder.keyword()
              // .wildcard()
              .onField("status")
              .matching(query.getStatus()).createQuery());
      }
      if(null != query.getExcludeStatus()){
        term.must(queryBuilder.keyword()
              .onField("status")
              .matching(query.getExcludeStatus()).createQuery()).not();
      }
      if(null != query.getUsername()){
        term.must(queryBuilder.keyword()
              // .wildcard()
              .onField("owner.username")
               .ignoreFieldBridge()
              .matching(query.getUsername()).createQuery());
      }
      luceneQuery =term.createQuery();
      if(LOG.isDebugEnabled()){
        LOG.debug("create complicated keyword search query: " + luceneQuery.toString());
      }
    }
    // BooleanQuery
    FullTextQuery hibernateQuery = fullTextSession.createFullTextQuery(
        luceneQuery, Topic.class);
    return hibernateQuery;
  }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved