0%

pom.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
<!-- 修改后立即生效,热部署 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>

第二步:2002,2003的主啟動類EurekaServerApplication_2002,EurekaServerApplication_2003複製下

第三步:直接改端口不同,來區別是什麼

第四步:
之前的2001

1
2
3
4
5
6
7
8
9
10
11
12
13
 server:
port:2001
context-path:/
eurka:
instance:
hostname:locahost #eureka註冊中心名稱
hostname:eureka2001.java1234.com #集群
client:
register-with-eureka:false (不能自己註冊自己)
fetch-registry:false 由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为false
service-url:
defaltZone:http://${eurka.instance.hostname}:${service.port}/eureka #设置与Eureka注册中心交互的地址,查询服务和注册服务用到
defaltZone: http://eureka2002.java1234.com:2002/eureka http://eureka2003.java1234.com:2003/eureka #集群版

2002修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server:

port: 2002

context-path: /



eureka:

instance:

# 单机 hostname: localhost #eureka注册中心实例名称

hostname: eureka2002.java1234.com # 集群

client:

register-with-eureka: false #false 由于该应用为注册中心,所以设置为false,代表不向注册中心注册自己。

fetch-registry: false #false 由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为false

service-url:

defaltZone: http://eureka2001.java1234.com:2001/eureka http://eureka2003.java1234.com:2003/eureka #集群版

2003修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
server:

port: 2003

context-path: /

eureka:

instance:

# 单机 hostname: localhost #eureka注册中心实例名称

hostname: eureka2003.java1234.com # 集群

client:

register-with-eureka: false #false 由于该应用为注册中心,所以设置为false,代表不向注册中心注册自己。

fetch-registry: false #false 由于注册中心的职责就是维护服务实例,它并不需要去检索服务,所以也设置为false

service-url:

defaltZone: http://eureka2001.java1234.com:2001/eureka http://eureka2002.java1234.com:2002/eureka #集群版

第五部:修改服務提供者項目application.yml,主要修改eureka.client.service-url.defaultZone

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
server:

port: 1001

context-path: /

eureka:

instance:

hostname: localhost #eureka客户端主机实例名称

appname: microservice-student #客户端服务名

instance-id: microservice-student:1001 #客户端实例名称

prefer-ip-address: true #显示IP

client:

service-url:

# 单机 defaultZone: http://localhost:2001/eureka #把服务注册到eureka注册中心

defaultZone: http://eureka2001.java1234.com:2001/eureka/,http://eureka2002.java1234.com:2002/eureka/,http://eureka2003.java1234.com:2003/eureka/ # 集群

这里本质是三个服务注册中心都有我们服务提供者的信息,等后面讲到服务发现和服务调用,我们通过一些策略(默认轮询),会去找对应的服务注册中心;通过集群,能减轻每个服务注册中心的压力;

Restful是一种资源,

  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)。
  • DELETE(DELETE):从服务器删除资源。
  • 状态码
  • 200 OK – [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
  • 201 CREATED – [POST/PUT/PATCH]:用户新建或修改数据成功。
  • 202 Accepted – [*]:表示一个请求已经进入后台排队(异步任务)
  • 204 NO CONTENT – [DELETE]:用户删除数据成功。
  • 400 INVALID REQUEST – [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
  • 401 Unauthorized – [*]:表示用户没有权限(令牌、用户名、密码错误)。
  • 403 Forbidden – [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
  • 404 NOT FOUND – [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
  • 406 Not Acceptable – [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
  • 410 Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
  • 422 Unprocesable entity – [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
  • 500 INTERNAL SERVER ERROR – [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

rest API 10条规范; 流程——》》按照下面的流程记住,这样方便记忆。
https》》》域名》》版本》》名词》》url后可加条件,条件里面可加分页》》》》methods做请求》》return状态码,有错误信息发错误信息》》
返回值》》》headlink(这个是啥,不太确定)

1创建个文件夹
mkdir 文件夹的名字
2.查看目录下的文件
ls
ls lh 查看详细信息
3.编辑命令
vi 文件夹路径下的名字
4退出保存
点击esc 退出编辑模式,在写:wq 按enter退出
5.查看文件
cat 文件夹的名字
6.复制文件夹到另一个地方
mv 复制夹的路径路径 目标路径的路径
7.查看命令执行的最后几条
tail -f 文件夹的名字
8.拷贝文件
cp 源文件 目标文件
9.删除文件
rm -r 文件夹的路径
rm -rf 文件夹的路径
10.文件打包压缩
tar -cvf 文件的名字
11.解压
gzip -d 文件的名字
12.网络服务启动
service -status -all
service servicename start
13.查看指定服务运行状态
service servicename status
14.停止服务
service servicename stop
15.关闭防火墙服务
service iptables stop
16.关闭防火墙自动启动
chkconfig iptables off
17.退到上一步
cd. 目标编辑
cd.. 退出跟目录

单点登录是有两种解决方案。一种是cooike跨域登录.一种是cas登录。
cookie原理如下:

  1. 用户在应用系统1准备登录,拦截他所有的地址栏,检测他的页面是否有ticket,如果没有,就让他跳转到认证系统。
  2. 第一次登录时用 用户名-密码登录,返回一个ticket,setdomain跳转到跳转到认证系统,setpath跳转到/.
  3. 把这个ticke传到cookie里,并且跳转到系统1的main.jsp.
  4. 他在点击到应用系统2,那ticket去验证,验证有就通过。

创建zookeeper的过程:

解压到指定目录下F:\zookeeper
F:\zookeeper\conf下的zoo_sample.cfg重命名为 zoo.cfg
主要修改一下日志位置,具体配置文件如下:

1
2
dataDir=F:\\zookeeper\\data  
dataDirLog=F:\\zookeeper\\log

四、启动
1 进入到bin目录,并且启动zkServer.cmd,这个脚本中会启动一个java进程
创建dubbo的过程:
按照常理,直接去 https://github.com/alibaba/dubbo 下载,然后进入下面的dubbo-admin目录,进行mvn打包即可,但是不知道为何,却找不到dubbo-admin这个目录。
那就直接去下载他们打包好的源代码吧:https://github.com/alibaba/dubbo/releases
之后放在elipse打包,其中要加上

1
2
3
4
5
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
</dependency>

确保dubb的这些地方都是正确的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<!– <version>${project.parent.version}</version> –>
<version>2.6.0</version>
</dependency>
这里在是指maven打包的。
<build>
<plugins>
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>3.2.4</version>
<configuration>
<contextPath>/</contextPath>
<scanIntervalSeconds>10</scanIntervalSeconds>
<connectors>
<connector implementation=”org.mortbay.jetty.nio.SelectChannelConnector”>
<port>8080</port>
<maxIdleTime>60000</maxIdleTime>
</connector>
</connectors>
</configuration>
</plugin>
</plugins>
</build>

将ROOT文件放入tomcat/webapps下,替换tomcata自带的ROOT,启动tomcat,打开网址
http://localhost:8080/,账户名、密码都是root,点击服务治理->提供者,这里就可以看到dubbo发布的provider详细信息

由于我是利用SessionFactory调用存储过程,故说明一下。结合笔记中的存储过程–MySQL存储过程实现动态执行SQL进行理解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//此处的10表示s_device0,s_device1,…s_device10,
//s_device表示数据库的表名
int detotal=procedureService.savetotal(10, “s_device”);
下面是dao的调用
@Repository
public class ProcedureDaoImpl<T> extends BaseDao<T> implements IProcedureDao{
@Override
public int savetotal(int count, String str) {
String procedure_name=“query_deviceCount”; //存储过程的名字
ProcedureCall query =this.getSession().createStoredProcedureCall(procedure_name);
//存入的字段 ParameterMode.IN表示存进来的参数值,ParameterMode.OUT最后执行完这个参数获得数值。
query.registerParameter(“p_num”, Integer.class, ParameterMode.IN).bindValue(count);
query.registerParameter(“p_strs”,String.class, ParameterMode.IN).bindValue(str);
query.registerParameter(“p_count”, Integer.class, ParameterMode.OUT);
System.out.println(query.getOutputs()); //获取执行存储过程最后输出的参数
return (int) query.getOutputs().getOutputParameterValue(“p_count”); //数据库输出参数的名字
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
//以前的方法加上这两句

function first_click(){
$(“.i_box”).first().parent(‘span’).find(“div span.ap”).text(“序号1”);
$(“.i_box”).first().parent(‘span’).find(“div span.ap”).addClass(“ab”+1);
}

//点击时出现序号

function i_box_click(){
$(“.i_box”).on(“click”,function(){
var this_toggle = $(this).attr(“is_toggle”);
var i = $(this).parent(‘span’).next(‘ul’).find(“ul”);
if (this_toggle == ‘true’) {
$(this).parent(‘span’).next(‘ul’).slideUp();
$(this).parent(‘span’).next(‘ul’).find(“ul”).slideDown();
$(this).attr(“is_toggle”, “false”);
$(this).find(‘i’).removeClass(“fa fa-plus-circle fa-minus-circle”);
$(this).find(‘i’).addClass(“fa fa-plus-circle”);

} else {
$(this).parent(‘span’).next(‘ul’).slideDown();
$(this).parent(‘span’).next(‘ul’).find(“ul”).slideUp();
$(this).attr(“is_toggle”, “true”);
$(this).find(‘i’).removeClass(“fa fa-plus-circle fa-minus-circle”);
$(this).find(‘i’).addClass(“fa fa-minus-circle”);
var index = $(this).parent(‘span’).find(“div span.ap”).attr(“class”).indexOf(“ab”);
var zimu = $(this).parent(‘span’).find(“div span.ap”).attr(“class”).replace(/[^\d]/g,””);
if(index>1){
var number = parseInt(zimu) + 1;
$(this).parent(‘span’).next(‘ul’).find(“li”).find(“span”).find(“div span.ap”).text(“序号”+number);
$(this).parent(‘span’).next(‘ul’).find(“li”).find(“span”).find(“div span.ap”).removeClass(“ab”+zimu);
$(this).parent(‘span’).next(‘ul’).find(“li”).find(“span”).find(“div span.ap”).addClass(“ab”+number);
}
}

});
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
unction i_box_click(){
$(“.i_box”).on(“click”,function(){
var this_toggle = $(this).attr(“is_toggle”);
var i = $(this).parent(‘span’).next(‘ul’).find(“ul”);
if (this_toggle == ‘true’) {
$(this).parent(‘span’).next(‘ul’).slideUp();
$(this).parent(‘span’).next(‘ul’).find(“ul”).slideDown();
$(this).attr(“is_toggle”, “false”);
$(this).find(‘i’).removeClass(“fa fa-plus-circle fa-minus-circle”);
$(this).find(‘i’).addClass(“fa fa-plus-circle”);

} else {
$(this).parent(‘span’).next(‘ul’).slideDown();
$(this).parent(‘span’).next(‘ul’).find(“ul”).slideUp();
$(this).attr(“is_toggle”, “true”);
$(this).find(‘i’).removeClass(“fa fa-plus-circle”);

}

function first_click(){
var this_toggle = $(“.i_box”).first().attr(“is_toggle”);
$(“.i_box”).first().parent(‘span’).next(‘ul’).slideUp();
$(“.i_box”).first().attr(“is_toggle”, “true”);
$(“.i_box”).first().find(‘i’).removeClass(“fa fa-plus-circle fa-minus-circle”);
$(“.i_box”).first().find(‘i’).addClass(“fa fa-plus-circle”);
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
var truedata = [{
"id": 10,
"userName": "13076994079@163.com",
"children": [],
},
{
"id": 1,
"userName": "11111111111",
"children": [{
"id": 10067,
"userName": "11111111111",
"accountNonTrade": null,
},
{
"id": 69,
"userName": "222222",
"accountNonTrade": null,
}
],
},
{
"id": 2,
"userName": "333333333",
"children": [{
"id": 55,
"userName": "444444444",
"accountNonTrade": null,
"children": [],

},
{
"id": 56,
"userName": "4444443",
"children": [],
}
],
},

]

导入的css样式:

1
<link href=”https://cdn.bootcss.com/font-awesome/5.8.1/css/all.css” rel=”stylesheet”>

使用的css样式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
<style>
ul,
li {
list-style-type: none;
}

.tree {
width: 100%;
min-height: 100%;
overflow: scroll;
display: block;
position: relative;
padding: 5px 15px;
}

.tree p {
margin: 3px 0;
text-align: left;
}

.tree i {
font-style: normal;
}

.tree .i_box {
height: 28px;
text-align: right;
}

.tree span {
display: inline-block;
box-sizing: border-box;
line-height: 28px;
min-width: 60px;
text-align: center;
color: #888;
border: 1px solid #ddd;
border-radius: 5px;
padding: 0 8px;
}

.tree ul {
position: relative;
padding-left: 60px;
margin: 0;
}

.tree ul>li {
position: relative;
padding: 5px 0;
}

.tree>ul {
padding: 0;
margin: 0;
}
/** 水平方向连线 */

.tree>ul ul>li:after {
content: ‘ ‘;
position: absolute;
top: 20px;
left: -45px;
width: 45px;
border: none;
border-top: 1px solid #ddd;
}
/** 垂直方向连线 */

.tree ul>li:not(:last-child):before {
content: ‘ ‘;
position: absolute;
top: 0;
left: -45px;
height: 100%;
border: none;
border-left: 1px solid #ddd;
}

.tree ul>li:last-child:before {
content: ‘ ‘;
position: absolute;
top: 0;
left: -45px;
height: 20px;
border: none;
border-left: 1px solid #ddd;
}
/** 控制鼠标移上去的颜色 */

.tree span:hover,
.tree span:hover+ul span {
color: #fff;
background-color: orange;
}

.tree span:hover,
.tree span:hover+ul span,
.tree span:hover+ul li:before,
.tree span:hover+ul li:after {
border-color: orange;
}
/** 折叠图标 */

.tree .fa:before {
margin-right: 5px;
}

.tree .fa-minus-circle,
.tree .fa-plus-circle {
cursor: pointer;
}
</style>

1.font-size:字号大小

2.font-family:字体

常用技巧:

  1. 现在网页中普遍使用14px+。
  2. 尽量使用偶数的数字字号。ie6等老式浏览器支持奇数会有bug。
  3. 各种字体之间必须使用英文状态下的逗号隔开。
  4. 中文字体需要加英文状态下的引号,英文字体一般不需要加引号。当需要设置英文字体时,英文字体名必须位于中文字体名之前。
  5. 如果字体名中包含空格、#、$等符号,则该字体必须加英文状态下的单引号或双引号,例如font-family: “Times New Roman”;。
  6. 尽量使用系统默认字体,保证在任何用户的浏览器中都能正确显示。
字体名称 英文名称 Unicode 编码
宋体 SimSun \5B8B\4F53
新宋体 NSimSun \65B0\5B8B\4F53
黑体 SimHei \9ED1\4F53
微软雅黑 Microsoft YaHei \5FAE\8F6F\96C5\9ED1
楷体_GB2312 KaiTi_GB2312 \6977\4F53_GB2312
隶书 LiSu \96B6\4E66
幼园 YouYuan \5E7C\5706
华文细黑 STXihei \534E\6587\7EC6\9ED1
细明体 MingLiU \7EC6\660E\4F53
新细明体 PMingLiU \65B0\7EC6\660E\4F53

font-weight:字体粗细

font-style:字体风格

font-style属性用于定义字体风格,如设置斜体、倾斜或正常字体,其可用属性值如下:

normal:默认值,浏览器会显示标准的字体样式。

italic:浏览器会显示斜体的字体样式。

oblique:浏览器会显示倾斜的字体样式。

选择器{font: font-style font-weight font-size/line-height font-family;}

例子上手:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>
<style>
h2 {
font-size: 30px;
color: pink;
font-family: “Microsoft YaHei”,tahoma,arial,”Hiragino Sans GB”;
}
h4 {
color: purple;

/* font-size: 14px; 这是14号字体

font-family: “微软雅黑”;
font-style: italic; 让字体倾斜 */

/* font: italic bold 14px “微软雅黑” ; font 综合写法 更简洁 */
font: 14px “微软雅黑” ; /* 但必须保留font-size和font-family属性,否则font属性将不起作用 */
}
p {
font-size: 14px;
font-family: “\9ED1\4F53”; /* 这是unicode 黑体字体 */

}
span {
font-weight: 700; /* 字体加粗的效果 */
}
strong {
font-weight: normal; /* 让粗体变的不加粗 */
}
em {
font-style: normal; /* 让斜体变的不倾斜 */
color: green;
}
</style>
</head>
<body>
<!– 这是html 注释 ctrl + / –>
<h2>企业简介</h2>
<h4>公司由来</h4>
<p><span>北京传智播客教育科技有限公司</span>(简称传智播客)是一家专门致力于高素质软件开发人才培养的高科技公司。<strong>传智播客</strong>致力于为企业优选一流的人才的培训理念,以“学员自学入门教程,通过基础考核后进行强化培训”为招生原则,以“针对企业需求,重视基础理论建设,强化高端应用技能”为教学目标,以“高薪保证强大的资深教育团队”为教学后盾,彻底解决所有培训学员的后顾之忧,并解决用人企业难以招聘到合格人才的困扰。</p>

<h4>公司发展</h4>

<p><em>传智播客</em>为了将更优质的教育资源惠及更多学子,经过多年的教学探索及战略布局,已向着综合型职业教育集团发展,目前旗下已涵盖传智播客IT教育培训,黑马程序员训练营及博学谷三大子品牌。现直营分校已遍布北京、上海、广州、深圳、武汉、郑州、西安、哈尔滨、长沙、济南等一线城市及省会城市,并将逐步在其他省会城市开始直营分校,让学员可以离高薪更近一点。</p>

<h4>课程安排</h4>

<p>经过10年的专业积淀,<em>传智播客</em>一直专注培养Android、iOS、Java、C/C++、PHP、UI设计、游戏开发、大数据、网络营销、前端与移动开发等泛IT领域的应用工程师,并向社会输送了数10万泛IT行业的高级人才,其中90%以上的学员都在北、上、广、深等一线城市高薪就业。有效的解决了当下互联网行业飞速发展,高端人才供不应求的难题,并且带动了整个IT产业的发展。</p>

<p><em>传智播客</em>精益求精的教学品质,也赢得了学员口口相传,这也使得传智播客稳居国内IT培训的领先地位。</p>
</body>
</html>

CSS初识

CSS(Cascading Style Sheets)

CSS通常称为CSS样式表或层叠样式表(级联样式表),主要用于设置HTML页面中的文本内容(字体、大小、对齐方式等)、图片的外形(宽高、边框样式、边距等)以及版面的布局等外观显示样式。

CSS以HTML为基础,提供了丰富的功能,如字体、颜色、背景的控制及整体排版等,而且还可以针对不同的浏览器设置不同的样式。

使用HTML时,需要遵从一定的规范。CSS亦如此,要想熟练地使用CSS对网页进行修饰,首先需要了解CSS样式规则,具体格式如下:

在上面的样式规则中:

  1. 选择器用于指定CSS样式作用的HTML对象,花括号内是对该对象设置的具体样式。
  2. 属性和属性值以“键值对”的形式出现。
  3. 属性是对指定的对象设置的样式属性,例如字体大小、文本颜色等。
  4. 属性和属性值之间用英文“:”连接。
  5. 多个“键值对”之间用英文“;”进行区分。

可以用段落 和 表格的对齐的演示。

1.搜索结果高亮显示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
String keywords = “钟福成”;
List<Article> articleList = new ArrayList<Article>();
QueryParser queryParser = new QueryParser(LuceneUtil.getVersion(),”content”,LuceneUtil.getAnalyzer());
Query query = queryParser.parse(keywords);
IndexSearcher indexSearcher = new IndexSearcher(LuceneUtil.getDirectory());
TopDocs topDocs = indexSearcher.search(query,1000000);
//设置关键字高亮
Formatter formatter = new SimpleHTMLFormatter(“<font color=’red’>”,”</font>”);
Scorer scorer = new QueryScorer(query);
Highlighter highlighter = new Highlighter(formatter,scorer);


//设置摘要
Fragmenter fragmenter = new SimpleFragmenter(4);
highlighter.setTextFragmenter(fragmenter);

for(int i=0;i<topDocs.scoreDocs.length;i++){
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
int no = scoreDoc.doc;
Document document = indexSearcher.doc(no);
//设置内容高亮
String highlighterContent = highlighter.getBestFragment(LuceneUtil.getAnalyzer(),”content”,document.get(“content”));
document.getField(“content”).setValue(highlighterContent);
Article article = (Article) LuceneUtil.document2javabean(document,Article.class);
articleList.add(article);
}
for(Article article : articleList){
System.out.println(article);
}

1.IKAnalyzer分词器(中文分词器)

这是一个第三方的分词器,我们如果要使用的话需要导入对应的jar包

  • IKAnalyzer3.2.0Stable.jar
  • 步二:将IKAnalyzer.cfg.xml和stopword.dic和xxx.dic文件复制到MyEclipse的src目录下,再进行配置,在配置时,首行需要一个空行

这个第三方的分词器有什么好呢????他是中文首选的分词器…也就是说:他是按照中文的词语来进行拆分的!

1.索引库优化代码
合并其过程:查出在文件下有多少的cfs,然后在写上总数count
//索引库优化
indexWriter.optimize();
//设置合并因子为3,每当有3个cfs文件,就合并
indexWriter.setMergeFactor(count);
2.设置内存索引库
对于内存索引库而言,它的速度是很快的,因为我们直接操作内存…但是呢,我们要将内存索引库是要到硬盘索引库中保存起来的。当我们读取数据的时候,先要把硬盘索引库的数据同步到内存索引库中去的。

1
2
3
4
5
6
7
8
9
10
11
Article article = new Article(1,”培训”,”传智是一家Java培训机构”);
Document document = LuceneUtil.javabean2document(article);
Directory fsDirectory = FSDirectory.open(new File(“E:/indexDBDBDBDBDBDBDBDB”));
//硬盘索引库
Directory ramDirectory = new RAMDirectory(fsDirectory);
IndexWriter fsIndexWriter = new IndexWriter(fsDirectory,LuceneUtil.getAnalyzer(),true,LuceneUtil.getMaxFieldLength());
IndexWriter ramIndexWriter = new IndexWriter(ramDirectory,LuceneUtil.getAnalyzer(),LuceneUtil.getMaxFieldLength());
ramIndexWriter.addDocument(document);
ramIndexWriter.close();
fsIndexWriter.addIndexesNoOptimize(ramDirectory);
fsIndexWriter.close();

LuceneUtils工具类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import org.apache.commons.beanutils.BeanUtils;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
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.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* Created by ozc on 2017/7/12.
*/
/**
* 使用单例事例模式
* */
public class LuceneUtils {
private static Directory directory;
private static Analyzer analyzer;
private static IndexWriter.MaxFieldLength maxFieldLength;
private LuceneUtils() {}
static{
try {
directory = FSDirectory.open(new File(“E:/createIndexDB”));
analyzer = new StandardAnalyzer(Version.LUCENE_30);
maxFieldLength = IndexWriter.MaxFieldLength.LIMITED;
} catch (Exception e) {
e.printStackTrace();
}
}
public static Directory getDirectory() {
return directory;
}
public static Analyzer getAnalyzer() {
return analyzer;
}
public static IndexWriter.MaxFieldLength getMaxFieldLength() {
return maxFieldLength;
}
/**
* @param object 传入的JavaBean类型
* @return 返回Document对象
*/
public static Document javaBean2Document(Object object) {
try {
Document document = new Document();
//得到JavaBean的字节码文件对象
Class<?> aClass = object.getClass();
//通过字节码文件对象得到对应的属性【全部的属性,不能仅仅调用getFields()】
Field[] fields = aClass.getDeclaredFields();
//得到每个属性的名字
for (Field field : fields) {
String name = field.getName();
//得到属性的值【也就是调用getter方法获取对应的值】
String method = “get” + name.substring(0, 1).toUpperCase() + name.substring(1);
//得到对应的值【就是得到具体的方法,然后调用就行了。因为是get方法,没有参数】
Method aClassMethod = aClass.getDeclaredMethod(method, null);
String value = aClassMethod.invoke(object).toString();
System.out.println(value);
//把数据封装到Document对象中。
document.add(new org.apache.lucene.document.Field(name, value, org.apache.lucene.document.Field.Store.YES, org.apache.lucene.document.Field.Index.ANALYZED));
}
return document;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* @param aClass 要解析的对象类型,要用户传入进来
* @param document 将Document对象传入进来
* @return 返回一个JavaBean
*/
public static Object Document2JavaBean(Document document, Class aClass) {
try {
//创建该JavaBean对象
Object obj = aClass.newInstance();
//得到该JavaBean所有的成员变量
Field[] fields = aClass.getDeclaredFields();
for (Field field : fields) {
//设置允许暴力访问
field.setAccessible(true);
String name = field.getName();
String value = document.get(name);
//使用BeanUtils把数据封装到Bean中
BeanUtils.setProperty(obj, name, value);
}
return obj;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Test
public void test() {
User user = new User();
LuceneUtils.javaBean2Document(user);
}
}

使用LuceneUtils改造程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
@Test
public void createIndexDB() throws Exception {
//把数据填充到JavaBean对象中
User user = new User(“2”, “钟福成2”, “未来的程序员2”);
Document document = LuceneUtils.javaBean2Document(user);
/**
* IndexWriter将我们的document对象写到硬盘中
*
* 参数一:Directory d,写到硬盘中的目录路径是什么
* 参数二:Analyzer a, 以何种算法来对document中的原始记录表数据进行拆分成词汇表
* 参数三:MaxFieldLength mfl 最多将文本拆分出多少个词汇
*
* */
IndexWriter indexWriter = new IndexWriter(LuceneUtils.getDirectory(), LuceneUtils.getAnalyzer(), LuceneUtils.getMaxFieldLength());
//将Document对象通过IndexWriter对象写入索引库中
indexWriter.addDocument(document);
//关闭IndexWriter对象
indexWriter.close();
}
@Test
public void findIndexDB() throws Exception {
//创建IndexSearcher对象
IndexSearcher indexSearcher = new IndexSearcher(LuceneUtils.getDirectory());
//创建QueryParser对象
QueryParser queryParser = new QueryParser(Version.LUCENE_30, “userName”, LuceneUtils.getAnalyzer());
//给出要查询的关键字
String keyWords = “钟”;
//创建Query对象来封装关键字
Query query = queryParser.parse(keyWords);
//用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准
TopDocs topDocs = indexSearcher.search(query, 100);
//获取符合条件的编号
for (int i = 0; i < topDocs.scoreDocs.length; i++) {
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
int no = scoreDoc.doc;
//用indexSearcher对象去索引库中查询编号对应的Document对象
Document document = indexSearcher.doc(no);
//将Document对象中的所有属性取出,再封装回JavaBean对象中去
User user = (User) LuceneUtils.Document2JavaBean(document, User.class);
System.out.println(user);
}
}

步骤:
1)创建IndexSearcher对象
2)创建QueryParser对象
3)创建Query对象来封装关键字
4)用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准
5)获取符合条件的编号
6)用indexSearcher对象去索引库中查询编号对应的Document对象
7)将Document对象中的所有属性取出,再封装回JavaBean对象中去,并加入到集合中保存,以备将之用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
@Test
public void findIndexDB() throws Exception {
/**
* 参数一: IndexSearcher(Directory path)查询以xxx目录的索引库
*
* */
Directory directory = FSDirectory.open(new File(“E:/createIndexDB”));
//创建IndexSearcher对象
IndexSearcher indexSearcher = new IndexSearcher(directory);
//创建QueryParser对象
/**
* 参数一: Version matchVersion 版本号【和上面是一样的】
* 参数二:String f,【要查询的字段】
* 参数三:Analyzer a【使用的拆词算法】
* */
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
QueryParser queryParser = new QueryParser(Version.LUCENE_30, “userName”, analyzer);
//给出要查询的关键字
String keyWords = “钟”;
//创建Query对象来封装关键字
Query query = queryParser.parse(keyWords);
//用IndexSearcher对象去索引库中查询符合条件的前100条记录,不足100条记录的以实际为准
TopDocs topDocs = indexSearcher.search(query, 100);
//获取符合条件的编号
for (int i = 0; i < topDocs.scoreDocs.length; i++) {
ScoreDoc scoreDoc = topDocs.scoreDocs[i];
int no = scoreDoc.doc;
//用indexSearcher对象去索引库中查询编号对应的Document对象
Document document = indexSearcher.doc(no);
//将Document对象中的所有属性取出,再封装回JavaBean对象中去
String id = document.get(“id”);
String userName = document.get(“userName”);
String sal = document.get(“sal”);
User user = new User(id, userName, sal);
System.out.println(user);
}

步骤一:jar导入

lucene-core-3.0.2.jar【Lucene核心】
lucene-analyzers-3.0.2.jar【分词器】
lucene-highlighter-3.0.2.jar【Lucene会将搜索出来的字,高亮显示,提示用户】
lucene-memory-3.0.2.jar【索引库优化策略】
步骤二:
创建索引库的步骤:
1)创建JavaBean对象
2)创建Docment对象
3)将JavaBean对象所有的属性值,均放到Document对象中去,属性名可以和JavaBean相同或不同
4)创建IndexWriter对象
5)将Document对象通过IndexWriter对象写入索引库中
6)关闭IndexWriter对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@Test
public void createIndexDB() throws Exception {
//把数据填充到JavaBean对象中
User user = new User(“1”, “钟福成”, “未来的程序员”);
//创建Document对象【导入的是Lucene包下的Document对象】
Document document = new Document();
//将JavaBean对象所有的属性值,均放到Document对象中去,属性名可以和JavaBean相同或不同
/**
* 向Document对象加入一个字段
* 参数一:字段的关键字
* 参数二:字符的值
* 参数三:是否要存储到原始记录表中
* YES表示是
* NO表示否
* 参数四:是否需要将存储的数据拆分到词汇表中
* ANALYZED表示拆分
* NOT_ANALYZED表示不拆分
*
* */
document.add(new Field(“id”, user.getId(), Field.Store.YES, Field.Index.ANALYZED));
document.add(new Field(“userName”, user.getUserName(), Field.Store.YES, Field.Index.ANALYZED));
document.add(new Field(“sal”, user.getSal(), Field.Store.YES, Field.Index.ANALYZED));
//创建IndexWriter对象
//目录指定为E:/createIndexDB
Directory directory = FSDirectory.open(new File(“E:/createIndexDB”));
//使用标准的分词算法对原始记录表进行拆分
Analyzer analyzer = new StandardAnalyzer(Version.LUCENE_30);
//LIMITED默认是1W个
IndexWriter.MaxFieldLength maxFieldLength = IndexWriter.MaxFieldLength.LIMITED;
/**
* IndexWriter将我们的document对象写到硬盘中
*
* 参数一:Directory d,写到硬盘中的目录路径是什么
* 参数二:Analyzer a, 以何种算法来对document中的原始记录表数据进行拆分成词汇表
* 参数三:MaxFieldLength mfl 最多将文本拆分出多少个词汇
*
* */
IndexWriter indexWriter = new IndexWriter(directory, analyzer, maxFieldLength);
//将Document对象通过IndexWriter对象写入索引库中
indexWriter.addDocument(document);
//关闭IndexWriter对象
indexWriter.close();
}