写在前面
本文将在第六篇《使用ElasticSearch实现商品复杂搜索》的基础上整合MongoDB,实现用户商品浏览记录这一功能。
MongoDB
MongoDB简介
MongoDB是一个为快速开发互联网Web应用而构建的数据库系统,其数据模型和持久化策略就是为了构建高读/写吞吐量和高自动灾备伸缩性的系统。
安装MongoDB服务
第一步,点击 这里 下载MongoDB的安装包;
第二步,自定义MongoDB的安装路径:
第三步,在MongoDB安装路径下创建data\db
和data\log
这两个文件夹:
第四步,在MongoDB安装路径下创建mongod.cfg
配置文件,里面的配置信息如下:
1 2 3 4 5
| systemLog: destination: file path: E:\Application\MongoDB\data\log\mongod.log storage: dbPath: E:\Application\MongoDB\data\db
|
第五步,进入到MongoDB安装路径下的bin目录,里面有两个exe文件,分别是客户端和服务端运行程序:
然后以管理员身份打开终端,并切换到bin目录下,执行如下命令来给系统安装MongoDB服务:
1
| E:\Application\MongoDB\bin\mongod.exe --config "E:\Application\MongoDB\mongod.cfg" --install
|
第六步,一些与MongoDB服务管理相关的命令:
1 2 3
| 启动服务:net start MongoDB 关闭服务:net stop MongoDB 移除服务:E:\Application\MongoDB\bin\mongod.exe --remove
|
使用上述命令来启动MongoDB服务。
安装MongoDB客户端
第一步,点击 这里 下载MongoDB客户端的安装包;
第二步,将其解压到指定目录,并打开名为robo3t.exe
的软件,然后连接到localhost:27017
:
Spring Data MongoDB
Spring Data MongoDB是Spring提供的一种以Spring Data风格来操作数据存储的方式,可以避免开发者编写大量的样板代码,提升代码质量。
Spring Data MongoDB常用注解
@Document
@Document
注解添加到需要映射到MongoDB文档上的领域对象上:
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Persistent @Inherited @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE}) public @interface Document { @AliasFor("collection") String value() default "";
@AliasFor("value") String collection() default "";
String language() default ""; }
|
@Id
@Id
注解添加到映射到MongoDB文档上的领域对象的ID字段上,即文档的id,类似于数据库中的行:
1 2 3 4
| @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.METHOD, ElementType.ANNOTATION_TYPE}) public @interface Id { }
|
@Indexed
@Indexed
注解添加到映射到MongoDB文档上的领域对象的某个字段上,用于标识该字段为MongoDB的索引字段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Indexed { boolean unique() default false;
IndexDirection direction() default IndexDirection.ASCENDING;
boolean sparse() default false;
/** @deprecated */ @Deprecated boolean dropDups() default false;
String name() default "";
boolean useGeneratedName() default false;
boolean background() default false;
int expireAfterSeconds() default -1; }
|
Spring Data操作数据的方式
如果你之前使用过JPA,你会发现Spring Data操作数据的方式都是类似的,即继承XXXRepository接口,然后就可以获得一些操作数据的常用方法。此处是继承MongoRepository接口:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @NoRepositoryBean public interface MongoRepository<T, ID> extends PagingAndSortingRepository<T, ID>, QueryByExampleExecutor<T> { <S extends T> List<S> saveAll(Iterable<S> var1);
List<T> findAll();
List<T> findAll(Sort var1);
<S extends T> S insert(S var1);
<S extends T> List<S> insert(Iterable<S> var1);
<S extends T> List<S> findAll(Example<S> var1);
<S extends T> List<S> findAll(Example<S> var1, Sort var2); }
|
实际上开发者也可以使用衍生查询,即在接口中直接指定查询方法的名称就可以实现查询,无需提供具体的实现:
就像后面会使用到的,根据会员id按照时间倒序获取会员的浏览记录,直接在接口中定义如下方法即可:
1 2 3 4 5 6 7 8 9 10 11
| /** * 会员商品浏览历史记录Repository */ public interface MemberReadHistoryRepository extends MongoRepository<MemberReadHistory,String> { /** * 根据会员id按照时间倒序获取商品浏览历史记录 * @param memberId 会员id * @return 商品浏览历史记录 */ List<MemberReadHistory> findByMemberIdOrderByCreateTimeDesc(Long memberId); }
|
如果开发者使用的IDE是IDEA,那么它会在开发者编写方法的时候直接提示对应字段信息:
当然了,开发者也可以使用@Query
注解,直接使用MongoDB的JSON语句来进行查询:
1 2
| @Query("{ 'memberId' : ?0 }") List<MemberReadHistory> findByMemberId(Long memberId);
|
整合MongoDB实现用户商品浏览记录
第一步,复制一份shop-elasticsearch
源码,将其名字修改为shop-mongodb
,然后对应包和文件中的信息也记得修改,本篇后续所有操作均在shop-mongodb
这一Module中进行。注意复制之后需要重新执行一下Generator类,以覆盖之前项目的自动生成文件。关于如何使用IDEA复制module,可以点击 这里 进行阅读。
第二步,在shop-mongodb
的POM文件中新增如下依赖:
1 2 3 4 5
| <!---MongoDB相关依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
|
第三步,往application.yml
配置文件中在spring.data
节点下添加MongoDB相关配置信息:
1 2 3 4 5 6
| # MongoDB相关 data: mongodb: host: localhost # mongodb的连接地址 port: 27017 # mongodb的连接端口号 database: shop-port # mongodb的连接的数据库
|
第四步,在nosql包内定义一个名为mongodb的包,接着在mongodb包内定义一个名为document的包。然后在document包内定义一个名为MemberReadHistory
的类,注意这是会员浏览记录文档对象。然后文档对象的ID域使用@Id
注解,需要检索的字段添加@Indexed
注解:
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
| /** * 用户商品浏览历史记录文档对象 */ @Data @Document public class MemberReadHistory { @Id private String id; /** * 用户id */ @Indexed private Long memberId; /** * 用户昵称 */ private String memberNickname; /** * 用户头像 */ private String memberIcon; /** * 商品id */ @Indexed private Long productId; /** * 商品名称 */ private String productName; /** * 商品图片 */ private String productPic; /** * 商品副标题 */ private String productSubTitle; /** * 商品价格 */ private String productPrice; /** * 浏览时间 */ private Date createTime; }
|
第五步,
在mongodb包内新建一个名为repository的包,并在该包内定义一个名为MemberReadHistoryRepository
的接口,注意这个接口需要继承MongoRepository
接口,这样就拥有了一些基本的操作MongoDB数据的方法,同时我们在里面定义了一个衍生的根据用户(会员)id按照时间倒序获取商品浏览历史记录的方法:
1 2 3 4 5 6 7 8 9 10 11
| /** * 会员商品浏览历史记录Repository */ public interface MemberReadHistoryRepository extends MongoRepository<MemberReadHistory,String> { /** * 根据会员id按照时间倒序获取商品浏览历史记录 * @param memberId 会员id * @return 商品浏览历史记录 */ List<MemberReadHistory> findByMemberIdOrderByCreateTimeDesc(Long memberId); }
|
第六步,在service包内定义一个名为MemberReadHistoryService
的接口,用于定义与会员浏览商品历史记录管理相关的接口方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| /** * 会员浏览商品历史记录管理 Service */ public interface MemberReadHistoryService { /** * 生成浏览历史记录 * @param memberReadHistory 浏览历史记录信息 */ int create(MemberReadHistory memberReadHistory);
/** * 批量删除浏览历史记录 * @param ids 浏览历史记录id */ int delete(List<String> ids);
/** * 获取指定会员的浏览历史记录 * @param memberId 会员id */ List<MemberReadHistory> list(Long memberId); }
|
第七步,在impl包内定义一个名为MemberReadHistoryServiceImpl
的类,这个类需要实现MemberReadHistoryService
接口,并重写其中的方法:
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
| /** * 会员浏览商品历史记录管理Service的实现类 */ @Service public class MemberReadHistoryServiceImpl implements MemberReadHistoryService { @Autowired private MemberReadHistoryRepository memberReadHistoryRepository;
@Override public int create(MemberReadHistory memberReadHistory) { memberReadHistory.setId(null); memberReadHistory.setCreateTime(new Date()); memberReadHistoryRepository.save(memberReadHistory); return 1; }
@Override public int delete(List<String> ids) { List<MemberReadHistory> deleteMemberReadHistoryLists = new ArrayList<>(); for(String id:ids){ MemberReadHistory memberReadHistory = new MemberReadHistory(); memberReadHistory.setId(id); deleteMemberReadHistoryLists.add(memberReadHistory); } memberReadHistoryRepository.deleteAll(deleteMemberReadHistoryLists); return deleteMemberReadHistoryLists.size(); }
@Override public List<MemberReadHistory> list(Long memberId) { return memberReadHistoryRepository.findByMemberIdOrderByCreateTimeDesc(memberId); } }
|
第八步,在controller包内定义一个名为MemberReadHistoryController
的类,这是会员商品浏览历史记录管理的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
| /** * 会员商品浏览历史记录管理Controller */ @Api(tags = "MemberReadHistoryController",description = "会员商品浏览历史记录管理") @RestController @RequestMapping("/member/readHistory") public class MemberReadHistoryController { @Autowired private MemberReadHistoryService memberReadHistoryService;
@ApiOperation("创建浏览记录") @PostMapping( "/create") public CommonResult create(@RequestBody MemberReadHistory memberReadHistory) { int count = memberReadHistoryService.create(memberReadHistory); if (count > 0) { return CommonResult.success(count); } else { return CommonResult.failed(); } }
@ApiOperation("删除浏览记录") @PostMapping("/delete") public CommonResult delete(@RequestParam("ids") List<String> ids) { int count = memberReadHistoryService.delete(ids); if (count > 0) { return CommonResult.success(count); } else { return CommonResult.failed(); } }
@ApiOperation("展示浏览记录") @GetMapping("/list") public CommonResult<List<MemberReadHistory>> list(@RequestParam(value = "memberId")@ApiParam("会员id") Long memberId) { List<MemberReadHistory> memberReadHistoryList = memberReadHistoryService.list(memberId); return CommonResult.success(memberReadHistoryList); } }
|
第九步,启动项目,访问Swagger-UI接口文档地址,即浏览器访问http://localhost:8080/swagger-ui.html
链接,可以看到新的接口已经出现了:
第十步,进行接口测试。首先后台用户进行登录,接着测试“创建浏览记录”:
可以更改memberId来创建两条测试数据:
接着测试一下查看某会员商品浏览历史记录接口:
这样本篇关于整合MongoDB实现用户商品浏览记录的学习就完成了,后续介绍如何整合RabbitMQ实现延迟消息这一功能。本篇笔记源码,可以点击 这里 进行阅读。