Spring boot集成mongoDB使用MongoRepository

引入依赖

springboot集成MongoDb引入依赖


org.springframework.bootspring-boot-starter-data-mongodb

看一下MongoRepository接口,它集成了 spring-data-commons的PagingAndSortingRepository接口和QueryByExampleExecutor接口

public interface MongoRepository extends PagingAndSortingRepository, QueryByExampleExecutor 

spring-data包介绍

Spring Data 是spring的组件之一,主要目的是为了让开发者再工作中能更加轻松的完成CURD,简化代码应该是所有框架的目的吧。Spring-data-commons只是其中的一个模块而已,spring-data-mongo包含了spring-data-comons,另外spring-data-JPA也是实现了spring-data-common的接口完成简单的CRUD操作以及复杂自定义的查询更新操作。

JPA操作手册:https://docs.spring.io/spring-data/jpa/docs/current/reference/html/

最底层的接口是:

package org.springframework.data.repository;
@Indexed
public interface Repository {}

中央存储库标记接口,通过实现这个接口进行扩展查询比如分页,排序等操作

jpa自定义查询的一些规范

查询创建

通常,JPA 的查询创建机制如“查询方法”中所述。以下示例显示了 JPA 查询方法转换为的内容:

示例 57. 从方法名称创建查询
公共接口 UserRepository 扩展 Repository {List findByEmailAddressAndLastname(String emailAddress, String lastname);
}

表 3. 方法名称中支持的关键字
关键词样本JPQL 片段

Distinct

findDistinctByLastnameAndFirstname

select distinct …​ where x.lastname = ?1 and x.firstname = ?2

And

findByLastnameAndFirstname

… where x.lastname = ?1 and x.firstname = ?2

Or

findByLastnameOrFirstname

… where x.lastname = ?1 or x.firstname = ?2

Is,Equals

findByFirstnamefindByFirstnameIs,findByFirstnameEquals

… where x.firstname = ?1

Between

findByStartDateBetween

… where x.startDate between ?1 and ?2

LessThan

findByAgeLessThan

… where x.age < ?1

LessThanEqual

findByAgeLessThanEqual

… where x.age <= ?1

GreaterThan

findByAgeGreaterThan

… where x.age > ?1

GreaterThanEqual

findByAgeGreaterThanEqual

… where x.age >= ?1

After

findByStartDateAfter

… where x.startDate > ?1

Before

findByStartDateBefore

… where x.startDate < ?1

IsNull,Null

findByAge(Is)Null

… where x.age is null

IsNotNull,NotNull

findByAge(Is)NotNull

… where x.age not null

Like

findByFirstnameLike

… where x.firstname like ?1

NotLike

findByFirstnameNotLike

… where x.firstname not like ?1

StartingWith

findByFirstnameStartingWith

… where x.firstname like ?1(与 append 绑定的参数%

EndingWith

findByFirstnameEndingWith

… where x.firstname like ?1(以 prepended 绑定的参数%

Containing

findByFirstnameContaining

… where x.firstname like ?1(参数绑定在 中%

OrderBy

findByAgeOrderByLastnameDesc

… where x.age = ?1 order by x.lastname desc

Not

findByLastnameNot

… where x.lastname <> ?1

In

findByAgeIn(Collection ages)

… where x.age in ?1

NotIn

findByAgeNotIn(Collection ages)

… where x.age not in ?1

True

findByActiveTrue()

… where x.active = true

False

findByActiveFalse()

… where x.active = false

IgnoreCase

findByFirstnameIgnoreCase

… where UPPER(x.firstname) = UPPER(?1)

MongoRepository使用

自定义实体类:

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {@Idprivate String id;private String userName;private String userId;private Integer age;private String sex;@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")private Date birthDay;
}

 定义Dao层操作MongoDB

@Repository
public interface UserRepository extends MongoRepository {List findByUserNameLike(String userName);
}

service层

public interface UserService {/*** 模糊查询* @param userName 用户名* @return List*/List findUserName(String userName);/*** 保存用户信息* @param user user用户信息*/void saveUser(User user);/*** 根据用户id删除用户* @param userId 用户Id*/void deleteUser(String userId);/*** @param  pageable 分页信息* @return Page*/Page findUserPage(Pageable pageable);/*** 更新用户信息 * @param user 用户信息*/void updateUserInfo(User user);/*** 模糊查询 按照名字* @param userName* @return List*/List findLikeUserName(String userName);/*** 查询所有数据* @return List*/List findAll();
}

controller层:

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/find/userName")public CommonResponse findUserName(@RequestParam("userName") String userName) {List users = userService.findUserName(userName);return CommonResponse.success(users);}@GetMapping("/find/like")public CommonResponse findLikeUserName(@RequestParam("userName") String userName) {List users = userService.findLikeUserName(userName);return CommonResponse.success(users);}@PostMapping("/save")public CommonResponse save(@RequestBody User user) {userService.saveUser(user);return CommonResponse.success();}@PutMapping("/update")public CommonResponse update(@RequestBody User user) {userService.updateUserInfo(user);return CommonResponse.success();}@GetMapping("/page")public CommonResponse page(@RequestParam Integer page, @RequestParam Integer limit) {MongoPageAble mongoPageAble = MongoPageAble.of(page, limit);Page page1 = userService.findUserPage(mongoPageAble);return CommonResponse.success(new PageInfoDTO<>(page1));}@DeleteMapping("/delete")public CommonResponse delete(@RequestParam String userId) {userService.deleteUser(userId);return CommonResponse.success();}@GetMapping("/find/all")public CommonResponse findAll() {List users = userService.findAll();return CommonResponse.success(users);}
}

提供自定义的分页查询数据PO:

public class MongoPageAble extends AbstractPageRequest {private Sort sort;public MongoPageAble(int pageNum, int pageSize, Sort sort) {super(pageNum, pageSize);this.sort = sort;}public static MongoPageAble of(int page, int size) {return of(page, size, Sort.unsorted());}public static MongoPageAble of(int page, int size, Sort sort) {return new MongoPageAble(page, size, sort);}public static MongoPageAble of(int page, int size, Sort.Direction direction, String... properties) {return of(page, size, Sort.by(direction, properties));}@Overridepublic Sort getSort() {return sort;}@Overridepublic Pageable next() {return new MongoPageAble(this.getPageNumber() + 1, this.getPageSize(), this.getSort());}@Overridepublic Pageable previousOrFirst() {return this.hasPrevious() ? this.previous() : this.first();}@Overridepublic Pageable previous() {return this.getPageNumber() == 1 ? this : new MongoPageAble(this.getPageNumber() - 1, this.getPageSize(), this.getSort());}@Overridepublic Pageable first() {return new MongoPageAble(1, this.getPageSize(), this.getSort());}public void setSort(Sort sort) {this.sort = sort;}@Overridepublic boolean equals(@Nullable Object obj) {if (this == obj) {return true;} else if (!(obj instanceof MongoPageAble)) {return false;} else {MongoPageAble that = (MongoPageAble)obj;return super.equals(that) && this.sort.equals(that.sort);}}@Overridepublic int hashCode() {return 31 * super.hashCode() + this.sort.hashCode();}@Overridepublic String toString() {return String.format("Page request [number: %d, size %d, sort: %s]", this.getPageNumber(), this.getPageSize(), this.sort);}/*** 使用分页这个一定要改写 他们默认的分页是以下标0开始* @return*/@Overridepublic long getOffset() {return ( (getPageNumber()-1) * getPageSize());}
}

      其中需要注意的是getOffset方法,因为mongoDB在实际执行分页查询时候,走的是skip().limit()操作,skip表示跳过查询的数量,这里传入的参数offset偏移量,而我们接口实际查询的时候页数page是从1开始的,mongo在计算偏移量的时候是offset=page*size 导致跳过第一页数据

自定义封装分页查询结果:

@Data
@NoArgsConstructor
public class PageInfoDTO {/*** 总记录数*/private Integer totalCount;/*** 每页记录数*/private Integer pageSize;/*** 总页数*/private Integer totalPage;/*** 开始页数默认从1*/private Integer startPage;/*** 列表数据*/private List list;/*** 分页** @param list      列表数据* @param pageSize  每页记录数* @param startPage 当前页数*/public PageInfoDTO(List list, Integer pageSize, Integer startPage) {this.list = list;this.totalCount = list.size();this.pageSize = pageSize;this.startPage = startPage;this.totalPage = (int) Math.ceil((double) totalCount / pageSize);}/*** 分页*/public PageInfoDTO(IPage page) {this.list = page.getRecords();this.totalCount = (int) page.getTotal();this.pageSize = (int) page.getSize();this.startPage = (int) page.getCurrent();this.totalPage = (int) page.getPages();}public PageInfoDTO(Page page) {
//        this.list = page.get().collect(Collectors.toList());this.list = page.getContent();this.totalCount = (int) page.getTotalElements();this.pageSize = page.getSize();this.startPage = page.getPageable().getPageNumber();this.totalPage = page.getTotalPages();}
}

 下面开始实际测试:

插入数据:

查询全部数据:

http://localhost:8080/user/find/all

 查询结果:

{

    "success": true,

    "code": "200",

    "msg": "操作成功",

    "data": [

        {

            "id": "1111",

            "userName": "小王",

            "userId": "23",

            "age": 23,

            "sex": "男",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "222",

            "userName": "小王",

            "userId": "23",

            "age": 23,

            "sex": "男",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "333",

            "userName": "小王",

            "userId": "23",

            "age": 23,

            "sex": "男",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "444",

            "userName": "小王",

            "userId": "23",

            "age": 23,

            "sex": "女",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "555",

            "userName": "小王22",

            "userId": "23",

            "age": 23,

            "sex": "女",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "666",

            "userName": "小王11",

            "userId": "23",

            "age": 23,

            "sex": "女",

            "birthDay": "2020-11-20 20:02:20"

        }

    ]

}

模糊查询:

http://localhost:8080/user/find/like?userName=小王

 查询结果:

{

    "success": true,

    "code": "200",

    "msg": "操作成功",

    "data": [

        {

            "id": "1111",

            "userName": "小王",

            "userId": "23",

            "age": 23,

            "sex": "男",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "222",

            "userName": "小王",

            "userId": "23",

            "age": 23,

            "sex": "男",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "333",

            "userName": "小王",

            "userId": "23",

            "age": 23,

            "sex": "男",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "444",

            "userName": "小王",

            "userId": "23",

            "age": 23,

            "sex": "女",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "555",

            "userName": "小王22",

            "userId": "23",

            "age": 23,

            "sex": "女",

            "birthDay": "2020-11-20 20:02:20"

        },

        {

            "id": "666",

            "userName": "小王11",

            "userId": "23",

            "age": 23,

            "sex": "女",

            "birthDay": "2020-11-20 20:02:20"

        }

    ]

}

分页查询:

 localhost:8080/user/page?page=2&limit=3

查询结果:

{

    "success": true,

    "code": "200",

    "msg": "操作成功",

    "data": {

        "totalCount": 6,

        "pageSize": 3,

        "totalPage": 2,

        "startPage": 2,

        "list": [

            {

                "id": "444",

                "userName": "小王",

                "userId": "23",

                "age": 23,

                "sex": "女",

                "birthDay": "2020-11-20 20:02:20"

            },

            {

                "id": "555",

                "userName": "小王22",

                "userId": "23",

                "age": 23,

                "sex": "女",

                "birthDay": "2020-11-20 20:02:20"

            },

            {

                "id": "666",

                "userName": "小王11",

                "userId": "23",

                "age": 23,

                "sex": "女",

                "birthDay": "2020-11-20 20:02:20"

            }

        ]

    }

}

在实际开发中也可使用MongoTemplate代替上面的操作 ,后续会介绍MongoTemplate的CRUD操作以及分页聚合排序等


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部