lucene高级智能查询小案例
首先贴上项目的整体组成框架:
pom.xml资源层
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>fxys</groupId>
<artifactId>UserLucene</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>UserLucene Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>5.0.2.RELEASE</spring.version>
<mybatis.version>3.4.5</mybatis.version>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<!-- alipay -->
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>2.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
</dependency>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<!--<dependency>-->
<!--<groupId>net.sourceforge.jexcelapi</groupId>-->
<!--<artifactId>jxl</artifactId>-->
<!--<version>2.6.12</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
<scope>runtime</scope>
</dependency>
<!-- druid连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.26</version>
</dependency>
<!-- aspectJ织入 -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
<!-- JSON处理 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
<!-- JUnit4测试工具 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- Servlet-API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- JSTL标签库 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
<!-- https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.0.0</version>
</dependency>
<!-- lombok插件 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/activation/activation -->
<dependency>
<groupId>activation</groupId>
<artifactId>activation</artifactId>
<version>1.0.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-email -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
<version>1.4.4</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- lucene -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
<version>4.10.4</version>
</dependency>
<!-- lucene高亮相关的包 -->
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-highlighter</artifactId>
<version>4.10.4</version>
</dependency>
<!-- IK -->
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>
<dependency>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-queryparser</artifactId>
<version>4.10.4</version>
</dependency>
<!--使用mybatis分页插件-->
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.8</version>
</dependency>
<!-- jsoup和HtmlUnit爬虫包-->
<!-- https://mvnrepository.com/artifact/org.jsoup/jsoup -->
<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>1.11.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sourceforge.htmlunit/htmlunit -->
<dependency>
<groupId>net.sourceforge.htmlunit</groupId>
<artifactId>htmlunit</artifactId>
<version>2.33</version>
</dependency>
<!--获取请求头的工具类-->
<!-- https://mvnrepository.com/artifact/eu.bitwalker/UserAgentUtils -->
<dependency>
<groupId>eu.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.21</version>
</dependency>
<!-- ehcache核心jar包 -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>
<!-- MyBatis与ehcache整合jar包 -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!--ECharts工具类-->
<dependency>
<groupId>com.github.abel533</groupId>
<artifactId>ECharts</artifactId>
<version>3.0.0.2</version>
</dependency>
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.7</version>
</dependency>
<!-- 地理位置工具类-->
<dependency>
<groupId>com.maxmind.geoip2</groupId>
<artifactId>geoip2</artifactId>
<version>2.8.1</version>
</dependency>
<!--标签转换工具类-->
<dependency>
<groupId>com.0opslab</groupId>
<artifactId>opslabJutil</artifactId>
<version>1.0.8</version>
</dependency>
</dependencies>
<build>
<plugins>
<!--Java编译器插件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<extdirs>${project.basedir}/src/main/webapp/WEB-INF/lib</extdirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml
</configurationFile>
<verbose>true</verbose>
<overwrite>false</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
<scope>runtime</scope>
</dependency>
</dependencies>
</plugin>
<!-- 添加一个tomcat插件 -->
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<configuration>
<!-- tomcat启动的端口 -->
<port>80</port>
<!-- 应用的上下文路径 -->
<path>/</path>
<!--解决中文乱码-->
<uriEncoding>UTF-8</uriEncoding>
</configuration>
<!-- 在打包的时候运行这个容器 -->
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
数据库设计:
使用注意点:
1、本项目只能当做练习,还有地方没有完善,比如出现找不到的时候,会出现找不到这个类,然后报错,后期将会改进(因为这很简单,不想改了)
2、页数下拉单,如果超出这个范围,将会溢出报错,但是改的话,也是很简单的,太懒了 不愿意改,只教你们Lucene查询的具体的方法思路
3如果把本练习用到你那里运行的时候,记得修改路径
4、本次实现的代码有点冗余、有点乱,后期将会进行抽取
具体源码
domain
User类
package UserLucene.domain;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.util.Date;
@[email protected]@Data
public class User {
private Long id;
private String password;
private String phone;
private String sex;
private Date birthday;
private Date createtime;
}
mapper接口层
UserMapper接口
package UserLucene.mapper;
import UserLucene.domain.User;
import UserLucene.query.QueryObject;
import java.util.List;
public interface UserMapper {
int deleteByPrimaryKey(Long id);
int insert(User record);
User selectByPrimaryKey(Long id);
List<User> selectAll();
int updateByPrimaryKey(User record);
int queryforpagecount(QueryObject qo);
List<User>queryforpage(QueryObject qo);
}
page层
PageResult分页层
package UserLucene.page;
import UserLucene.util.PageIndex;
import lombok.Getter;
import lombok.Setter;
import java.util.Arrays;
import java.util.List;
public class PageResult {
private List<?>data;
private Integer totalcount;
private Integer currentpage=1;
private Integer pagesize=1;
private Integer beginpage=1;
private Integer endpage;
private Integer lastpage;
private Integer nextpage;
private Integer beginIndex;
private Integer endIndex;
private List<Integer> pagedata= Arrays.asList(1,3,5,6,9,10);
public PageResult(List<?> data, Integer totalcount, Integer currentpage, Integer pagesize) {
this.data = data;
this.totalcount = totalcount;
this.currentpage = currentpage;
this.pagesize = pagesize;
endpage=this.totalcount%this.pagesize==0? this.totalcount/this.pagesize:this.totalcount/this.pagesize+1;
lastpage=currentpage-1>=1?currentpage-1:1;
nextpage=currentpage+1<=endpage?currentpage+1:endpage;
PageIndex index=PageIndex.getPageIndex(3, currentpage, endpage);
beginIndex=index.getBeginIndex();
endIndex=index.getEndIndex();
}
}
query查找层
QueryObject查找类
package UserLucene.query;
import com.opslab.util.web.WebUtil;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
@[email protected]@Data
public class QueryObject {
private String keyword;
private String beginTime;
private String endTime;
private Integer currentPage=1;
private Integer pageSize=1;
private Integer beginIndex;
public String getKeyword(){
return WebUtil.unhtml(keyword);
}
public Integer getBeginIndex() {
return pageSize*(currentPage-1);
}
}
Service服务层
IUserService接口
package UserLucene.service;
import UserLucene.domain.User;
import UserLucene.page.PageResult;
import UserLucene.query.QueryObject;
import java.util.List;
import java.util.Map;
public interface IUserService {
int deleteByPrimaryKey(Long id);
int insert(User record);
User selectByPrimaryKey(Long id);
List<User> selectAll();
int updateByPrimaryKey(User record);
/**
* 根据Lucene全文检索翻页和查询数据获取用户行为集合
* @param qo 开始时间,结束时间,关键字
* @param webId 网站id
* @return 用户行为集合
*/
Map<String, Object> selectAllUserActionByLucene(QueryObject qo, String webId) throws Exception;
PageResult pageforpage(QueryObject qo);
}
UserServiceImpl业务实现层
package UserLucene.service.impl;
import UserLucene.domain.User;
import UserLucene.mapper.UserMapper;
import UserLucene.page.PageResult;
import UserLucene.query.QueryObject;
import UserLucene.service.IUserService;
import UserLucene.util.LuceneQueryUtil;
import UserLucene.util.LuceneUtil;
import UserLucene.util.StringUtil;
import com.opslab.util.web.WebUtil;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.search.highlight.Highlighter;
import org.apache.lucene.util.BytesRef;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.text.SimpleDateFormat;
import java.util.*;
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private UserMapper usermapper;
@Override
public int deleteByPrimaryKey(Long id) {
return usermapper.deleteByPrimaryKey(id);
}
@Override
public int insert(User record) {
LuceneUtil.insert(record,"D:/workforce/UserLucene/src/main/luceneindex"); //用户插入的时候,先插入到
return usermapper.insert(record);
}
@Override
public User selectByPrimaryKey(Long id) {
return usermapper.selectByPrimaryKey(id);
}
@Override
public List<User> selectAll() {
return usermapper.selectAll();
}
@Override
public int updateByPrimaryKey(User record) {
return usermapper.updateByPrimaryKey(record);
}
@Override
public Map<String, Object> selectAllUserActionByLucene(QueryObject qo, String userId) throws Exception {
//如果使用的是查询则用lucene查询
//如果是第一页则ScoreDoc为null
BooleanQuery query = new BooleanQuery();
WildcardQuery phoneQuery =new WildcardQuery(new Term("phone",""+qo.getKeyword()+"*"));
query.add(phoneQuery, BooleanClause.Occur.SHOULD);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
if(!StringUtil.isEmpty(qo.getBeginTime())&&StringUtil.isEmpty(qo.getEndTime())){
//有开始时间 没 结束时间
String beginTime =DateTools.dateToString(sdf.parse(qo.getBeginTime()),DateTools.Resolution.MILLISECOND);
String endTime =DateTools.dateToString(new Date(),DateTools.Resolution.MILLISECOND);
TermRangeQuery timeQuery =new TermRangeQuery("createTime", new BytesRef(beginTime), new BytesRef(endTime),true, true);
query.add(timeQuery, BooleanClause.Occur.MUST);
}else if(StringUtil.isEmpty(qo.getBeginTime())&&!StringUtil.isEmpty(qo.getEndTime())){
//没开始时间 有 结束时间
String beginTime = DateTools.dateToString(new Date(0L),DateTools.Resolution.MILLISECOND);
String endTime =DateTools.dateToString(sdf.parse(qo.getEndTime()),DateTools.Resolution.MILLISECOND);
TermRangeQuery timeQuery =new TermRangeQuery("createTime", new BytesRef(beginTime), new BytesRef(endTime),true, true);
query.add(timeQuery, BooleanClause.Occur.MUST);
}else if(!StringUtil.isEmpty(qo.getBeginTime())&&!StringUtil.isEmpty(qo.getEndTime())){
//有开始时间有结束时间
String beginTime =DateTools.dateToString(sdf.parse(qo.getBeginTime()),DateTools.Resolution.MILLISECOND);
String endTime =DateTools.dateToString(sdf.parse(qo.getEndTime()),DateTools.Resolution.MILLISECOND);
TermRangeQuery timeQuery =new TermRangeQuery("createTime", new BytesRef(beginTime), new BytesRef(endTime),true, true);
query.add(timeQuery, BooleanClause.Occur.MUST);
}
Map<String,Object> result= LuceneQueryUtil.QueryUser(qo,"/luceneIndex/user/"+userId,query);
List<User> user= makeluceneDocAsUserList(result,qo);
result.put("user",user);
return result;
}
@Override
public PageResult pageforpage(QueryObject qo) {
Integer count=usermapper.queryforpagecount(qo);
if(count==0)
return null;
else{
List<User> result=usermapper.queryforpage(qo);
return new PageResult(result,count,qo.getCurrentPage(),qo.getPageSize());
}
}
/**
*讲查询到的lucene文档进行简单包装成useraction数组
* @param result lucene查询得到的map,其中包括所有查询出来的文档和高亮工具类
* @return 所有符合的股票集合
* @throws Exception
*/
private List<User> makeluceneDocAsUserList(Map<String, Object> result,QueryObject qo) throws Exception {
List<Document> docs= (List<Document>) result.get("docs");
//获取高亮工具类
Highlighter hl= (Highlighter) result.get("Highlighter");
//设置前N项关键字高亮
hl.setMaxDocCharsToAnalyze(100000000);
List<User> userList=new ArrayList<>();
for (Document doc : docs) {
User user=new User();
if(!StringUtil.isEmpty(hl.getBestFragment(LuceneUtil.analyzer,"phone", WebUtil.unhtml(doc.get("phone"))))){
user.setPhone(hl.getBestFragment(LuceneUtil.analyzer,"phone",WebUtil.unhtml(doc.get("phone"))));
}else {
user.setPhone(WebUtil.unhtml(doc.get("phone")));
}
user.setId(Long.valueOf(doc.get("id")));
user.setPhone(doc.get("phone"));
user.setBirthday(DateTools.stringToDate(doc.get("birthday")));
user.setPassword(doc.get("password"));
user.setCreatetime(DateTools.stringToDate(doc.get("createTime")));
userList.add(user);
}
return userList;
}
}
util工具层
applicateLucene(本次使用的工具类)
package UserLucene.util;
import UserLucene.domain.User;
import UserLucene.query.QueryObject;
import com.opslab.util.web.WebUtil;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.Version;
import org.springframework.stereotype.Component;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class applicateLucene {
static Version version= Version.LUCENE_4_10_4; //创建Lucene的版本
public static Analyzer analyzer = new CJKAnalyzer(version);//配置分词对象
public static String path="D:/workforce/UserLucene/src/main/luceneindex";
public static List<User> luceneFenye(QueryObject qo) throws IOException, ParseException, InvalidTokenOffsetsException {
List<User>list=new ArrayList<>();
//分页用两个参数
int page=qo.getCurrentPage(); //第2页
int pagenum=qo.getPageSize(); //每页显示2条
//获取查询对象
IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(new File(path))));
BooleanQuery query = new BooleanQuery();
WildcardQuery PasswordQuery =new WildcardQuery(new Term("password",""+qo.getKeyword()+"*"));
WildcardQuery PhoneQuery =new WildcardQuery(new Term("phone",""+qo.getKeyword()+"*"));
//
query.add(PasswordQuery, BooleanClause.Occur.SHOULD);
query.add(PhoneQuery, BooleanClause.Occur.SHOULD);
// SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// if(!StringUtil.isEmpty(qo.getBeginTime())&&StringUtil.isEmpty(qo.getEndTime())){
// //有开始时间 没 结束时间
// String beginTime =DateTools.dateToString(sdf.parse(qo.getBeginTime()),DateTools.Resolution.MILLISECOND);
// String endTime =DateTools.dateToString(new Date(),DateTools.Resolution.MILLISECOND);
// TermRangeQuery timeQuery =new TermRangeQuery("createTime", new BytesRef(beginTime), new BytesRef(endTime),true, true);
// query.add(timeQuery, BooleanClause.Occur.MUST);
// }else if(StringUtil.isEmpty(qo.getBeginTime())&&!StringUtil.isEmpty(qo.getEndTime())){
// //没开始时间 有 结束时间
// String beginTime =DateTools.dateToString(new Date(0L),DateTools.Resolution.MILLISECOND);
// String endTime =DateTools.dateToString(sdf.parse(qo.getEndTime()),DateTools.Resolution.MILLISECOND);
// TermRangeQuery timeQuery =new TermRangeQuery("createTime", new BytesRef(beginTime), new BytesRef(endTime),true, true);
// query.add(timeQuery, BooleanClause.Occur.MUST);
// }else if(!StringUtil.isEmpty(qo.getBeginTime())&&!StringUtil.isEmpty(qo.getEndTime())){
// //有开始时间有结束时间
// String beginTime =DateTools.dateToString(sdf.parse(qo.getBeginTime()),DateTools.Resolution.MILLISECOND);
// String endTime =DateTools.dateToString(sdf.parse(qo.getEndTime()),DateTools.Resolution.MILLISECOND);
// TermRangeQuery timeQuery =new TermRangeQuery("createTime", new BytesRef(beginTime), new BytesRef(endTime),true, true);
// query.add(timeQuery, BooleanClause.Occur.MUST);
// }
//
//
//
//
//
//
//
//执行查询,此处用此处用词条查询
//TermQuery termQuery = new TermQuery(new Term("password",qo.getKeyword()));
Formatter formatter =new SimpleHTMLFormatter("<font color='red'>","</font>");
Scorer scorer =new QueryScorer(query);
Highlighter hl =new Highlighter(formatter,scorer);
//限定N个字符需要高亮显示,多余的内容会被忽略掉
hl.setMaxDocCharsToAnalyze(1000000000);
// FuzzyQuery empquery=new FuzzyQuery(new Term("content","格"),1);
// QueryParser parser=new QueryParser("content",analyzer);
// Query query=parser.parse("*:*");
TopDocs topDocs = indexSearcher.search(query, page*pagenum); //第一页显示2条,第二页显示2条+第一页2条=4条
int totalHits = topDocs.totalHits;//查询总数
if(totalHits==0)
return null;
ScoreDoc[] scoreDocs = topDocs.scoreDocs;//查询分数的数组
int total=0;
for(int i=(page-1)*pagenum;i< page*pagenum;i++){ //选择读取pagenum
ScoreDoc scoreDoc = scoreDocs[i];
float score = scoreDoc.score;//获取分数
int id = scoreDoc.doc;//获取该分数对应的id
Document doc = indexSearcher.doc(id);//根据id查询文档
// String content = doc.get("password");
// String phone=doc.get("phone");
// if(content!=null){
// try {
// String password=hl.getBestFragment(LuceneUtil.analyzer,"password", WebUtil.unhtml(doc.get("password")));
// System.out.println(password);
// } catch (InvalidTokenOffsetsException e) {
// e.printStackTrace();
// }
// System.out.println("-----password="+content+" "+phone);
// total++;
// }
// if(total==totalHits){
// return;
// }
//
User u=new User();
if(doc.get("password")!=null||doc.get("phone")!=null||doc.get("sex")!=null){
total++;
if(!StringUtil.isEmpty(hl.getBestFragment(analyzer,"password",WebUtil.unhtml(doc.get("password"))))){
u.setPassword(hl.getBestFragment(analyzer,"password",WebUtil.unhtml(doc.get("password"))));
}else {
u.setPassword(WebUtil.unhtml(doc.get("password")));
}
if(!StringUtil.isEmpty(hl.getBestFragment(analyzer,"phone",doc.get("phone")))){
u.setPhone(hl.getBestFragment(analyzer,"phone",doc.get("phone")));
}else {
u.setPhone(doc.get("phone"));
}
if(!StringUtil.isEmpty(hl.getBestFragment(LuceneUtil.analyzer,"sex",doc.get("sex")))){
u.setSex(hl.getBestFragment(LuceneUtil.analyzer,"sex",doc.get("sex")));
}else {
u.setSex(doc.get("sex"));
}
u.setId(Long.valueOf(doc.get("id")));
//u.setBirthday(DateTools.stringToDate(doc.get("birthday")));
//u.setCreatetime(DateTools.stringToDate(doc.get("createTime")));
list.add(u);
}
if(total==totalHits)
break;
}
return list;
}
public static List<User> luceneNullFenYe(QueryObject qo) throws IOException, org.apache.lucene.queryparser.classic.ParseException, ParseException {
List<User> list=new ArrayList<>();
//分页用两个参数
int page=qo.getCurrentPage(); //第2页
int pagenum=qo.getPageSize(); //每页显示2条
//获取查询对象
IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(new File(path))));
QueryParser parser=new QueryParser("id",analyzer);
Query query=parser.parse("*:*");
TopDocs topDocs = indexSearcher.search(query, page*pagenum); //第一页显示2条,第二页显示2条+第一页2条=4条
int totalHits = topDocs.totalHits;//查询总数
if(totalHits==0)
return null;
ScoreDoc[] scoreDocs = topDocs.scoreDocs;//查询分数的数组
int total=0;
for(int i=(page-1)*pagenum;i< page*pagenum;i++){ //选择读取pagenum
ScoreDoc scoreDoc = scoreDocs[i];
float score = scoreDoc.score;//获取分数
int id = scoreDoc.doc;//获取该分数对应的id
Document doc = indexSearcher.doc(id);//根据id查询文档
User u=new User();
if(doc.get("password")!=null||doc.get("phone")!=null||doc.get("birthday")!=null||doc.get("sex")!=null||doc.get("createTime")!=null){
total++;
u.setPassword(doc.get("password"));
u.setPhone(doc.get("phone"));
u.setSex(doc.get("sex"));
u.setId(Long.valueOf(doc.get("id")));
//u.setBirthday(DateTools.stringToDate(doc.get("birthday")));
//u.setCreatetime(DateTools.stringToDate(doc.get("createTime")));
list.add(u);
}
if(total==totalHits)
break;
}
return list;
}
public static List<User> souci() throws org.apache.lucene.queryparser.classic.ParseException, IOException {
List<User> list=new ArrayList<>();
IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(new File(path))));
QueryParser parser=new QueryParser("id",analyzer);
Query query=parser.parse("*:*");
TopDocs topDocs = indexSearcher.search(query,100000); //第一页显示2条,第二页显示2条+第一页2条=4条
int totalHits = topDocs.totalHits;//查询总数
if(totalHits==0)
return null;
ScoreDoc[] scoreDocs = topDocs.scoreDocs;//查询分数的数组
ScoreDoc scoredoc=null;
Document doc=null;
for (int i=0;i<scoreDocs.length;i++){
User u=new User();
scoredoc=scoreDocs[i];
doc=indexSearcher.doc(scoredoc.doc);
u.setPassword(doc.get("password"));
u.setPhone(doc.get("phone"));
u.setSex(doc.get("sex"));
u.setId(Long.valueOf(doc.get("id")));
list.add(u);
}
return list;
}
public static List<User> Qosouci(QueryObject qo) throws org.apache.lucene.queryparser.classic.ParseException, IOException {
List<User> list=new ArrayList<>();
IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(new File(path))));
BooleanQuery query = new BooleanQuery();
WildcardQuery PasswordQuery =new WildcardQuery(new Term("password",""+qo.getKeyword()+"*"));
WildcardQuery PhoneQuery =new WildcardQuery(new Term("phone",""+qo.getKeyword()+"*"));
//
query.add(PasswordQuery, BooleanClause.Occur.SHOULD);
query.add(PhoneQuery, BooleanClause.Occur.SHOULD);
TopDocs topDocs = indexSearcher.search(query, 1000000); //第一页显示2条,第二页显示2条+第一页2条=4条
int totalHits = topDocs.totalHits;//查询总数
if(totalHits==0)
return null;
ScoreDoc[] scoreDocs = topDocs.scoreDocs;//查询分数的数组
ScoreDoc scoredoc=null;
Document doc=null;
for (int i=0;i<scoreDocs.length;i++){
User u=new User();
scoredoc=scoreDocs[i];
doc=indexSearcher.doc(scoredoc.doc);
u.setPassword(doc.get("password"));
u.setPhone(doc.get("phone"));
u.setSex(doc.get("sex"));
u.setId(Long.valueOf(doc.get("id")));
list.add(u);
}
return list;
}
}
limit(本次获得灵感的测试方法)
package UserLucene.util;
import com.opslab.util.web.WebUtil;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
public class limit {
static Version version= Version.LUCENE_4_10_4; //创建Lucene的版本
public static Analyzer analyzer = new CJKAnalyzer(version);//配置分词对象
String path="D:/workforce/UserLucene/src/main/luceneindex";
@Test
public void testLucene() throws Exception{
//1.定义Lucene存放文件的位置
Directory directory= FSDirectory.open(new File(path));
//2.配置分词对象
//3.配置对象
IndexWriterConfig config=new IndexWriterConfig(version,analyzer);
IndexWriter writer=new IndexWriter(directory,config);
//4.往库里写入内容
FieldType type=new FieldType();
type.setStored(true);//可存储
type.setIndexed(true);//存储索引
type.setTokenized(true);//设置分词
//创建文档对象
Document doc=new Document();
doc.add(new Field("content","格力是个好空调",type));
doc.add(new Field("content","威士忌",type));
doc.add(new Field("content","苏格兰",type));
doc.add(new Field("content","苏格兰",type));
writer.addDocument(doc);
//5.提交资源
//6.关闭资源
writer.close();
}
@Test
public void limit() throws IOException, ParseException {
//分页用两个参数
int page=1; //第2页
int pagenum=1; //每页显示2条
//获取查询对象
IndexSearcher indexSearcher = new IndexSearcher(DirectoryReader.open(FSDirectory.open(new File(path))));
BooleanQuery query = new BooleanQuery();
WildcardQuery userIpQuery =new WildcardQuery(new Term("password",""+"人类"+"*"));
WildcardQuery pageQuery =new WildcardQuery(new Term("phone",""+"按钮"+"*"));
//
query.add(userIpQuery, BooleanClause.Occur.SHOULD);
query.add(pageQuery, BooleanClause.Occur.SHOULD);
//执行查询,此处用此处用词条查询
// TermQuery termQuery = new TermQuery(new Term("password","按钮"));
Formatter formatter =new SimpleHTMLFormatter("<font color='red'>","</font>");
Scorer scorer =new QueryScorer(query);
Highlighter hl =new Highlighter(formatter,scorer);
//限定N个字符需要高亮显示,多余的内容会被忽略掉
hl.setMaxDocCharsToAnalyze(1000000000);
// FuzzyQuery empquery=new FuzzyQuery(new Term("content","格"),1);
// QueryParser parser=new QueryParser("content",analyzer);
// Query query=parser.parse("*:*");
TopDocs topDocs = indexSearcher.search(query, page*pagenum); //第一页显示2条,第二页显示2条+第一页2条=4条
int totalHits = topDocs.totalHits;//查询总数
System.out.println(totalHits);
if(totalHits==0)
return;
ScoreDoc[] scoreDocs = topDocs.scoreDocs;//查询分数的数组
int total=0;
for(int i=(page-1)*pagenum;i< page*pagenum;i++){ //选择读取pagenum
ScoreDoc scoreDoc = scoreDocs[i];
float score = scoreDoc.score;//获取分数
int id = scoreDoc.doc;//获取该分数对应的id
Document doc = indexSearcher.doc(id);//根据id查询文档
String content = doc.get("password");
String phone=doc.get("phone");
if(content!=null){
try {
String password=hl.getBestFragment(LuceneUtil.analyzer,"password", WebUtil.unhtml(doc.get("password")));
System.out.println(password);
} catch (InvalidTokenOffsetsException e) {
e.printStackTrace();
}
System.out.println("-----password="+content+" "+phone);
total++;
}
if(total==totalHits){
return;
}
}
}
}
LogUtil日志工具类(没认真写好)
package UserLucene.util;
import org.aspectj.lang.JoinPoint;
public class LogUtil {
public void writelog(JoinPoint joinPoint) {}
}
LuceneQueryUtil(Lucene查询工具类)
package UserLucene.util;
import UserLucene.query.QueryObject;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.search.*;
import org.apache.lucene.search.highlight.*;
import org.apache.lucene.search.highlight.Scorer;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import static jdk.nashorn.internal.objects.NativeString.search;
public class LuceneQueryUtil {
public static List<Document> queryById(String id, String path)throws Exception{
return (List<Document>) search("id:"+id,path);
}
/**
* //分页查询
* @param qo 包括keyword 查询关键字 after 上一页的最后一个pageSize 每页大小
* @param path 文件路径
* @return 高亮工具类和所查询到的文档
* @throws Exception
*/
public static HashMap<String, Object> search(QueryObject qo, String path, Query query)throws Exception{
//返回的所有文档内容
List<Document> docs=new ArrayList<>();
//先创建目录文件,存储的索引文件
Directory directory = FSDirectory.open(new File(path));
//需要读取索引内容
IndexReader r= DirectoryReader.open(directory);
//创建索引读取对象
IndexSearcher searcher=new IndexSearcher(r);
//设置高亮
Formatter formatter =new SimpleHTMLFormatter("<font color='red'>","</font>");
Scorer scorer =new QueryScorer(query);
Highlighter hl =new Highlighter(formatter,scorer);
//限定N个字符需要高亮显示,多余的内容会被忽略掉
hl.setMaxDocCharsToAnalyze(1000000000);
ScoreDoc lastSd=getLastScoreDoc(qo.getCurrentPage(),qo.getPageSize(),query,searcher);
TopDocs tds= searcher.searchAfter(lastSd,query,qo.getPageSize());//查询前1000000000条
ScoreDoc[] sds=tds.scoreDocs;
for (int i=0;i<sds.length;i++){
docs.add(searcher.doc(sds[i].doc));
//获取高亮字符串
//String str =hl.getBestFragment(new IKAnalyzer(),"content",doc.get("content"));
}
HashMap<String,Object> result=new HashMap<>();
result.put("docs",docs);
result.put("ScoreDocs",sds);
result.put("totalCount",tds.totalHits);
result.put("Highlighter",hl);
return result;
}
private static ScoreDoc getLastScoreDoc(int pageIndex,int pageSize,Query query,IndexSearcher searcher) throws Exception {
if(pageIndex==1)return null;//如果是第一页就返回空
int num = pageSize*(pageIndex-1);//获取上一页的最后数量
TopDocs tds = searcher.search(query, num);
return tds.scoreDocs[num-1];
}
public static List<Document> search(String keyword, String path)throws Exception{
//返回的所有文档内容
List<Document> docs=new ArrayList<>();
//先创建目录文件,存储的索引文件
Directory directory =FSDirectory.open(new File(path));
//需要读取索引内容
IndexReader r= DirectoryReader.open(directory);
//创建索引读取对象
IndexSearcher searcher=new IndexSearcher(r);
//分词器
//Analyzer analyzer =new IKAnalyzer();
//查询对象
QueryParser parser=new QueryParser("name",LuceneUtil.analyzer);
Query query =parser.parse(keyword);
TopDocs tds= searcher.search(query,1000000000);//查询前1000000000条
ScoreDoc[] sds=tds.scoreDocs;
for (int i=0;i<sds.length;i++){
docs.add(searcher.doc(sds[i].doc));
//获取高亮字符串
//String str =hl.getBestFragment(new IKAnalyzer(),"content",doc.get("content"));
}
return docs;
}
/**
* @param qo keyword 根据关键字查询
* @param path 查询哪个文档路径
* @param query 查询器
*/
public static HashMap<String, Object> QueryUser(QueryObject qo,String path,Query query){
try {
return search(qo,path,query);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
}
LuceneUtil(工具类)(包括增删改,很重要)
package UserLucene.util;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.cjk.CJKAnalyzer;
import org.apache.lucene.document.DateTools;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
public class LuceneUtil {
static Version version= Version.LUCENE_4_10_4; //创建Lucene的版本
public static Analyzer analyzer = new CJKAnalyzer(version);//配置分词对象
//删除操作
public static void LuceneDelete(Long id,String path) throws IOException {
IndexWriter writer=null;
try {
//定义Lucene存放文件的位置
Directory directory= FSDirectory.open(new File(path));
//配置对象
IndexWriterConfig config=new IndexWriterConfig(version,analyzer);
writer=new IndexWriter(directory,config);
writer.deleteDocuments(new Term("id",id+""));
}catch (Exception e){
e.printStackTrace();
}finally {
writer.close();
}
}
//更新操作
public static <T> void LuceneUpdate(T obj,String path) throws IOException {
IndexWriter writer=null;
try {
//定义Lucene存放文件的位置
Directory directory= FSDirectory.open(new File(path));
//配置对象
IndexWriterConfig config=new IndexWriterConfig(version,analyzer);
writer=new IndexWriter(directory,config);
//往库里写入内容
FieldType type=new FieldType();
type.setStored(true);//可存储
type.setIndexed(true);//存储索引
type.setTokenized(true);//设置分词
//设置文档对象
Document updateDoc=new Document();
Long id=null;
//-------------------------------------
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(),Object.class);
PropertyDescriptor[] pds =beanInfo.getPropertyDescriptors();
//获取该类的ID
for (PropertyDescriptor pd :pds){
String fieldName=pd.getName();//获取字段名
if(fieldName.equals("id")){
id=(Long)pd.getReadMethod().invoke(obj);
break;
}
}
//因为更新时是先删除,所以要把原来的信息加回去,所以这里根据ID查询回来保存着
List<Document> docs= LuceneQueryUtil.queryById(id+"",path);
//把原来的字段先加进来
for (PropertyDescriptor pd :pds){
String fieldName=pd.getName();//获取字段名
for (int i =0;i<docs.size();i++){
if(docs.get(i).get(fieldName)!=null){
updateDoc.add(new Field(fieldName,docs.get(i).get(fieldName),type));
break;
}
}
}
for (PropertyDescriptor pd :pds){
String fieldName=pd.getName();//获取字段名
Method method=pd.getReadMethod();
Object value =method.invoke(obj);//获取该字段的值
//把所有string存入
if(value!=null&& value instanceof String){
String v=(String)value;
if(v.length()!=0){
if(updateDoc.get(fieldName)!=null){
updateDoc.removeField(fieldName);
}
updateDoc.add(new Field(fieldName,v,type));
}
}
//把number类型存入
if(value!=null&& value instanceof Number){
if(value instanceof Integer){
if(updateDoc.get(fieldName)!=null){
updateDoc.removeField(fieldName);
}
Integer v=(Integer)value;
updateDoc.add(new Field(fieldName,v+"",type));
}
if(value instanceof Long){
Long v=(Long)value;
//把该ID保存下来
if(fieldName.equals("id")){
id=v;
}
if(updateDoc.get(fieldName)!=null){
updateDoc.removeField(fieldName);
}
updateDoc.add(new Field(fieldName,v+"",type));
}
if(value instanceof BigDecimal){
if(updateDoc.get(fieldName)!=null){
updateDoc.removeField(fieldName);
}
BigDecimal v=(BigDecimal)value;
updateDoc.add(new Field(fieldName,v.toString(),type));
}
}
//把date类型存入lucene的date类型只能是YYYYMMDDhhmmss
if(value!=null&& value instanceof Date){
if(updateDoc.get(fieldName)!=null){
updateDoc.removeField(fieldName);
}
Date v=(Date) value;
String date= DateTools.dateToString(v, DateTools.Resolution.MILLISECOND);
updateDoc.add(new Field(fieldName,date,type));
}
}
//-------------------------------------
writer.updateDocument(new Term("id",id+""),updateDoc);
}catch (Exception e){
e.printStackTrace();
}finally {
writer.close();
}
}
/**
* 插入操作
*/
public static <T> void insert(T obj,String path){
//lucene的插入
IndexWriter writer=null;
try {
Directory directory =FSDirectory.open(new File(path));
//Analyzer analyzer =new IKAnalyzer();
IndexWriterConfig config =new IndexWriterConfig(version,analyzer);
writer =new IndexWriter(directory,config);
FieldType type =new FieldType();
type.setIndexed(true);//建立索引
type.setStored(true);//保存值信息
Document insertDoc =new Document();
//-------------------------------------
BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass(),Object.class);
PropertyDescriptor[] pds =beanInfo.getPropertyDescriptors();
for (PropertyDescriptor pd :pds){
String fieldName=pd.getName();//获取字段名
Method method=pd.getReadMethod();
Object value =method.invoke(obj);//获取该字段的值
System.out.println(fieldName+" "+value);
//把所有string存入
if(value!=null&& value instanceof String){
String v=(String)value;
if(v.length()!=0){
insertDoc.add(new Field(fieldName,v,type));
}
}
//把number类型存入
if(value!=null&& value instanceof Number){
if(value instanceof Integer){
Integer v=(Integer)value;
insertDoc.add(new Field(fieldName,v+"",type));
}
if(value instanceof Long){
Long v=(Long)value;
insertDoc.add(new Field(fieldName,v+"",type));
}
if(value instanceof BigDecimal){
BigDecimal v=(BigDecimal)value;
insertDoc.add(new Field(fieldName,v.toString(),type));
}
}
//把date类型存入lucene的date类型只能是YYYYMMDDhhmmss
if(value!=null&& value instanceof Date){
Date v=(Date) value;
String date= DateTools.dateToString(v, DateTools.Resolution.MILLISECOND);
insertDoc.add(new Field(fieldName,date,type));
}
}
//-------------------------------------
writer.addDocument(insertDoc);
}catch (Exception e){
e.printStackTrace();
}finally {
try {
writer.close();
}catch (Exception e){
e.printStackTrace();
}
}
}
}
PageIndex分页工具类
package UserLucene.util;
public class PageIndex {
private Integer beginIndex;
private Integer endIndex;
public static PageIndex getPageIndex(Integer totalIndexCount,
Integer currentPage, Integer totalPage) {
Integer startPageIndex = currentPage
- (totalIndexCount % 2 == 0 ? totalIndexCount / 2 - 1 : totalIndexCount / 2);
Integer endPageIndex = currentPage + totalIndexCount / 2;
if (startPageIndex < 1) {
startPageIndex = 1;
if (totalPage >= totalIndexCount)
endPageIndex = totalIndexCount;
else
endPageIndex = totalPage;
}
if (endPageIndex > totalPage) {
endPageIndex = totalPage;
if ((endPageIndex - totalIndexCount) > 0)
startPageIndex = endPageIndex - totalIndexCount + 1;
else
startPageIndex = 1;
}
return new PageIndex(startPageIndex, endPageIndex);
}
public PageIndex(Integer beginIndex, Integer endIndex) {
this.beginIndex = beginIndex;
this.endIndex = endIndex;
}
public Integer getBeginIndex() {
return beginIndex;
}
public Integer getEndIndex() {
return endIndex;
}
}
SearchResultBean查找方法
package UserLucene.util;
import org.apache.lucene.document.Document;
import java.util.List;
import java.util.List;
import org.apache.lucene.document.Document;
public class SearchResultBean
{
private int totalHits;
private List<Document> docs;
public SearchResultBean()
{
}
public SearchResultBean(int totalHits, List<Document> docs)
{
this.totalHits = totalHits;
this.docs = docs;
}
public int getTotalHits()
{
return this.totalHits;
}
public void setTotalHits(int totalHits)
{
this.totalHits = totalHits;
}
public List<Document> getDocs()
{
return this.docs;
}
public void setDocs(List<Document> docs)
{
this.docs = docs;
}
}
StringUtil工具类
package UserLucene.util;
public class StringUtil {
public static boolean isEmpty(String value){
if(value==null||value.length()==0||"null".equals(value)) {
return true;
}else {
return false;
}
}
}
UserController用户控制层
package UserLucene.web.controller;
import UserLucene.domain.User;
import UserLucene.page.PageResult;
import UserLucene.query.QueryObject;
import UserLucene.util.applicateLucene;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.highlight.InvalidTokenOffsetsException;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
@Controller
public class UserController {
@RequestMapping("/PageResult")
public void list(QueryObject qo, HttpServletRequest req, HttpServletResponse resp) throws IOException, ParseException, java.text.ParseException, InvalidTokenOffsetsException, ServletException {
String currentPage=req.getParameter("currentPage");
if(qo.getKeyword() ==null||qo.getKeyword().equals("")){
List<User>Userlist= applicateLucene.luceneNullFenYe(qo);
List<User>Userlist1= applicateLucene.souci();
PageResult page1= new PageResult(Userlist,Userlist1.size(),qo.getCurrentPage(),qo.getPageSize());
req.setAttribute("pageresult",page1);
req.getRequestDispatcher("/page.jsp").forward(req,resp);
}
else {
System.out.println(currentPage+" "+1111);
List<User>Userlist= applicateLucene.luceneFenye(qo);
List<User>Userlist1=applicateLucene.Qosouci(qo);
PageResult page2= new PageResult(Userlist,Userlist1.size(),qo.getCurrentPage(),qo.getPageSize());
req.setAttribute("qo",qo);
req.setAttribute("pageresult",page2);
req.getRequestDispatcher("/page.jsp").forward(req,resp);
}
}
}
InitServlet初始化(没认真写)
package UserLucene.web.initServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
public class InitServlet extends HttpServlet {
@Override
//用于启动服务器时的初始化操作
public void init() throws ServletException {}
}
LoginIncepter登录拦截器(没认真写)
package UserLucene.web.intercepter;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginIncepter implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
}
mapper资源层
UserMapper资源层
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="UserLucene.mapper.UserMapper" >
<resultMap id="BaseResultMap" type="UserLucene.domain.User" >
<id column="id" property="id" jdbcType="BIGINT" />
<result column="password" property="password" jdbcType="VARCHAR" />
<result column="phone" property="phone" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<result column="birthday" property="birthday" />
<result column="createTime" property="createtime" jdbcType="DATE" />
</resultMap>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
delete from user
where id = #{id,jdbcType=BIGINT}
</delete>
<insert id="insert" parameterType="UserLucene.domain.User" useGeneratedKeys="true" keyProperty="id" >
insert into user (password, phone, sex,
birthday,createTime)
values (#{password,jdbcType=VARCHAR}, #{phone,jdbcType=VARCHAR}, #{sex,jdbcType=VARCHAR},
#{birthday},#{createtime,jdbcType=DATE})
</insert>
<update id="updateByPrimaryKey" parameterType="UserLucene.domain.User" >
update user
set password = #{password,jdbcType=VARCHAR},
phone = #{phone,jdbcType=VARCHAR},
sex = #{sex,jdbcType=VARCHAR},
birthday = #{birthday},
createTime = #{createtime,jdbcType=DATE}
where id = #{id,jdbcType=BIGINT}
</update>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
select *
from user
where id = #{id,jdbcType=BIGINT}
</select>
<select id="selectAll" resultMap="BaseResultMap" >
select *
from user
</select>
<sql id="search_sql">
<where>
<if test="keyword!=null">
phone LIKE CONCAT('%',#{keyword},'%')
</if>
<if test="beginTime!=null">and createTime > #{beginTime}</if>
<if test="endTime!=null">and createTIme <#{endTime}</if>
</where>
</sql>
<select id="queryforpagecount" resultType="int">
SELECT COUNT(*) FROM user
<include refid="search_sql"></include>
</select>
<select id="queryforpage" resultType="UserLucene.domain.User">
select *from user
<include refid="search_sql"></include>
<if test="currentPage!=null">
limit 0,#{pageSize}
</if>
</select>
</mapper>
application.xml资源层
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--0.导入数据库连接-->
<!--组件注解解析器-->
<context:annotation-config></context:annotation-config>
<!--扫描包-->
<context:component-scan base-package="UserLucene.service"></context:component-scan>
<context:component-scan base-package="UserLucene.util"></context:component-scan>
<!--AOP自动代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--1.配置数据库连接池-->
<context:property-placeholder location="classpath:db.properties" ></context:property-placeholder>
<bean id="datasource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="maxActive" value="${jdbc.maxActive}"></property>
</bean>
<!--2.sessionFactory-->
<bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--2.1数据源引用-->
<property name="dataSource" ref="datasource"></property>
<!--2.2mybatis配置文件-->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<!--2.3引用映射文件-->
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml"></property>
</bean>
<!--3.事务管理器-->
<!--what:事务管理器的配置-->
<bean id="txmanager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
<!--4.事务模板-->
<!--when:事务增强的时机-->
<tx:advice id="txadvice" transaction-manager="txmanager">
<tx:attributes>
<tx:method name="query*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="list*" read-only="true" propagation="SUPPORTS"/>
<tx:method name="*" propagation="SUPPORTS"></tx:method>
</tx:attributes>
</tx:advice>
<!--5.AOP相关配置-->
<bean id="logutils" class="UserLucene.util.LogUtil"></bean>
<!--在哪些包下的哪些类进行增强-->
<aop:config>
<!--切入点-->
<aop:pointcut id="txpoint" expression="execution(* UserLucene.service.*.*(..))"></aop:pointcut>
<!--关联-->
<aop:advisor advice-ref="txadvice" pointcut-ref="txpoint"></aop:advisor>
<aop:aspect ref="logutils">
<aop:after method="writelog" pointcut="execution(* UserLucene.service.*.*(..))"></aop:after>
</aop:aspect>
</aop:config>
<!--6.开启扫描注解-->
<!--7.mapper接口的扫描器-->
<bean id="mapperscanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="UserLucene.mapper"></property>
</bean>
</beans>
application-mvc.xml资源层
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
<!-- 1.开启注解扫描 -->
<context:component-scan base-package="UserLucene.web"/>
<!-- 2.支持注解驱动:如json解析 -->
<mvc:annotation-driven/>
<!-- 定时任务配置-->
<task:annotation-driven/>
<!-- 3.配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--静态资源处理,防止过滤静态资源,其中的web.xml也可以配置 -->
<mvc:default-servlet-handler/>
<!-- 加载其他配置文件 -->
<import resource="classpath:application.xml"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/*"/>
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/register"/>
<bean class="UserLucene.web.intercepter.LoginIncepter"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
db.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost/userlucene?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=123456
jdbc.maxActive=5
ehcache.xml
<?xml version="1.0" encoding="UTF-8" ?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<!--
java.io.tmpdir - Default temp file path 默认的 temp 文件目录
maxElementsInMemory:内存中最大缓存对象数.
maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大.
eternal:Element是否永久有效,一但设置了,timeout将不起作用.
overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0, 也就是可闲置时间无穷大
timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,
默认是0.也就是element存活时间无穷大.
diskPersistent:是否缓存虚拟机重启期数据。(这个虚拟机是指什么虚拟机一直没看明白是什么,有高人还希望能指点一二)
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区.
-->
<diskStore path="/ehcache" />
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true"
maxElementsOnDisk="10000000" diskPersistent="false"
diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
</ehcache>
generatorConfig.xml(代码自动生成)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<!-- 配置生成器 -->
<generatorConfiguration>
<context id="mysql" defaultModelType="hierarchical"
targetRuntime="MyBatis3Simple">
<!-- 自动识别数据库关键字,默认false,如果设置为true,根据SqlReservedWords中定义的关键字列表; 一般保留默认值,遇到数据库关键字(Java关键字),使用columnOverride覆盖 -->
<property name="autoDelimitKeywords" value="false" />
<!-- 生成的Java文件的编码 -->
<property name="javaFileEncoding" value="UTF-8" />
<!-- 格式化java代码 -->
<property name="javaFormatter"
value="org.mybatis.generator.api.dom.DefaultJavaFormatter" />
<!-- 格式化XML代码 -->
<property name="xmlFormatter"
value="org.mybatis.generator.api.dom.DefaultXmlFormatter" />
<!-- beginningDelimiter和endingDelimiter:指明数据库的用于标记数据库对象名的符号,比如ORACLE就是双引号,MYSQL默认是`反引号; -->
<property name="beginningDelimiter" value="`" />
<property name="endingDelimiter" value="`" />
<commentGenerator>
<property name="suppressDate" value="true" />
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 必须要有的,使用这个配置链接数据库 @TODO:是否可以扩展 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/userlucene" userId="root" password="123456">
<!-- 这里面可以设置property属性,每一个property属性都设置到配置的Driver上 -->
</jdbcConnection>
<!-- java类型处理器 用于处理DB中的类型到Java中的类型,默认使用JavaTypeResolverDefaultImpl; 注意一点,默认会先尝试使用Integer,Long,Short等来对应DECIMAL和
NUMERIC数据类型; -->
<javaTypeResolver
type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
<!-- true:使用BigDecimal对应DECIMAL和 NUMERIC数据类型 false:默认, scale>0;length>18:使用BigDecimal;
scale=0;length[10,18]:使用Long; scale=0;length[5,9]:使用Integer; scale=0;length<5:使用Short; -->
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- java模型创建器,是必须要的元素 负责:1,key类(见context的defaultModelType);2,java类;3,查询类
targetPackage:生成的类要放的包,真实的包受enableSubPackages属性控制; targetProject:目标项目,指定一个存在的目录下,生成的内容会放到指定目录中,如果目录不存在,MBG不会自动建目录 -->
<javaModelGenerator targetPackage="UserLucene.domain"
targetProject="src/main/java">
<!-- for MyBatis3/MyBatis3Simple 自动为每一个生成的类创建一个构造方法,构造方法包含了所有的field;而不是使用setter; -->
<property name="constructorBased" value="false" />
<!-- for MyBatis3 / MyBatis3Simple 是否创建一个不可变的类,如果为true, 那么MBG会创建一个没有setter方法的类,取而代之的是类似constructorBased的类 -->
<property name="immutable" value="false" />
<!-- 设置是否在getter方法中,对String类型字段调用trim()方法 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成SQL map的XML文件生成器, 注意,在Mybatis3之后,我们可以使用mapper.xml文件+Mapper接口(或者不用mapper接口),
或者只使用Mapper接口+Annotation,所以,如果 javaClientGenerator配置中配置了需要生成XML的话,这个元素就必须配置
targetPackage/targetProject:同javaModelGenerator
targetProject="src/main/java-->
<sqlMapGenerator targetPackage="mapper"
targetProject="src/main/resources">
<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 对于mybatis来说,即生成Mapper接口,注意,如果没有配置该元素,那么默认不会生成Mapper接口 targetPackage/targetProject:同javaModelGenerator
type:选择怎么生成mapper接口(在MyBatis3/MyBatis3Simple下): 1,ANNOTATEDMAPPER:会生成使用Mapper接口+Annotation的方式创建(SQL生成在annotation中),不会生成对应的XML;
2,MIXEDMAPPER:使用混合配置,会生成Mapper接口,并适当添加合适的Annotation,但是XML会生成在XML中; 3,XMLMAPPER:会生成Mapper接口,接口完全依赖XML;
注意,如果context是MyBatis3Simple:只支持ANNOTATEDMAPPER和XMLMAPPER -->
<javaClientGenerator targetPackage="UserLucene.mapper"
type="XMLMAPPER" targetProject="src/main/java">
<!-- 在targetPackage的基础上,根据数据库的schema再生成一层package,最终生成的类放在这个package下,默认为false -->
<property name="enableSubPackages" value="true" />
<!-- 可以为所有生成的接口添加一个父接口,但是MBG只负责生成,不负责检查 <property name="rootInterface"
value=""/> -->
</javaClientGenerator>
<table tableName="user" >
<!-- 参考 javaModelGenerator 的 constructorBased属性 -->
<property name="constructorBased" value="false" />
<generatedKey column="id" sqlStatement="JDBC" />
</table>
</context>
</generatorConfiguration>
IKAnalyzer.cfg.xml(检索库)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<comment>IK Analyzer 扩展配置</comment>
<!--用户可以在这里配置自己的扩展字典 -->
<entry key="ext_dict">ext.dic;</entry>
<!--用户可以在这里配置自己的扩展停止词字典-->
<entry key="ext_stopwords">stopword.dic;</entry>
</properties>
log4j.properties
# Global logging configuration
log4j.rootLogger=INFO, stdout
# MyBatis logging configuration...
log4j.logger.UserLucene.mapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--启用延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--禁用积极延迟加载-->
<setting name="aggressiveLazyLoading" value="false"/>
<!--延迟加载触发的方法-->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode"/>
<!--日志管理-->
<setting name="logImpl" value="LOG4J"/>
<!-- 启用mybatis二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!-- 使用mysql方言 -->
<property name="helperDialect" value="mysql"/>
<!-- 当传入的当pageSize为0时,不查询所有(默认为查询所有) -->
<property name="pageSizeZero" value="true"/>
</plugin>
</plugins>
</configuration>
测试层
userTest
package UserTest;
import UserLucene.domain.User;
import UserLucene.service.IUserService;
import com.alipay.api.domain.Data;
import org.apache.lucene.document.DateTools;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class userTest {
@Autowired
private IUserService userservice;
@Test
public void insertUser() throws IOException, ParseException {
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date=new Date();
String d=sdf.format(date);
User u=new User();
u.setPhone("人生不过如此 长城长江");
// u.setCreatetime(new Date());
// u.setBirthday(new Date());
u.setSex("女");
u.setId(16L);
u.setPassword("按钮事件太多,人员太少,根本弄不过来");
userservice.insert(u);
}
}
前端页面:
index.jsp
<!DOCTYPE html>
<html lang="en">
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<head>
<meta charset="utf-8">
<meta name="description" content="12">
<meta name="author" content="12">
<meta name="keyword" content="12">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>首页</title>
<link rel="stylesheet" type="text/css" href="asset/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="asset/css/plugins/font-awesome.min.css"/>
<link rel="stylesheet" type="text/css" href="asset/css/plugins/simple-line-icons.css"/>
<link rel="stylesheet" type="text/css" href="asset/css/plugins/animate.min.css"/>
<link rel="stylesheet" type="text/css" href="asset/css/plugins/fullcalendar.min.css"/>
<link href="asset/css/style.css" rel="stylesheet">
</head>
<body id="mimin" class="dashboard">
<!-- start: Header -->
<nav class="navbar navbar-default header navbar-fixed-top">
<div class="col-md-12 nav-wrapper">
<div class="navbar-header" style="width:100%;">
<div class="opener-left-menu is-open">
<span class="top"></span>
<span class="middle"></span>
<span class="bottom"></span>
</div>
<a href="index.html" class="navbar-brand"> <b>首页</b> </a>
<ul class="nav navbar-nav navbar-right user-nav">
<li class="user-name"><span>洲洲</span></li>
<li class="dropdown avatar-dropdown">
<img src="asset/img/avatar.jpg" class="img-circle avatar" alt="user name" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true"/>
<ul class="dropdown-menu user-dropdown">
<li><a href="#"><p value="洲洲" id="backli" onclick="back()"><span class="fa fa-power-off"></span> 退出登录</p></a></li>
</ul>
</li>
</ul>
</div>
</div>
</nav>
<!-- end: Header -->
<div class="container-fluid mimin-wrapper">
<!-- start:Left Menu -->
<div id="left-menu">
<div class="sub-left-menu scroll">
<ul class="nav nav-list">
<li>
<div class="left-bg"></div>
</li>
<li class="active ripple">
<a class="tree-toggle nav-header"><span class="fa-home fa"></span> 首页
<span class="fa-angle-right fa right-arrow text-right"></span>
</a>
</li>
<li class="ripple">
<a class="tree-toggle nav-header"><p id="leveljudge" value="" onclick="leveljudge()"> <span class="fa-diamond fa"></span> 用户管理
<span class="fa-angle-right fa right-arrow text-right"></span> </p>
</a>
<ul class="nav nav-list tree">
<li id="leveljudge1"><a href="userlist.html">用户列表</a></li>
</ul>
</li>
<li class="ripple">
<a class="tree-toggle nav-header"><span class="fa fa-check-square-o"></span> 新闻管理
<span class="fa-angle-right fa right-arrow text-right"></span>
</a>
<ul class="nav nav-list tree">
<li><a href="newslist.html">新闻列表</a></li>
<li><a href="newsupload.html">发表新闻</a></li>
</ul>
</li>
</ul>
</div>
</div>
<!-- end: Left Menu -->
<!-- start: content -->
<div id="content">
<div class="panel">
<div class="panel-body">
<div class="col-md-6 col-sm-12">
<h3 class="animated fadeInLeft">欢迎您:洲洲</h3>
<p class="animated fadeInDown"><span class="fa fa-map-marker"></span> 首页</p>
</div>
</div>
</div>
<div class="col-md-12" style="padding:20px;">
<div class="col-md-12 padding-0">
<div class="col-md-8 padding-0">
<div class="col-md-12 padding-0">
<div class="col-md-6">
<div class="panel box-v1">
<div class="panel-heading bg-white border-none">
<div class="col-md-6 col-sm-6 col-xs-6 text-left padding-0">
<h4 class="text-left">最新新闻</h4>
</div>
<div class="col-md-6 col-sm-6 col-xs-6 text-right">
<h4> <span class="icon-user icons icon text-right"></span> </h4>
</div>
</div>
<div class="panel-body text-center">
<ul class="normal-list">
<li class="text-left"><span class="right"> 2019—03-29</span><a href="#">巨浪3实验成功<span class="fa fa-angle-right"></span></a></li>
<li class="text-left"><span class="right"> 2019—03-29</span><a href="#">巨浪3实验成功<span class="fa fa-angle-right"></span></a></li>
<li class="text-left"><span class="right"> 2019—03-29</span><a href="#">巨浪3实验成功<span class="fa fa-angle-right"></span></a></li>
<li class="text-left"><span class="right"> 2019—03-29</span><a href="#">巨浪3实验成功<span class="fa fa-angle-right"></span></a></li>
</ul>
<p><a href="#">更多信息</a></p>
<hr/>
</div>
</div>
</div>
<div class="col-md-6">
<div class="panel box-v1">
<div class="panel-heading bg-white border-none">
<div class="col-md-6 col-sm-6 col-xs-6 text-left padding-0">
<h4 class="text-left">热论新闻</h4>
</div>
<div class="col-md-6 col-sm-6 col-xs-6 text-right">
<h4> <span class="icon-check icons icon text-right"></span> </h4>
</div>
</div>
<div class="panel-body text-center">
<ul class="normal-list">
<li class="text-left"><span class="right">2019-03-29</span><a href="#"><span class="fa fa-angle-right">中国乒乓球队成功卫冕</span> </a></li>
<li class="text-left"><span class="right">2019-03-29</span><a href="#"><span class="fa fa-angle-right">中国乒乓球队成功卫冕</span> </a></li>
<li class="text-left"><span class="right">2019-03-29</span><a href="#"><span class="fa fa-angle-right">中国乒乓球队成功卫冕</span> </a></li>
<li class="text-left"><span class="right">2019-03-29</span><a href="#"><span class="fa fa-angle-right">中国乒乓球队成功卫冕</span> </a></li>
</ul>
<p><a href="#">更多信息</a></p>
<hr/>
</div>
</div>
</div>
</div>
</div>
<div class="col-md-4">
<div class="col-md-12 padding-0">
<div class="panel box-v2">
<div class="panel-heading padding-0"> <img src="asset/img/bg2.jpg" class="box-v2-cover img-responsive"/>
<div class="box-v2-detail"> <img src="asset/img/avatar.jpg" class="img-responsive"/>
<h4>洲洲</h4>
</div>
</div>
<div class="panel-body">
<div class="col-md-12 padding-0 text-center">
<div class="col-md-4 col-sm-4 col-xs-6 padding-0">
<h3>2000</h3>
<p>已发布新闻</p>
</div>
<div class="col-md-4 col-sm-4 col-xs-6 padding-0">
<h3>1000</h3>
<p>粉丝</p>
</div>
<div class="col-md-4 col-sm-4 col-xs-6 padding-0">
<h3>1000</h3>
<p>评论数</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- end: content -->
</div>
<!-- start: Javascript -->
<script src="asset/js/jquery.min.js"></script>
<script src="asset/js/jquery.ui.min.js"></script>
<script src="asset/js/bootstrap.min.js"></script>
<!-- plugins -->
<script src="asset/js/plugins/jquery.nicescroll.js"></script>
<!-- custom -->
<script src="asset/js/main.js"></script>
<script src="asset/js/moment.js"></script>
<script src="js/Confim.js"></script>
<!-- end: Javascript -->
</body>
</html>
load.jsp登录界面
<!DOCTYPE html>
<html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String username =request.getParameter("username");
application.setAttribute("user",username);
%>
<head>
<title>登陆</title>
<meta charset="utf-8">
<link href="css/style.css" rel='stylesheet' type='text/css' />
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="js/login.js"></script>
</head>
<body>
<div class="main">
<div class="login-form">
<h1>用户登陆</h1>
<div class="head">
<img src="images/user.png" alt=""/>
</div>
<form action="LoadFilterServlet" method="post">
<input type="text" id="username" class="text" value="用户名" name="username">
<input type="text" id="password" name="password" value="密码">
<input type="password" id="password1" name="password1" value="password" style="display: none;">
<div class="submit">
<input type="submit" value="登陆">
</div>
<p>
<a href="#">忘记密码 ?</a>
<a href="login.jsp">注册</a>
</p>
</form>
</div>
<!--//End-login-form-->
<div class="copy-right">
<p><a> Copyright © 2018</a></p>
</div>
</div>
<!-----//end-main---->
</body>
</html>
login.jsp注册页面
<!DOCTYPE html>
<html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<head>
<title>注册</title>
<meta charset="utf-8">
<link href="css/style.css" rel='stylesheet' type='text/css' />
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="js/login.js"></script>
</head>
<body>
<div class="main">
<div class="login-form">
<h1>用户注册</h1>
<div class="head">
<img src="images/user.png" alt=""/>
</div>
<form action="LoginServlet" method="post">
<input type="text" id="username" class="text" value="用户名" name="username">
<input type="text" id="password" name="password" value="密码">
<input type="password" id="password1" name="password1" style="display: none;">
<input type="text" id="password2" name="password2" value="确认密码">
<input type="password" id="password3" name="password3" style="display: none;">
<input type="text" name="tel" value="手机号" id="telephone">
<p class="p1">性别:
<input type="radio" name="sex" class="sex" value="男">男
<input type="radio" name="sex" class="sex" value="女">女
</p>
<input type="text" name="birthday" class="text" value="生日日期" id="birthday">
<div class="submit">
<input type="submit" value="注册">
</div>
<p>
<a href="#">忘记密码 ?</a>
<a href="load.jsp">登陆</a>
</p>
</form>
</div>
<!--//End-login-form-->
<div class="copy-right">
<p><a href=""> Copyright © 2018</a></p>
</div>
</div>
<!-----//end-main---->
</body>
</html>
page.jsp分页页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<script type="text/javascript" href="js/jquery-3.3.1.min.js"></script>
<script type="text/javascript">
function go(pageno){
// document.getElementById("currentpage").value=pageno;
var keyword=document.getElementById("keyword").value;
// console.log(pageno)
// document.forms[0].submit();
window.location.href="/PageResult?currentPage="+pageno+"&&keyword="+keyword
}
function go2() {
var keyword=document.getElementById("keyword").value;
var pageno=document.getElementById("currentpage").value;
window.location.href="/PageResult?currentPage="+pageno+"&&keyword="+keyword
}
function go3() {
var keyword=document.getElementById("keyword").value;
var pageno=document.getElementById("currentpage").value;
var pageSize=document.getElementById("pageSize").value;
window.location.href="/PageResult?currentPage="+pageno+"&&keyword="+keyword+"&&pageSize="+pageSize
}
</script>
</head>
<body>
<h1>商品信息</h1>
<form action="/PageResult" method="post">
关键字查询:<input type="text" id="keyword" name="keyword" value="${qo.keyword}" /><br>
<input type="submit" value="查询"/>
<br>
<table cellpadding="0" cellspacing="0" border="1" width="80%">
<tr style="background-color:orange;">
<th>用户id</th>
<th>用户密码</th>
<th>用户手机</th>
<th>性别</th>
<%--<th>生日</th>--%>
<%--<th>登录时间</th>--%>
<%--<th>成本价</th>--%>
<%--<th>折扣</th>--%>
<%--<th>操作</th>--%>
</tr>
<c:forEach items="${pageresult.data}" var="item" varStatus="vs">
<tr style="background-color:${vs.count%2==0?'pink':''};">
<td>${item.id}</td>
<td>${item.password}</td>
<td>${item.phone}</td>
<td>${item.sex}</td>
<%--<td>${item.birthday}</td>--%>
</c:forEach>
</tr>
<tr>
<td colspan="9" align="center">
<a href="javascript:go(1);">首页</a>
<a href="javascript:go(${pageresult.lastpage });">上一页</a>
<c:forEach begin="${pageresult.beginIndex }" end="${pageresult.endIndex }" var="pagenumber">
<c:if test="${pagenumber!=pageresult.currentpage }">
<a href="javascript:go(${pagenumber });">${pagenumber}</a>
</c:if>
<c:if test="${pagenumber==pageresult.currentpage }">
<span style="color:red;font:italic bold;">
${pagenumber }
</span>
</c:if>
</c:forEach>
<a href="javascript:go(${pageresult.nextpage });">下一页</a>
<a href="javascript:go(${pageresult.endpage });">尾页</a>
当前第${pageresult.currentpage }页,一共${pageresult.endpage }页,共${pageresult.totalcount }数据
跳转到第<input name="currentpage" id="currentpage" type="number" min="1" max="${pageresult.endpage }" value="${pageresult.currentpage }"/>页
<input type="button" value="GO" onclick="go2();"/>
每页
<select name="pageSize" id="pageSize" onchange="go3();">
<c:forEach items="${pageresult.pagedata}" var="item">
<option ${item==pageresult.pagesize?"selected":"" }>${item }</option>
</c:forEach>
</select>
条数据
</td>
</tr>
</table>
</form>
</body>
</html>
具体实现效果: