文档

简介 (easy-es.cn)

自动托管索引 - Easy-Es

springboot 引入步骤

pom.xml

1
2
3
4
5
<dependency>
<groupId>io.github.xpc1024</groupId>
<artifactId>easy-es-boot-starter</artifactId>
<version>0.9.20</version>
</dependency>

application.yml

1
2
3
4
5
easy-es:
enable: true #默认为true,若为false则认为不启用本框架
address : tcboot-elasticsearch:9200 # es的连接地址,必须含端口 若为集群,则可以用逗号隔开
username: elastic #若无 则可省略此行配置
password: WG7WVmuNMtM4GwNYkyWH #若无 则可省略此行配置

启动类

1
2
// 添加注解
@EsMapperScan("org.jeecg.modules.*.es.mapper")

实体类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package org.jeecg.modules.zhzf.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.xpc.easyes.core.anno.TableId;
import com.xpc.easyes.core.anno.TableName;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.jeecg.common.aspect.annotation.Dict;
import org.jeecgframework.poi.excel.annotation.Excel;
import org.springframework.format.annotation.DateTimeFormat;

import java.io.Serializable;
import java.util.Date;

/**
* @Description: 法律法规管理
* @Author: bjtc-boot
* @Date: 2022-03-23
* @Version: V1.0
*/
@Data
@TableName("law")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="zf_law对象", description="法律法规管理")
public class Law implements Serializable {
private static final long serialVersionUID = 1L;

/**主键*/
@TableId(value = "id")
@ApiModelProperty(value = "主键")
private String id;
/**创建人*/
@ApiModelProperty(value = "创建人")
private String createBy;
/**创建日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "创建日期")
private Date createTime;
/**更新人*/
@ApiModelProperty(value = "更新人")
private String updateBy;
/**更新日期*/
@JsonFormat(timezone = "GMT+8",pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
@ApiModelProperty(value = "更新日期")
private Date updateTime;
/**所属部门*/
@ApiModelProperty(value = "所属部门")
private String sysOrgCode;
/**类别*/
@Excel(name = "类别", width = 15, dicCode = "zf_law_type")
@Dict(dicCode = "zf_law_type")
@ApiModelProperty(value = "类别")
private String lawtype;
/**名称*/
@Excel(name = "名称", width = 15)
@ApiModelProperty(value = "名称")
private String name;
/**简介*/
@Excel(name = "简介", width = 15)
@ApiModelProperty(value = "简介")
private String intro;
/**章*/
@Excel(name = "章", width = 15)
@ApiModelProperty(value = "章")
private String zhang;
/**节*/
@Excel(name = "节", width = 15)
@ApiModelProperty(value = "节")
private String jie;
/**条*/
@Excel(name = "条", width = 15)
@ApiModelProperty(value = "条")
private String tiao;
/**款*/
@Excel(name = "款", width = 15)
@ApiModelProperty(value = "款")
private String kuan;
/**项*/
@Excel(name = "项", width = 15)
@ApiModelProperty(value = "项")
private String xiang;
/**目*/
@Excel(name = "目", width = 15)
@ApiModelProperty(value = "目")
private String mu;
/**内容*/
@Excel(name = "内容", width = 15)
@ApiModelProperty(value = "内容")
private String content;
/**排序号*/
@Excel(name = "排序号", width = 15)
@ApiModelProperty(value = "排序号")
private String ordernumber;
}

“自动挡”模式下的最佳实践示例:

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
@Data
@TableName(shardsNum = 3,replicasNum = 2) // 可指定分片数,副本数,若缺省则默认均为1
public class Document {
/**
* es中的唯一id,如果你想自定义es中的id为你提供的id,比如MySQL中的id,请将注解中的type指定为customize,如此id便支持任意数据类型)
*/
@TableId(type = IdType.CUSTOMIZE)
private Long id;
/**
* 文档标题,不指定类型默认被创建为keyword类型,可进行精确查询
*/
private String title;
/**
* 文档内容,指定了类型及存储/查询分词器
*/
@TableField(fieldType = FieldType.TEXT, analyzer = Analyzer.IK_SMART, searchAnalyzer = Analyzer.IK_MAX_WORD)
private String content;
/**
* 作者 加@TableField注解,并指明strategy = FieldStrategy.NOT_EMPTY 表示更新的时候的策略为 创建者不为空字符串时才更新
*/
@TableField(strategy = FieldStrategy.NOT_EMPTY)
private String creator;
/**
* 创建时间
*/
@TableField(fieldType = FieldType.DATE, dateFormat = "yyyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis")
private String gmtCreate;
/**
* es中实际不存在的字段,但模型中加了,为了不和es映射,可以在此类型字段上加上 注解@TableField,并指明exist=false
*/
@TableField(exist = false)
private String notExistsField;
/**
* 地理位置经纬度坐标 例如: "40.13933715136454,116.63441990026217"
*/
@TableField(fieldType = FieldType.GEO_POINT)
private String location;
/**
* 图形(例如圆心,矩形)
*/
@TableField(fieldType = FieldType.GEO_SHAPE)
private String geoLocation;
/**
* 自定义字段名称
*/
@TableField(value = "wu-la")
private String customField;

/**
* 高亮返回值被映射的字段
*/
@HighLightMappingField("content")
private String highlightContent;
}

XxxMapper 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package org.jeecg.modules.zhzf.es.mapper;

import com.xpc.easyes.core.conditions.interfaces.BaseEsMapper;
import org.jeecg.modules.zhzf.entity.Law;

/**
* @Description: 法律法规管理
* @Author: bjtc-boot
* @Date: 2022-03-23
* @Version: V1.0
*/
public interface LawMapper extends BaseEsMapper<Law> {

}

Controller 接口

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package org.jeecg.modules.zhzf.controller;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xpc.easyes.core.common.PageInfo;
import com.xpc.easyes.core.conditions.LambdaEsQueryWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.base.controller.JeecgEsController;
import org.jeecg.modules.zhzf.entity.Law;
import org.jeecg.modules.zhzf.es.mapper.LawMapper;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.Arrays;

/**
* @Description: 法律法规管理
* @Author: bjtc-boot
* @Date: 2022-03-23
* @Version: V1.0
*/
@Api(tags = "法律法规管理")
@RestController
@RequestMapping("/zhzf/law")
@Slf4j
public class LawController extends JeecgEsController<Law, LawMapper> {

@Resource
private LawMapper lawMapper;

/**
* 分页列表查询
*
* @param law
* @param pageNo
* @param pageSize
* @param req
* @return
*/
@AutoLog(value = "法律法规管理-分页列表查询")
@ApiOperation(value = "法律法规管理-分页列表查询", notes = "法律法规管理-分页列表查询")
@GetMapping(value = "/list")
public Result<?> queryPageList(Law law,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
LambdaEsQueryWrapper<Law> queryWrapper = new LambdaEsQueryWrapper<>();
String lawtype = law.getLawtype();
queryWrapper.eq(StrUtil.isNotBlank(lawtype), Law::getLawtype, lawtype);
String content = law.getContent();
queryWrapper.match(StrUtil.isNotBlank(content), Law::getContent, content);

PageInfo pageInfo = lawMapper.pageQuery(queryWrapper, pageNo, pageSize);

// 分页数据返回:records total 信息
Page<Law> page = new Page<>(pageNo, pageSize);
long total = pageInfo.getTotal();
page.setTotal(total);
if (total > 0) {
page.setRecords(pageInfo.getList());
} else {
page.setRecords(new ArrayList<>());
}
return Result.OK(page);
}

/**
* 添加
*
* @param law
* @return
*/
@AutoLog(value = "法律法规管理-添加")
@ApiOperation(value = "法律法规管理-添加", notes = "法律法规管理-添加")
@PostMapping(value = "/add")
public Result<?> add(@RequestBody Law law) {
// 添加基本字段信息-新增字段
this.initAddBaseinfo(law);

lawMapper.insert(law);
return Result.OK("添加成功!");
}

/**
* 编辑
*
* @param law
* @return
*/
@AutoLog(value = "法律法规管理-编辑")
@ApiOperation(value = "法律法规管理-编辑", notes = "法律法规管理-编辑")
@PutMapping(value = "/edit")
public Result<?> edit(@RequestBody Law law) {
// 添加基本字段信息-修改字段
this.initUpdateBaseinfo(law);

lawMapper.updateById(law);
return Result.OK("编辑成功!");
}

/**
* 通过id删除
*
* @param id
* @return
*/
@AutoLog(value = "法律法规管理-通过id删除")
@ApiOperation(value = "法律法规管理-通过id删除", notes = "法律法规管理-通过id删除")
@DeleteMapping(value = "/delete")
public Result<?> delete(@RequestParam(name = "id", required = true) String id) {
lawMapper.deleteById(id);
return Result.OK("删除成功!");
}

/**
* 批量删除
*
* @param ids
* @return
*/
@AutoLog(value = "法律法规管理-批量删除")
@ApiOperation(value = "法律法规管理-批量删除", notes = "法律法规管理-批量删除")
@DeleteMapping(value = "/deleteBatch")
public Result<?> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
lawMapper.deleteBatchIds(Arrays.asList(ids.split(",")));
return Result.OK("批量删除成功!");
}

/**
* 通过id查询
*
* @param id
* @return
*/
@AutoLog(value = "法律法规管理-通过id查询")
@ApiOperation(value = "法律法规管理-通过id查询", notes = "法律法规管理-通过id查询")
@GetMapping(value = "/queryById")
public Result<?> queryById(@RequestParam(name = "id", required = true) String id) {
Law law = lawMapper.selectById(id);
if (law == null) {
return Result.error("未找到对应数据");
}
return Result.OK(law);
}

/**
* 导出excel
*
* @param request
* @param law
*/
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, Law law) {
LambdaEsQueryWrapper<Law> queryWrapper = new LambdaEsQueryWrapper<>();
String lawtype = law.getLawtype();
queryWrapper.eq(StrUtil.isNotBlank(lawtype), Law::getLawtype, lawtype);
String content = law.getContent();
queryWrapper.match(StrUtil.isNotBlank(content), Law::getContent, content);
return super.exportXls(request, queryWrapper, Law.class, "法律法规管理");
}

/**
* 通过excel导入数据
*
* @param request
* @param response
* @return
*/
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, Law.class);
}
}

其它

JeecgEsController.java

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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
package org.jeecg.common.system.base.controller;

import com.xpc.easyes.core.common.PageInfo;
import com.xpc.easyes.core.conditions.LambdaEsQueryWrapper;
import com.xpc.easyes.core.conditions.interfaces.BaseEsMapper;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecgframework.poi.excel.ExcelImportUtil;
import org.jeecgframework.poi.excel.entity.ExportParams;
import org.jeecgframework.poi.excel.entity.ImportParams;
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;

public class JeecgEsController<T, S extends BaseEsMapper<T>> {
private static final Logger log = LoggerFactory.getLogger(JeecgEsController.class);
@Autowired
protected S mapper;
@Value("${jeecg.path.upload}")
private String upLoadPath;

public JeecgEsController() {
}

public void initAddBaseinfo(Object object) {
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
Field[] fields = oConvertUtils.getAllFields(object);

try {
Field[] var4 = fields;
int var5 = fields.length;

for(int var6 = 0; var6 < var5; ++var6) {
Field field = var4[var6];
if ("createBy".equals(field.getName()) && sysUser != null) {
field.setAccessible(true);
field.set(object, sysUser.getUsername());
field.setAccessible(false);
}

if ("createTime".equals(field.getName())) {
field.setAccessible(true);
field.set(object, new Date());
field.setAccessible(false);
}

if ("sysOrgCode".equals(field.getName())) {
field.setAccessible(true);
field.set(object, sysUser.getOrgCode());
field.setAccessible(false);
}
}
} catch (IllegalAccessException var8) {
var8.printStackTrace();
}

}

public void initUpdateBaseinfo(Object object) {
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
Field[] fields = oConvertUtils.getAllFields(object);

try {
Field[] var4 = fields;
int var5 = fields.length;

for(int var6 = 0; var6 < var5; ++var6) {
Field field = var4[var6];
if ("updateBy".equals(field.getName()) && sysUser != null) {
field.setAccessible(true);
field.set(object, sysUser.getUsername());
field.setAccessible(false);
}

if ("updateTime".equals(field.getName())) {
field.setAccessible(true);
field.set(object, new Date());
field.setAccessible(false);
}
}
} catch (IllegalAccessException var8) {
var8.printStackTrace();
}

}

protected ModelAndView exportXls(HttpServletRequest request, LambdaEsQueryWrapper<T> queryWrapper, Class<T> clazz, String title) {
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
List<T> pageList = this.mapper.selectList(queryWrapper);
List<T> exportList = null;
String selections = request.getParameter("selections");
if (oConvertUtils.isNotEmpty(selections)) {
List<String> selectionList = Arrays.asList(selections.split(","));
exportList = (List)pageList.stream().filter((item) -> {
return selectionList.contains(this.getId(item));
}).collect(Collectors.toList());
} else {
exportList = pageList;
}

ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
mv.addObject("fileName", title);
mv.addObject("entity", clazz);
ExportParams exportParams = new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title);
exportParams.setImageBasePath(this.upLoadPath);
mv.addObject("params", exportParams);
mv.addObject("data", exportList);
return mv;
}

protected ModelAndView exportXlsSheet(HttpServletRequest request, LambdaEsQueryWrapper<T> queryWrapper, Class<T> clazz, String title, String exportFields, Integer pageNum) {
LoginUser sysUser = (LoginUser)SecurityUtils.getSubject().getPrincipal();
double total = (double)this.mapper.selectCount((LambdaEsQueryWrapper)null);
int count = (int)Math.ceil(total / (double)pageNum);
List<Map<String, Object>> listMap = new ArrayList();

for(int i = 1; i <= count; ++i) {
PageInfo<T> tPageInfo = this.mapper.pageQuery(queryWrapper, i, pageNum);
List<T> records = tPageInfo.getList();
List<T> exportList = null;
String selections = request.getParameter("selections");
if (oConvertUtils.isNotEmpty(selections)) {
List<String> selectionList = Arrays.asList(selections.split(","));
exportList = (List)records.stream().filter((item) -> {
return selectionList.contains(this.getId(item));
}).collect(Collectors.toList());
} else {
exportList = records;
}

Map<String, Object> map = new HashMap();
ExportParams exportParams = new ExportParams(title + "报表", "导出人:" + sysUser.getRealname(), title + i, this.upLoadPath);
exportParams.setType(ExcelType.XSSF);
map.put("params", exportParams);
map.put("entity", clazz);
map.put("data", exportList);
listMap.add(map);
}

ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
mv.addObject("fileName", title);
mv.addObject("mapList", listMap);
return mv;
}

protected ModelAndView exportXls(HttpServletRequest request, LambdaEsQueryWrapper<T> queryWrapper, Class<T> clazz, String title, String exportFields) {
ModelAndView mv = this.exportXls(request, queryWrapper, clazz, title);
mv.addObject("exportFields", exportFields);
return mv;
}

private String getId(T item) {
try {
return PropertyUtils.getProperty(item, "id").toString();
} catch (Exception var3) {
var3.printStackTrace();
return null;
}
}

protected Result<?> importExcel(HttpServletRequest request, HttpServletResponse response, Class<T> clazz) {
MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest)request;
Map<String, MultipartFile> fileMap = multipartRequest.getFileMap();
Iterator var6 = fileMap.entrySet().iterator();
if (var6.hasNext()) {
Entry<String, MultipartFile> entity = (Entry)var6.next();
MultipartFile file = (MultipartFile)entity.getValue();
ImportParams params = new ImportParams();
params.setTitleRows(2);
params.setHeadRows(1);
params.setNeedSave(true);

Result var11;
try {
List<T> list = ExcelImportUtil.importExcel(file.getInputStream(), clazz, params);
long start = System.currentTimeMillis();
this.mapper.insertBatch(list);
log.info("消耗时间" + (System.currentTimeMillis() - start) + "毫秒");
Result var13 = Result.ok("文件导入成功!数据行数:" + list.size());
return var13;
} catch (Exception var23) {
log.error(var23.getMessage(), var23);
var11 = Result.error("文件导入失败:" + var23.getMessage());
} finally {
try {
file.getInputStream().close();
} catch (IOException var22) {
var22.printStackTrace();
}

}

return var11;
} else {
return Result.error("文件导入失败!");
}
}
}

高亮

高亮查询 - Easy-Es

  • 字段做高亮处理并返回,字段添加注解即可 @HighLight

  • 如果想返回高亮处理的字段数据,又想返回字段原值,则配置@HighLight(mappingField = "highlightContent"),额外返回高亮字段。原字段数据不做处理

    官方说法:如果你不想原来的字段值被高亮字段覆盖,那么你需要在@HighLight注解中指定mappingField,并将该字段添加至对应实体类中,这样配置以后,高亮内容在highlightContent字段中返回,原content字段的值依旧返回它本身的值

1
2
3
4
5
6
7
8
9
10
11
12
public class Document{
/**
* 指定 mappingField ,则返回本身的数据,不做高亮处理。mappingField 指定的字段返回高亮处理后的数据
*/
@HighLight(mappingField = "highlightContent")
private String content;
/**
* 高亮返回值被映射的字段-返回高亮处理后的数据
*/
private String highlightContent;
// 省略其它无关字段...
}