Hibernate search使用示例(基础小结-注解方式)

(对于项目环境配置,一直没怎么看过。这次经历里从基础环境搭建到hibernate search示例的完成)

1.首先创建project,选择了web project。

2.导入hibernate search所需要的包,(根据官方指南导入必须包和部分需要的其他组件包)具体如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
--hibernate search导入包提示的必须包,具体是否必须未验证
antlr-2.7.7
avro-1.7.5
commons-compress-1.5
dom4j-1.6.1
hibernate-commons-annotations-4.0.4.Final
hibernate-core-4.3.1.Final
jackson-core-asl-1.9.12
jackson-mapper-asl-1.9.12
jandex-1.1.0.Final
javassist-3.18.1-GA
jboss-logging-3.1.3.GA
jboss-logging-annotations-1.2.0.Beta1
lucene-core-3.6.2
paranamer-2.3
slf4j-api-1.6.1
xml-apis-1.3.03
--jpa需要的包(不知道jms,jsr,jta是不是需要的)
hibernate-jpa-2.1-api-1.0.0.Final
jms-1.1
jsr250-api-1.0
jta-1.1
--hibernate search引擎,映射
hibernate-search-engine-4.5.0.Final
hibernate-search-orm-4.5.0.Final
--db2 jdbc和lincense
db2jcc
db2jcc_license_cu
--junit
junit-4.8.1

(2014.04.02 jms,jsr,jta是不需要的)

3.所有的库导入完成后,开始配置hibernate,此处选择XML来配置,在src目录下新建hibernate.cfg.xml文件

基本配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
xml  version="1.0" encoding="UTF-8"?>
DOCTYPE  hibernate-configuration PUBLIC
     "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
< hibernate-configuration >
     < session-factory >
         < property  name="show_sql">true property >
         < property  name="format_sql">true property >
         < property  name="hibernate.dialect">org.hibernate.dialect.DB2Dialect property >
         < property  name="hibernate.connection.driver_class">
         com.ibm.db2.jcc.DB2Driver
         property >
         < property  name="hibernate.connection.url">
         jdbc:db2://IP地址/数据库名 property >
         < property  name="hibernate.connection.username">USER property >
         < property  name="hibernate.connection.password">PASSWORD property >
         < property  name="hibernate.search.default.directory_provider">
         org.hibernate.search.store.impl.FSDirectoryProvider
         property >
         < property  name="hibernate.search.default.indexBase">
         d:\lucene\indexs
         property >
         < mapping  class="hst.first.template.entity.Book" />
     session-factory >
hibernate-configuration >

此处没使用官方教程中的directory_provider和indexBase配置,官方配置也能正常使用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
show_sql 显示查询语句
 
format_sql 格式化查询语句
 
dialect 数据库方言
 
connection.driver_class JDBC数据库驱动
 
connection.url JDBC数据库连接地址
 
connection.username 数据库连接用户名
 
connection.password 数据库连接密码
 
search.default.directory_provider 全文检索缓存方式
 
search.default.indexBase 缓存路径
 
mapping class = “” 数据库表映射

PS:hibernate.search.default.directory_provider指定Directory的代理,即把索引的文件保存在硬盘中(org.hibernate.search.store.impl.FSDirectoryProvider)还是内存里(org.hibernate.search.store.impl.RAMDirectoryProvider),保存在硬盘的话hibernate.search.default.indexBase属性指定索引保存的路径。

4.创建Book实体类,并增加相应的hibernate search所需注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package  hst.first.template.entity;
 
import  java.util.Date;
 
import  javax.persistence.Column;
import  javax.persistence.Entity;
import  javax.persistence.Id;
import  javax.persistence.Temporal;
import  javax.persistence.TemporalType;
 
import  org.hibernate.search.annotations.Analyze;
import  org.hibernate.search.annotations.DateBridge;
import  org.hibernate.search.annotations.DocumentId;
import  org.hibernate.search.annotations.Field;
import  org.hibernate.search.annotations.Index;
import  org.hibernate.search.annotations.Indexed;
import  org.hibernate.search.annotations.Resolution;
import  org.hibernate.search.annotations.Store;
 
 
@Entity
@Indexed
public  class  Book {
     
     private  String id;
     private  String title;
     private  String subtitle;
     private  String author;
     private  Date publicationDate;
     
     /** default constructor */
     public  Book() {
     }
     
     public  Book(String id, String title, String subtitle, String author,
             Date publicationDate) {
         this .id = id;
         this .title = title;
         this .subtitle = subtitle;
         this .author = author;
         this .publicationDate = publicationDate;
     }
     
     // Property accessors
 
     @Id
     @Column (name = "ID" , length = 100 )
     @DocumentId
     public  String getId() {
         return  this .id;
     }
 
     public  void  setId(String id) {
         this .id = id;
     }
 
     @Field (index=Index.YES, analyze=Analyze.YES, store=Store.NO)
     @Column (name = "TITLE" , length = 200 )
     public  String getTitle() {
         return  this .title;
     }
 
     public  void  setTitle(String title) {
         this .title = title;
     }
 
     @Field (index=Index.YES, analyze=Analyze.YES, store=Store.NO)
     @Column (name = "SUBTITLE" , length = 200 )
     public  String getSubtitle() {
         return  this .subtitle;
     }
 
     public  void  setSubtitle(String subtitle) {
         this .subtitle = subtitle;
     }
     
     @Field (index=Index.YES, analyze=Analyze.YES, store=Store.NO)
     @Column (name = "AUTHOR" , length = 200 )
     public  String getAuthor() {
         return  this .author;
     }
 
     public  void  setAuthor(String author) {
         this .author = author;
     }
     
     @Field (index=Index.YES, analyze=Analyze.NO, store=Store.NO)
     @DateBridge (resolution=Resolution.DAY)
     @Temporal (TemporalType.DATE)
     @Column (name = "PUBLICATION_DATE" , length = 10 )
     public  Date getPublicationDate() {
         return  this .publicationDate;
     }
     
     public  void  setPublicationDate(Date publicationDate) {
         this .publicationDate = publicationDate;
     }
}

需要增加的注解:

1
2
3
4
5
6
7
需要检索的实体类增加 @Indexed
 
主键增加 @Id
 
需要检索的字段增加 @Field 和相关属性(默认属性如本例)
 
对非文本格式字段检索时,需要进行转换 (转换注解方式如本例) 格式转换相关内容详见: http: //docs .jboss.org /hibernate/search/4 .5 /reference/en-US/html_single/ #search-mapping-bridge

PS:本例测试中(ejb3 自动生成)默认实体注解 @Table 存在时,junit测试异常。去掉@Table之后可以正常使用

5.增加junit测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package hst.first.template.action;
 
 
import  hst.first.template.entity.Book;
 
import  java.text.SimpleDateFormat;
import  java.util.Calendar;
import  java.util.Date;
import  java.util.List;
 
import  org.hibernate.Query;
import  org.hibernate.Session;
import  org.hibernate.SessionFactory;
import  org.hibernate.Transaction;
import  org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import  org.hibernate.cfg.Configuration;
import  org.hibernate.search.FullTextSession;
import  org.hibernate.search.Search;
import  org.hibernate.search.SearchFactory;
import  org.hibernate.search.query.dsl.QueryBuilder;
import  org.hibernate.service.ServiceRegistry;
import  org.junit.After;
import  org.junit.AfterClass;
import  org.junit.Before;
import  org.junit.BeforeClass;
import  org.junit.Test;
 
public class HibernateSearchTest {
     
     private static SessionFactory sf = null;
     private static Session session = null;
     private static Transaction tx = null;
     @BeforeClass
     public static void setupBeforeClass()  throws Exception{
         StandardServiceRegistryBuilder serviceRegistryBuilder = new StandardServiceRegistryBuilder();
         Configuration cf = new Configuration();
         cf.configure( "hibernate.cfg.xml" );
         ServiceRegistry serviceRegistry = serviceRegistryBuilder.applySettings(cf.getProperties()).build();
         sf = cf.buildSessionFactory(serviceRegistry);
         assertNotNull(sf);
     }
     
     @Before
     public void setup() throws Exception {
         session = sf.openSession();
         tx = session.beginTransaction();
     }
     
     @After
     public void tearDown() throws Exception {
         tx.commit();
         session.close();
     }
     
     @AfterClass
     public static void tearDownAfterClass() throws Exception {
         if (sf !=null){
             sf.close();
         }
     }
     private static void assertNotNull(Object obj) throws Exception{
         if (obj == null){
             throw new NullPointerException();
         }
     }
     
     // @Test
     public void testAdd() throws Exception{
         Book book = new Book();
         book.setAuthor( "村上春树" );
         book.setSubtitle( "异恋" );
         book.setTitle( "死不过十天半月" );
         book.setId( "7" );
         Calendar timeMaker = Calendar.getInstance();
         timeMaker. set (2005, 06, 31);
         book.setPublicationDate(timeMaker.getTime());
         session.save(book);
     }
     
     @Test
     public void testFullTextSession() throws Exception{
         System.out.println(session==null);
         FullTextSession fullTextSession = Search.getFullTextSession(session);
         fullTextSession.createIndexer().startAndWait();
         SearchFactory sf = fullTextSession.getSearchFactory();
         QueryBuilder qb = sf.buildQueryBuilder().forEntity(Book.class).get();
         org.apache.lucene.search.Query luceneQuery  = qb.keyword().onFields( "author" , "title" , "subtitle" ).matching( "银河" ).createQuery();
//       QueryParser parser = new QueryParser(Version.LUCENE_36, "author" , new StopAnalyzer(Version.LUCENE_36));
//       org.apache.lucene.search.Query luceneQuery = parser
//       .parse( "author:亦舒" );
         Query hibQuery = fullTextSession.createFullTextQuery(luceneQuery);
         List list = hibQuery.list();
         assertNotNull(list);
         for (Object obj:list){
             Book book = (Book)obj;
             System.out.println( "书名:" +book.getSubtitle()+ "\n 副标题:" +book.getTitle()+ "\n 作者:" +book.getAuthor());
         }
     }
     
}

5.1在hibernate 4.0中sessionFactory获取方式发生了一些改变,如本例@BeforeClass中所写

5.2在Test中写有增加数据进库的测试。只是为了测试数据库连接情况

5.3在testFullTextSession()的测试中,测试了hibernate search的基础查询。fullTextSession.createIndexer().startAndWait(); 会在hibernate配置的路径中生成全文索引需要的文件。

5.4在测试中方法中注释掉的 StopAnalyzer()部分是关于解析器的,具体未解。解析器可以自定义。解析器的使用需要参考官方说明文档。

PS:在fullTextSession.createIndexer().startAndWait(); 时会自动进行重新从数据库中获取所有数据重建索引数据。如果直接使用fullTextSession.getSearchFactory(); 不执行上一句,则直接从已存在的索引数据中查询数据。根据不同测试输出内容可以看出:

1
2
3
不执行重建索引时,会先从全文索引数据中查询信息,获取对应主键信息,并通过这个主键获取数据库信息。
 
当获取到多个符合条件的数据,采用 in ( '' , '' )的方式查询数据,如果是单条数据则采用 =  查询。

你可能感兴趣的:(Hibernet)