您的位置:首页 > 其它

lucene5--增量索引(Zoie)(近实时搜索的实现)

2017-08-28 15:35 495 查看
Zoie的增量索引原理吧,摘自Zoie的官方Wiki:利用两个内存索引一个硬盘索引实现实时搜索的原理(1) 当系统启动的时候,索引处在Sleeping状态,这时Mem结构中,只有索引A,索引B为null,索引A为_currentWritable,_currentReadOnly为null,_diskIndexReader为硬盘索引的IndexReader。由于内存中索引的IndexReader是每添加完文档后立刻更新的,而且速度很快,而硬盘上的索引一旦打开,在下次合并之前,一直使用,可以保证新添加的文档能够马上被搜索到。



 (2) 当A中的文档数量达到一定的数量的时候,需要同硬盘上的索引进行合并,因此要进入Working状态。合并是一个相对比较长的过程,这时候会创建内存索引B,在合并过程中新添加的文档全部索引到B中。此时的Mem结构中,有内存索引A,内存索引B,索引A为currentReadOnly,索引B为currentWritable,diskIndexReader为硬盘索引的IndexReader。此时要获得ZoieSystem的IndexReader,则三个IndexReader全都返回,由于索引B的IndexReader是添加文档后立刻更新的,因而能够保证新添加的文档能够马上被搜索到,这个时候虽然索引A已经在同硬盘索引进行合并,然而由于硬盘索引的IndexReader还没有重新打开,因而索引A中的数据不会被重复搜到。



 (3) 当索引A中的数据已经完全合并到硬盘上之后,则要重新打开硬盘索引的IndexReader,打开完毕后,创建一个新的Mem结构,原来的索引B作为索引A,为currentWritable,原来的索引A被抛弃,设为null,currentReadOnly也设为null,diskIndexReader为新打开的硬盘索引的IndexReader。然后通过无缝切换用新的Mem结构替代旧的Mem结构,然后索引进入Sleeping状态。


上面的文字说的不够通俗易懂,我用更直白的话再解释一下:Zoie的增量索引原理是这样的,首先你可能会有一个定时器去不断检索是否有新增数据,发现了新数据,那首先会把新增的数据索引到内存目录A(RAMDirectory-A)中,当总不能一直让内存目录A中写索引啊,毕竟你占用的是内存,所以为内存目录A设定一个阀值,超过这个限定阀值就触发内存目录A中索引flush到硬盘索引目录C中,当内存目录A中索引还没有完全写入到硬盘索引目录C中且硬盘索引目录C的IndexReader还没有重新open的话,你通过IndexSearcher是查询不到的,这时就设计了一个内存索引目录B,即在内存索引目录A在往硬盘索引目录C中写索引的同时,也往内存索引目录B中写做个备份,这时使用Lucene中的MultiReader把B和C作为一个索引目录进行查询,之所以不包括A是因为A还没写完,前面博客我已经将过了Lucene的多目录搜索,你应该懂的,所以你新增数据之所以能几乎近实时的被你搜索到,是因为写入到了一个备份的索引目录B中,然后联合硬盘索引目录C(因为硬盘索引目录C在内存索引目录A里的索引合并到C过程还没完成之前,新增的索引在C中是搜索不到),当A和C的合并过程完成后,硬盘索引目录C的IndexReasder重新打开,保证新增的索引能被IndexSearcher搜索到,同时把B作为A,废弃A,再进入下一个循环.......
     核心就是利用两个内存目录,一个内存目录用来联合硬盘索引目录进行多目录查询,另一个目录只管进行索引合并到硬盘索引目录操作即可。     放假花了2天使用Zoie写了一个增量索引的Demo,示例程序就是模拟数据库表数据动态插入新数据后,能立马被准实时被索引到,且被搜索到。下面就直接上代码了:    Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import java.io.File;  
import java.util.ArrayList;  
import java.util.List;  
  
import org.ansj.lucene5.AnsjAnalyzer;  
import org.apache.lucene.analysis.Analyzer;  
import org.apache.lucene.search.similarities.DefaultSimilarity;  
  
import proj.zoie.api.DataConsumer.DataEvent;  
import proj.zoie.api.ZoieException;  
import proj.zoie.api.indexing.ZoieIndexableInterpreter;  
import proj.zoie.impl.indexing.DefaultIndexReaderDecorator;  
import proj.zoie.impl.indexing.ZoieConfig;  
import proj.zoie.impl.indexing.ZoieSystem;  
  
/** 
 * Zoie增量索引测试 
 * @author Lanxiaowei 
 * 
 */  
@SuppressWarnings({"unchecked","rawtypes"})  
public class ZoieIndex {  
      
    /**最大增量索引数量*/  
    public static final long MAX_INCREMENT_INDEX_NUMBER = Long.MAX_VALUE;  
    /**索引目录*/  
    public String userIndexPath;  
      
    public ZoieSystem zoieSystem;  
      
    /**队列中放入多少项才触发索引*/  
    private  int zoieBatchSize;  
      
    /**等待多长时间才触发索引*/  
    private int zoieBatchDelay;  
      
    /**分词器*/  
    private Analyzer analyzer;  
      
    private PersonDao personDao;  
      
    public ZoieIndex(String userIndexPath, Analyzer analyzer,  
            PersonDao personDao) {  
        super();  
        this.userIndexPath = userIndexPath;  
        this.analyzer = analyzer;  
        this.personDao = personDao;  
    }  
  
    public ZoieIndex(String userIndexPath, Analyzer analyzer,  
            PersonDao personDao, int zoieBatchSize, int zoieBatchDelay) {  
        super();  
        this.userIndexPath = userIndexPath;  
        this.analyzer = analyzer;  
        this.personDao = personDao;  
        this.zoieBatchSize = zoieBatchSize;  
        this.zoieBatchDelay = zoieBatchDelay;  
    }  
  
  
  
    public void init() throws ZoieException {  
        //如果索引目录不存在则新建  
        File idxDir = new File(userIndexPath);  
        if(!idxDir.exists()){  
            idxDir.mkdir();  
        }  
          
        //分词器设置为ansj-seg分词器  
        analyzer = new AnsjAnalyzer();  
          
        //数据转换器[JavaBea-->Document]  
        ZoieIndexableInterpreter interpreter = new CustomPersonZoieIndexableInterpreter(analyzer);  
        //Lucene的IndexReader装饰者,包装成zoie的IndexReader  
        DefaultIndexReaderDecorator readerDecorator = new DefaultIndexReaderDecorator();  
          
        //Zoie初始化相关配置  
        ZoieConfig zoieConfig = new ZoieConfig();  
        zoieConfig.setBatchDelay(zoieBatchDelay);  
        zoieConfig.setBatchSize(zoieBatchSize);  
        //设置分词器  
        zoieConfig.setAnalyzer(analyzer);  
        //设置相似性评分器  
        zoieConfig.setSimilarity(new DefaultSimilarity());  
        // 开启NRT索引  
        zoieConfig.setRtIndexing(true);  
        zoieSystem = new ZoieSystem(idxDir, interpreter, readerDecorator, zoieConfig);  
        zoieSystem.start();  
        zoieSystem.getAdminMBean().flushToDiskIndex();  
    }  
      
    /** 
     * 更新索引数据 
     * @throws ZoieException  
     */  
    public void updateIndexData() throws ZoieException {  
        //先从数据库查出新增加的数据  
        List<Person> persons = personDao.findPersonBefore3S();  
        if(persons == null || persons.size() == 0) {  
            System.out.println("No increment data right now.please wait a while.");  
            return;  
        }  
        List<DataEvent<Person>> dataEventList = new ArrayList<DataEvent<Person>>();  
        for(Person person : persons) {  
            dataEventList.add(new DataEvent<Person>(person, "1.0", person.isDeleteFlag()));  
        }  
        //消费数据  
        zoieSystem.consume(dataEventList);  
    }  
      
    public void destroy(){  
        // 将内存索引刷新到磁盘索引中  
        zoieSystem.shutdown();   
        System.out.println(".........将内存索引刷新到磁盘索引中.........");  
    }  
  
    public String getUserIndexPath() {  
        return userIndexPath;  
    }  
  
    public void setUserIndexPath(String userIndexPath) {  
        this.userIndexPath = userIndexPath;  
    }  
  
    public int getZoieBatchSize() {  
        return zoieBatchSize;  
    }  
  
    public void setZoieBatchSize(int zoieBatchSize) {  
        this.zoieBatchSize = zoieBatchSize;  
    }  
  
    public int getZoieBatchDelay() {  
        return zoieBatchDelay;  
    }  
  
    public void setZoieBatchDelay(int zoieBatchDelay) {  
        this.zoieBatchDelay = zoieBatchDelay;  
    }  
  
    public Analyzer getAnalyzer() {  
        return analyzer;  
    }  
  
    public void setAnalyzer(Analyzer analyzer) {  
        this.analyzer = analyzer;  
    }  
  
    public PersonDao getPersonDao() {  
        return personDao;  
    }  
  
    public void setPersonDao(PersonDao personDao) {  
        this.personDao = personDao;  
    }  
}  
    Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import java.util.TimerTask;  
  
import proj.zoie.api.ZoieException;  
  
/** 
 * Zoie定时增量索引任务 
 * @author LANXIAOWEI 
 * 
 */  
public class ZoieIndexTimerTask extends TimerTask {  
    private ZoieIndex zoieIndex;  
      
    @Override  
    public void run() {  
        try {  
            zoieIndex.init();  
            zoieIndex.updateIndexData();  
        } catch (ZoieException e) {  
            e.printStackTrace();  
        }  
    }  
  
    public ZoieIndexTimerTask(ZoieIndex zoieIndex) {  
        super();  
        this.zoieIndex = zoieIndex;  
    }  
  
    public ZoieIndex getZoieIndex() {  
        return zoieIndex;  
    }  
  
    public void setZoieIndex(ZoieIndex zoieIndex) {  
        this.zoieIndex = zoieIndex;  
    }  
}  
   Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import java.io.IOException;  
import java.nio.file.Paths;  
import java.util.ArrayList;  
import java.util.List;  
  
import org.apache.lucene.document.Document;  
import org.apache.lucene.index.DirectoryReader;  
import org.apache.lucene.index.IndexReader;  
import org.apache.lucene.index.Term;  
import org.apache.lucene.search.IndexSearcher;  
import org.apache.lucene.search.Query;  
import org.apache.lucene.search.ScoreDoc;  
import org.apache.lucene.search.TermQuery;  
import org.apache.lucene.search.TopDocs;  
import org.apache.lucene.search.WildcardQuery;  
import org.apache.lucene.store.FSDirectory;  
  
/** 
 * Zoie查询测试 
 *  
 * @author Lanxiaowei 
 *  
 */  
public class ZoieSearchTest {  
    public static void main(String[] args) throws IOException {  
        // 参数定义  
        String directoryPath = "C:/zoieindex";  
        String fieldName = "nativePlace";  
        String queryString = "*香港*";  
  
        Query query = new WildcardQuery(new Term(fieldName,queryString));  
        List<Document> list = query(directoryPath,query);  
        if (list == null || list.size() == 0) {  
            System.out.println("No results found.");  
            return;  
        }  
        for (Document doc : list) {  
            String personName = doc.get("personName");  
            String nativePlace = doc.get("nativePlace");  
            String hobby = doc.get("hobby");  
            System.out.println("personName:" + personName);  
            System.out.println("nativePlace:" + nativePlace);  
            System.out.println("hobby:" + hobby);  
        }  
    }  
      
    /** 
     * 创建索引阅读器 
     * @param directoryPath  索引目录 
     * @return 
     * @throws IOException   可能会抛出IO异常 
     */  
    public static IndexReader createIndexReader(String directoryPath) throws IOException {  
        return DirectoryReader.open(FSDirectory.open(Paths.get(directoryPath, new String[0])));  
    }  
      
    /** 
     * 创建索引查询器 
     * @param directoryPath   索引目录 
     * @return 
     * @throws IOException 
     */  
    public static IndexSearcher createIndexSearcher(String directoryPath) throws IOException {  
        return new IndexSearcher(createIndexReader(directoryPath));  
    }  
      
    /** 
     * 创建索引查询器 
     * @param reader 
     * @return 
     */  
    public static IndexSearcher createIndexSearcher(IndexReader reader) {  
        return new IndexSearcher(reader);  
    }  
      
    public static List<Document> query(String directoryPath,Query query) throws IOException {  
        IndexSearcher searcher = createIndexSearcher(directoryPath);  
        TopDocs topDocs = searcher.search(query, Integer.MAX_VALUE);  
        List<Document> docList = new ArrayList<Document>();  
        ScoreDoc[] docs = topDocs.scoreDocs;  
        for (ScoreDoc scoreDoc : docs) {  
            int docID = scoreDoc.doc;  
            Document document = searcher.doc(docID);  
            docList.add(document);  
        }  
        searcher.getIndexReader().close();  
        return docList;  
    }  
}  
   Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import java.util.Timer;  
  
import org.ansj.lucene5.AnsjAnalyzer;  
import org.apache.lucene.analysis.Analyzer;  
/** 
 * 增量索引测试 
 * @author Lanxiaowei 
 * 
 */  
public class ZoieTest {  
    public static void main(String[] args) throws Exception {  
          
        String userIndexPath = "C:/zoieindex";  
        Analyzer analyzer = new AnsjAnalyzer();  
        PersonDao personDao = new PersonDaoImpl();  
        int zoieBatchSize = 10;  
        int zoieBatchDelay = 1000;  
          
        //先读取数据库表中已有数据创建索引  
        CreateIndexTest createIndexTest = new CreateIndexTest(personDao, userIndexPath);  
        createIndexTest.index();  
          
        //再往数据库表中插入一条数据,模拟数据动态变化  
        PersonDaoTest.addPerson();  
          
          
        ZoieIndex zoindex = new ZoieIndex(userIndexPath, analyzer, personDao,   
            zoieBatchSize, zoieBatchDelay);  
        Timer timer = new Timer("myTimer",false);  
        timer.scheduleAtFixedRate(new ZoieIndexTimerTask(zoindex),10L,3000L);  
          
        //睡眠2分钟  
        Thread.sleep(2*60*1000L);  
        //2分钟后定时器取消  
        timer.cancel();  
        System.out.println("Timer cancled.");  
          
        /**把索引flush到硬盘*/  
        zoindex.destroy();  
        System.out.println("finished.");  
    }  
}  
   Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import java.io.IOException;  
import java.nio.file.Paths;  
import java.util.List;  
  
import org.ansj.lucene5.AnsjAnalyzer;  
import org.apache.lucene.analysis.Analyzer;  
import org.apache.lucene.document.Document;  
import org.apache.lucene.document.Field;  
import org.apache.lucene.document.IntField;  
import org.apache.lucene.document.LongField;  
import org.apache.lucene.document.NumericDocValuesField;  
import org.apache.lucene.document.StringField;  
import org.apache.lucene.document.TextField;  
import org.apache.lucene.index.IndexWriter;  
import org.apache.lucene.index.IndexWriterConfig;  
import org.apache.lucene.index.IndexWriterConfig.OpenMode;  
import org.apache.lucene.store.Directory;  
import org.apache.lucene.store.FSDirectory;  
  
import com.yida.framework.lucene5.util.LuceneUtils;  
  
/** 
 * 读取数据库表中数据创建索引 
 * @author Lanxiaowei 
 * 
 */  
public class CreateIndexTest {  
    private PersonDao personDao;  
    /**索引目录*/  
    private String indexDir;  
      
    public static void main(String[] args) throws IOException {  
        String userIndexPath = "C:/zoieindex";  
        PersonDao personDao = new PersonDaoImpl();  
        //先读取数据库表中已有数据创建索引  
        CreateIndexTest createIndexTest = new CreateIndexTest(personDao, userIndexPath);  
        createIndexTest.index();  
    }  
      
    public CreateIndexTest(PersonDao personDao, String indexDir) {  
        super();  
        this.personDao = personDao;  
        this.indexDir = indexDir;  
    }  
  
    public void index() throws IOException {  
        List<Person> persons = personDao.findAll();  
        if(null == persons || persons.size() == 0) {  
            return;  
        }  
        Directory dir = FSDirectory.open(Paths.get(indexDir));  
        Analyzer analyzer = new AnsjAnalyzer();  
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);  
        indexWriterConfig.setOpenMode(OpenMode.CREATE_OR_APPEND);  
        IndexWriter writer = new IndexWriter(dir, indexWriterConfig);  
        for(Person person : persons) {  
            Document document = new Document();  
            document.add(new Field("id",person.getId().toString(),Field.Store.YES,  
                Field.Index.NOT_ANALYZED,Field.TermVector.NO));  
            document.add(new StringField("personName", person.getPersonName(), Field.Store.YES));  
            document.add(new StringField("sex", person.getSex(), Field.Store.YES));  
            document.add(new LongField("birth", person.getBirth().getTime(), Field.Store.YES));  
            document.add(new TextField("nativePlace", person.getNativePlace(), Field.Store.YES));  
            document.add(new StringField("job", person.getJob(), Field.Store.YES));  
            document.add(new IntField("salary", person.getSalary(), Field.Store.YES));  
            document.add(new StringField("hobby", person.getHobby(), Field.Store.YES));  
            document.add(new StringField("deleteFlag", person.isDeleteFlag() + "", Field.Store.YES));  
            //Zoie需要的UID[注意:这个域必须加,且必须是NumericDocValuesField类型,至于UID的域值是什么没关系,只要保证它是唯一的即可]  
            document.add(new NumericDocValuesField("_ID", person.getId()));  
            LuceneUtils.addIndex(writer, document);  
        }  
        writer.close();  
        dir.close();  
    }  
}  
   Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import javax.sql.DataSource;  
  
import org.apache.commons.dbcp.BasicDataSource;  
import org.apache.commons.dbutils.QueryRunner;  
  
public class DBHelper {  
    private static DataSource dataSource;  
      
    public static QueryRunner getQueryRunner(){  
        if(DBHelper.dataSource == null){  
            BasicDataSource dbcpDataSource = new BasicDataSource();  
            dbcpDataSource.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8");  
            dbcpDataSource.setDriverClassName("com.mysql.jdbc.Driver");  
            dbcpDataSource.setUsername("root");  
            dbcpDataSource.setPassword("123");  
            dbcpDataSource.setDefaultAutoCommit(true);  
            dbcpDataSource.setMaxActive(100);  
            dbcpDataSource.setMaxIdle(30);  
            dbcpDataSource.setMaxWait(500);  
            DBHelper.dataSource = (DataSource)dbcpDataSource;  
        }  
        return new QueryRunner(DBHelper.dataSource);  
    }  
}  
    Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import org.apache.lucene.analysis.Analyzer;  
  
import proj.zoie.api.indexing.AbstractZoieIndexableInterpreter;  
import proj.zoie.api.indexing.ZoieIndexable;  
  
/** 
 * 自定义Person-->Document的数据转换器的生产者 
 * @author Lanxiaowei 
 * 
 */  
public class CustomPersonZoieIndexableInterpreter extends AbstractZoieIndexableInterpreter<Person>{  
    private Analyzer analyzer;  
      
    @Override  
    public ZoieIndexable convertAndInterpret(Person person) {  
        return new PersonZoieIndexable(person, analyzer);  
    }  
      
    public CustomPersonZoieIndexableInterpreter() {}  
      
    public CustomPersonZoieIndexableInterpreter(Analyzer analyzer) {  
        super();  
        this.analyzer = analyzer;  
    }  
  
    public Analyzer getAnalyzer() {  
        return analyzer;  
    }  
    public void setAnalyzer(Analyzer analyzer) {  
        this.analyzer = analyzer;  
    }  
}  
   Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import org.apache.lucene.analysis.Analyzer;  
import org.apache.lucene.document.Document;  
import org.apache.lucene.document.Field;  
import org.apache.lucene.document.IntField;  
import org.apache.lucene.document.LongField;  
import org.apache.lucene.document.StringField;  
import org.apache.lucene.document.TextField;  
  
import proj.zoie.api.indexing.AbstractZoieIndexable;  
/** 
 * JavaBean与Document的转换器 
 * @author Lanxiaowei 
 * 
 */  
public class PersonZoieIndexable extends AbstractZoieIndexable {  
    private Person person;  
    private Analyzer analyzer;  
  
    public PersonZoieIndexable(Person person) {  
        super();  
        this.person = person;  
    }  
  
    public PersonZoieIndexable(Person person, Analyzer analyzer) {  
        super();  
        this.person = person;  
        this.analyzer = analyzer;  
    }  
  
    public Document buildDocument() {  
        System.out.println("Person --> Document begining.");  
        Document document = new Document();  
        document.add(new Field("id",person.getId().toString(),Field.Store.YES,  
            Field.Index.NOT_ANALYZED,Field.TermVector.NO));  
        document.add(new StringField("personName", person.getPersonName(), Field.Store.YES));  
        document.add(new StringField("sex", person.getSex(), Field.Store.YES));  
        document.add(new LongField("birth", person.getBirth().getTime(), Field.Store.YES));  
        document.add(new TextField("nativePlace", person.getNativePlace(), Field.Store.YES));  
        document.add(new StringField("job", person.getJob(), Field.Store.YES));  
        document.add(new IntField("salary", person.getSalary(), Field.Store.YES));  
        document.add(new StringField("hobby", person.getHobby(), Field.Store.YES));  
        document.add(new StringField("deleteFlag", person.isDeleteFlag() + "", Field.Store.YES));  
        return document;  
    }  
  
    @Override  
    public IndexingReq[] buildIndexingReqs() {  
        return new IndexingReq[] {new IndexingReq(buildDocument(), analyzer)};  
    }  
  
    @Override  
    public long getUID() {  
        return person.getId();  
    }  
  
    @Override  
    public boolean isDeleted() {  
        return person.isDeleteFlag();  
    }  
      
    public Analyzer getAnalyzer() {  
        return analyzer;  
    }  
  
    public void setAnalyzer(Analyzer analyzer) {  
        this.analyzer = analyzer;  
    }  
}  
   Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import java.util.Date;  
  
public class Person {  
    private Long id;  
    private String personName;  
    /**性别:1(男)/0(女)*/  
    private String sex;  
    private Date birth;  
    /**籍贯*/  
    private String nativePlace;  
    private String job;  
    private Integer salary;  
    /**兴趣爱好*/  
    private String hobby;  
      
    /**删除标记: true已删除/false未删除*/  
    private boolean deleteFlag;  
    /**最后一次更新时间*/  
    private Date updatedTime;  
      
    public Person() {}  
      
      
      
    public Person(String personName, String sex, Date birth,  
            String nativePlace, String job, Integer salary, String hobby) {  
        super();  
        this.personName = personName;  
        this.sex = sex;  
        this.birth = birth;  
        this.nativePlace = nativePlace;  
        this.job = job;  
        this.salary = salary;  
        this.hobby = hobby;  
    }  
      
    public Person(String personName, String sex, Date birth,  
            String nativePlace, String job, Integer salary, String hobby,boolean deleteFlag) {  
        super();  
        this.personName = personName;  
        this.sex = sex;  
        this.birth = birth;  
        this.nativePlace = nativePlace;  
        this.job = job;  
        this.salary = salary;  
        this.hobby = hobby;  
        this.deleteFlag = deleteFlag;  
    }  
  
    public Person(String personName, String sex, Date birth,  
            String nativePlace, String job, Integer salary, String hobby,  
            boolean deleteFlag, Date updatedTime) {  
        super();  
        this.personName = personName;  
        this.sex = sex;  
        this.birth = birth;  
        this.nativePlace = nativePlace;  
        this.job = job;  
        this.salary = salary;  
        this.hobby = hobby;  
        this.deleteFlag = deleteFlag;  
        this.updatedTime = updatedTime;  
    }  
  
    public Long getId() {  
        return id;  
    }  
    public void setId(Long id) {  
        this.id = id;  
    }  
    public String getPersonName() {  
        return personName;  
    }  
    public void setPersonName(String personName) {  
        this.personName = personName;  
    }  
    public String getSex() {  
        return sex;  
    }  
    public void setSex(String sex) {  
        this.sex = sex;  
    }  
    public Date getBirth() {  
        return birth;  
    }  
    public void setBirth(Date birth) {  
        this.birth = birth;  
    }  
    public String getNativePlace() {  
        return nativePlace;  
    }  
    public void setNativePlace(String nativePlace) {  
        this.nativePlace = nativePlace;  
    }  
    public String getJob() {  
        return job;  
    }  
    public void setJob(String job) {  
        this.job = job;  
    }  
    public Integer getSalary() {  
        return salary;  
    }  
    public void setSalary(Integer salary) {  
        this.salary = salary;  
    }  
    public String getHobby() {  
        return hobby;  
    }  
    public void setHobby(String hobby) {  
        this.hobby = hobby;  
    }  
  
    public boolean isDeleteFlag() {  
        return deleteFlag;  
    }  
  
    public void setDeleteFlag(boolean deleteFlag) {  
        this.deleteFlag = deleteFlag;  
    }  
  
    public Date getUpdatedTime() {  
        return updatedTime;  
    }  
  
    public void setUpdatedTime(Date updatedTime) {  
        this.updatedTime = updatedTime;  
    }  
  
  
  
    @Override  
    public int hashCode() {  
        final int prime = 31;  
        int result = 1;  
        result = prime * result + ((id == null) ? 0 : id.hashCode());  
        return result;  
    }  
  
    @Override  
    public boolean equals(Object obj) {  
        if (this == obj)  
            return true;  
        if (obj == null)  
            return false;  
        if (getClass() != obj.getClass())  
            return false;  
        Person other = (Person) obj;  
        if (id == null) {  
            if (other.id != null)  
                return false;  
        } else if (!id.equals(other.id))  
            return false;  
        return true;  
    }  
}  
   Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import java.util.List;  
  
public interface PersonDao {  
    /** 
     * 新增 
     * @return 
     */  
    public boolean save(Person person);  
      
    /** 
     * 更新 
     * @param person 
     * @return 
     */  
    public boolean update(Person person);  
      
    /** 
     * 根据ID删除 
     * @param id 
     * @return 
     */  
    public boolean delete(Long id);  
      
    /** 
     * 根据ID查询 
     * @param id 
     * @return 
     */  
    public Person findById(Long id);  
      
    /** 
     * 查询所有 
     * @return 
     */  
    public List<Person> findAll();  
      
    /** 
     * 查询3秒之前的数据,用于测试 
     * @return 
     */  
    public List<Person> findPersonBefore3S();  
}  
   Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import java.sql.SQLException;  
import java.util.Date;  
import java.util.List;  
  
import org.apache.commons.dbutils.QueryRunner;  
import org.apache.commons.dbutils.handlers.BeanHandler;  
import org.apache.commons.dbutils.handlers.BeanListHandler;  
  
public class PersonDaoImpl implements PersonDao {  
    private QueryRunner queryRunner = DBHelper.getQueryRunner();  
    /** 
     * 新增 
     * @return 
     */  
    public boolean save(Person person) {  
        int result = 0;  
        try {  
            result = queryRunner.update("insert into person(personName,sex,birth,nativePlace,job,salary,hobby,deleteFlag,updatedTime) " +   
                    "values(?,?,?,?,?,?,?,?,?)" , new Object[] {  
                    person.getPersonName(),  
                    person.getSex(),  
                    person.getBirth(),  
                    person.getNativePlace(),  
                    person.getJob(),  
                    person.getSalary(),  
                    person.getHobby(),  
                    person.isDeleteFlag(),  
                    new Date()  
            });  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        return result == 1;  
    }  
      
    /** 
     * 根据ID更新 
     * @param person 
     * @return 
     */  
    public boolean update(Person person) {  
        int result = 0;  
        try {  
            result = queryRunner.update(  
                    "update person set personName = ?, sex = ?, birth = ?, " +   
                    "nativePlace = ?, job = ?, salary = ?, hobby = ?,deleteFlag = ?, " +  
                    "updatedTime = ? where id = ?"   
                    , new Object[] {  
                    person.getPersonName(),  
                    person.getSex(),  
                    person.getBirth(),  
                    person.getNativePlace(),  
                    person.getJob(),  
                    person.getSalary(),  
                    person.getHobby(),  
                    person.isDeleteFlag(),  
                    new Date(),  
                    person.getId()  
            });  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        return result == 1;  
    }  
      
    /** 
     * 根据ID删除 
     * @param id 
     * @return 
     */  
    public boolean delete(Long id) {  
        int result = 0;  
        try {  
            result = queryRunner.update("delete from person where id = ?", id);  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        return result == 1;  
    }  
      
    /** 
     * 根据ID查询 
     * @param id 
     * @return 
     */  
    public Person findById(Long id) {  
        Person person = null;  
        try {  
            person = queryRunner.query("select * from person where id = ?", new BeanHandler<Person>(Person.class),id);  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        return person;  
    }  
      
    /** 
     * 查询所有 
     * @return 
     */  
    public List<Person> findAll() {  
        List<Person> persons = null;  
        try {  
            persons = queryRunner.query("select * from person", new BeanListHandler<Person>(Person.class));  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        return persons;  
    }  
      
    /** 
     * 查询3秒之前的数据,用于测试 
     * @return 
     */  
    public List<Person> findPersonBefore3S() {  
        List<Person> persons = null;  
        try {  
            persons = queryRunner.query("select * from person where updatedTime >= DATE_SUB(NOW(),INTERVAL 3 SECOND)", new BeanListHandler<Person>(Person.class));  
        } catch (SQLException e) {  
            e.printStackTrace();  
        }  
        return persons;  
    }  
}  
   Java代码  

package com.yida.framework.lucene5.incrementindex;  
  
import java.text.DateFormat;  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Date;  
  
/** 
 * PersonDao测试 
 * @author Lanxiaowei 
 * 
 */  
public class PersonDaoTest {  
    private static final DateFormat dateFormate = new SimpleDateFormat("yyyy-MM-dd");  
    public static void main(String[] args) throws Exception {  
        addPerson();  
          
    }  
      
    /** 
     * 添加一个Person测试 
     * @throws ParseException 
     */  
    public static void addPerson() throws ParseException {  
        PersonDao personDao = new PersonDaoImpl();  
        String personName = "张国荣";  
        String sex = "1";  
        String birthString = "1956-09-12";  
        Date birth = dateFormate.parse(birthString);  
        String nativePlace = "中国香港九龙";  
        String job = "歌手";  
        Integer salary = 16000;  
        String hobby = "演员&音乐";  
        boolean deleteFlag = false;  
        Person person = new Person(personName, sex, birth, nativePlace, job, salary, hobby, deleteFlag);  
        boolean success = personDao.save(person);  
        System.out.println(success ? "Person save successful." : "Person save fauilure.");  
    }  
}  
   数据库建表SQL:Sql代码  

CREATE TABLE `person` (  
  `id` bigint(20) NOT NULL AUTO_INCREMENT,  
  `personName` varchar(60) DEFAULT NULL,  
  `sex` char(1) DEFAULT NULL,  
  `birth` datetime DEFAULT NULL,  
  `nativePlace` varchar(200) DEFAULT NULL,  
  `job` varchar(60) DEFAULT NULL,  
  `salary` int(11) DEFAULT NULL,  
  `hobby` varchar(200) DEFAULT NULL,  
  `deleteFlag` bit(1) DEFAULT NULL,  
  `updatedTime` datetime DEFAULT NULL,  
  PRIMARY KEY (`id`)  
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;  
  
  
INSERT INTO `person` VALUES (1, '兰小伟', '1', '1987-6-5 00:00:00', '湖北省武穴市', '码农', 16000, '看书写代码听歌看电影玩玩CS看看斯诺克比赛', '', '2015-4-6 18:01:30');  
INSERT INTO `person` VALUES (2, '李小龙', '1', '1940-2-26 00:00:00', '中国广东顺德均安镇', '武术大师', 16000, '武术&音乐', '', '2015-4-6 18:14:04');  
   建表SQL文件和demo源码我会在底下的附件里上传,自己去下载。SQL文件怎么导入到MySQL我就不多说了哈,如果这个你不会,请自己Google。运行ZoieTest类进行测试,在运行之前,请先打开DBHelper工具类,修改里面的MySQL数据库的帐号密码,因为你的MySQL登录帐号密码可能跟我的不一样,还有记得把Zoie-core的jar包install到本地仓库,否则你maven的pom.xml会报错。运行ZoieTest测试类之后,你就可以不断运行ZoieSearchTest测试来查询数据,来查看新增的数据是否已经被索引且能被搜索到。
资源地址 http://download.csdn.net/download/asdfsadfasdfsa/10273285
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: