SpringData框架提供基本增删改查方法
但是如果有具体的针对性的查询逻辑,一定还是需要我们自己编写代码
例如实现类似数据库中的模糊查询
我们的查询需求是查询title属性中包含"游戏"这个分词的商品信息
参考模糊查询代码
select * from item where title like '%游戏%'
我们使用ES查询,本质上运行的就是我们在es.http文档中编写的查询语句
但是SpringData框架下,编写查询语句更加简单
我们在ItemRepository接口中添加如下代码
// SpringData自定义查询
// 遵循SpringData框架规定的格式的前提下,编写方法名会自动生成查询逻辑
// query: 表示当前方法是一个查询功能,类似sql中的select
// Item\Items: 表示查询结果的实体类,带s的返回集合
// By:标识开始设置条件,类似sql的where
// Title: 要查询的字段名称
// Matches: 是要执行的查询操作,这里是分词查询,类似sql的like
Iterable<Item> queryItemsByTitleMatches(String title);
再测试类中进行测试
//单条件自定义查询
@Test
void queryOne(){
// 查询 ES中title字段包含"游戏"分词的数据
Iterable<Item> items=itemRepository.queryItemsByTitleMatches("游戏");
items.forEach(item -> System.out.println(item));
}
上面代码运行时底层运行的查询语句为:
### 单条件搜索
POST http://localhost:9200/items/_search
Content-Type: application/json
{
"query": {"match": { "title": "游戏" }}
}
在相对复杂的查询逻辑下
经常使用多个条件来定位查询需要的数据
这样就需要逻辑运算符"and"/“or”
ItemRepository接口中添加多条件的查询方法
// 多条件查询
// 两个或多个条件之间直接编写And或Or表示查询逻辑
// 参数名称实际上没有要求必须和字段名称匹配,底层代码是按照参数顺序赋值的
Iterable<Item> queryItemsByTitleMatchesAndBrandMatches(String title,String brand);
上面的查询添加了品牌作为条件
逻辑关系是and(与)
测试代码如下
// 多条件自定义查询
@Test
void queryTwo(){
Iterable<Item> items=itemRepository
.queryItemsByTitleMatchesAndBrandMatches("游戏","雷蛇");
items.forEach(item -> System.out.println(item));
}
底层运行的请求
### 多字段搜索
POST http://localhost:9200/items/_search
Content-Type: application/json
{
"query": {
"bool": {
"must": [
{ "match": { "title": "游戏"}},
{ "match": { "brand": "雷蛇"}}
]
}
}
}
当查询条件关系为And时,查询语句关键字为must
当查询条件关系为Or时,查询语句关键字为should
上次课我们完成了单条件查询和多条件查询
但是条件的变化只是查询的需求之一
我们还需要像排序等需求的查询
如果实施排序需求,就在Repository接口中添加方法如下
// 排序查询
// 默认情况下,ES查询结果按score排序,如果想按其他的规则排序可以加OrderBy
// 和数据库一样,默认升序排序 Desc结尾会降序
Iterable<Item> queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
String title, String brand);
测试代码如下
// 排序查询
@Test
void queryOrder(){
Iterable<Item> items=itemRepository
.queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc("游戏","罗技");
items.forEach(item -> System.out.println(item));
}
底层代码逻辑
### 多字段搜索
POST http://localhost:9200/items/_search
Content-Type: application/json
{
"query": {
"bool": {
"should": [
{ "match": { "title": "游戏"}},
{ "match": { "brand": "罗技"}}
]
}
},"sort":[{"price":"desc"}]
}
SpringData框架支持分页查询
只需要修改参数和返回值就能实现自动分页的效果
修改ItemRepository接口代码如下
// 分页查询
// 当查询数据较多时,我们可以利用SpringData的分页功能,按用户要求的页码查询需要的数据
// 返回值修改为Page类型,这个类型对象除了包含Iterable能够包含的集合信息之外,还包含分页信息
Page<Item> queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
String title, String brand, Pageable pageable);
测试代码如下
// 分页查询
@Test
void queryPage(){
int pageNum=1; //页码
int pageSize=2; //每页条数
Page<Item> page= itemRepository
.queryItemsByTitleMatchesOrBrandMatchesOrderByPriceDesc(
"游戏","罗技", PageRequest.of(pageNum-1,pageSize));
page.forEach(item -> System.out.println(item));
// page对象中还包含了一些基本的分页信息
System.out.println("总页数:"+page.getTotalPages());
System.out.println("当前页:"+page.getNumber());
System.out.println("每页条数:"+page.getSize());
System.out.println("当前页是不是首页:"+page.isFirst());
System.out.println("当前页是不是末页:"+page.isLast());
}