技术选型
mongodb-driver
mongodb-driver是mongodb官方推出的java连接mongoDB的驱动包,相当于JDBC驱动。我们通过一个入门的案例来了解mongodb-driver的基本使用。
springDataMongoDB
springData家族成员之一用于操作MongoDB的持久层操作,封装了底层的mongodb-driver。
练习
1.引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2.创建application.yml
spring:
#数据源配置
data:
mongodb:
#主机地址
host: 39.97.100.141
#数据库
database: testclient
#默认端口是27017
port: 27017
#用户名
username: root
#密码
password: root
#也可以使用uri进行连接
# mongodb://用户名:密码@IP地址:27017/数据库
#uri: mongodb://root:root@39.97.100.141:27017/testclient
# 集群配置mongodb://[username:password@]host1[:port1][,host2[:port2],...[,hostN[:portN]]][/[database][?options]]
#uri: mongodb://192.168.204.81:27017,192.168.204.82:27017,192.168.204.83:27017/testdb?maxPoolSize=512
3.创建启动类
因为我是用idea连接网站生成的启动类自动创建好了。要是想自己写的话参照下面就行
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MongodbApplication {
public static void main(String[] args) {
SpringApplication.run(MongodbApplication.class, args);
}
}
@SpringBootApplication是springboot核心注解
其次使用springboot需要引入几个依赖依赖如下:
<!--继承springboot父项目,依赖会自动匹配版本号-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
</parent>
<!--springboot启动依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!--springboot测试依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--springbootweb启动依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<build>
<!--引入jsp运行插件-->
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<!-- spring-boot:run 中文乱码解决 -->
<jvmArguments>-Defile.encoding=UTF-8</jvmArguments>
<!--指定入口类,打包的时候用-->
<mainClass>com.mongodb.mongodb</mainClass>
</configuration>
</plugin>
</plugins>
</build>
启动类核心注解
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
该注解的作用是,排除自动注入数据源的配置(取消数据库配置),一般使用在客户端(消费者)服务中
启动项目进行测试
实体类的创建
创建实体类,包命名规则pogo或者entity在你项目的src下的路径创建和启动类平级。
例如:com.mongodb.mongodb.pojo
实体类:
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import java.time.LocalDateTime;
import java.util.Date;
/*
* @Document(collection = "集合名" 对应的集合名)
* 若未加 @Document,改 bean save到mongo的comment collection
* 若添加@Document 则save到comment collection
* */
@Document(collection = "comment")//可以省略,如果省略,则默认使用类名小写映射集合
//复合索引
@CompoundIndex(def = "{'userid':1 ,'nickname':-1}")
public class Comment {
//主键标识,该属性的值会自动对应mongodb的主键字段_id,如果该属性名叫”id“则该注解可以省略否则必须写
@Id
private String id;//主键
//该属性对应mongodb的字段的名字,如果一样,则无需改注解
@Field("content")
private String content;//吐槽内容
private Date publishtime;//发布日期
//添加一个单字段的索引
@Indexed
private String userid;//发布人ID
private String nicknane;//昵称
private LocalDateTime createdatatime;//评论的日期时间
private Integer likenum;//点赞数
private Integer replynum;//回复数
private String state;//状态
private String parentid;//上级ID
private String articleid;
//getter and setter
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getPublishtime() {
return publishtime;
}
public void setPublishtime(Date publishtime) {
this.publishtime = publishtime;
}
public String getUserid() {
return userid;
}
public void setUserid(String userid) {
this.userid = userid;
}
public String getNicknane() {
return nicknane;
}
public void setNicknane(String nicknane) {
this.nicknane = nicknane;
}
public LocalDateTime getCreatedatatime() {
return createdatatime;
}
public void setCreatedatatime(LocalDateTime createdatatime) {
this.createdatatime = createdatatime;
}
public Integer getLikenum() {
return likenum;
}
public void setLikenum(Integer likenum) {
this.likenum = likenum;
}
public Integer getReplynum() {
return replynum;
}
public void setReplynum(Integer replynum) {
this.replynum = replynum;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getParentid() {
return parentid;
}
public void setParentid(String parentid) {
this.parentid = parentid;
}
public String getArticleid() {
return articleid;
}
public void setArticleid(String articleid) {
this.articleid = articleid;
}
@Override
public String toString() {
return "Comment{" +
"id='" + id + '\'' +
", content='" + content + '\'' +
", publishtime=" + publishtime +
", userid='" + userid + '\'' +
", nicknane='" + nicknane + '\'' +
", createdatatime=" + createdatatime +
", likenum=" + likenum +
", replynum=" + replynum +
", state='" + state + '\'' +
", parentid='" + parentid + '\'' +
", articleid='" + articleid + '\'' +
'}';
}
}
说明:索引可以大大提高查询效率,一般在查询字段上添加索引,索引的添加可以通过MongoDB的命令来添加,也可以在Java的实体类中通过注解添加。
基本整改改查操作
创建数据访问接口创建dao包,包下创建接口
commentdao.java
import com.mongodb.mongodb.pojo.Comment;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface CommentDao extends MongoRepository<Comment,String> {
}
创建业务逻辑类
创建service包,包下创建类
import com.mongodb.mongodb.dao.CommentDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class CommentService {
@Autowired
private CommentDao commentDao;
}
在service层写整删改查代码
import com.mongodb.mongodb.dao.CommentDao;
import com.mongodb.mongodb.pojo.Comment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CommentService {
@Autowired
private CommentDao commentDao;
/*
* 保存一个评论
* */
public void saveComent(Comment comment){
//如果需要自定义主键,可以在这里指定主键,如果不指定主键,MongoDB会自动生成主键
//设置一些默认初始值、
//调用dao
commentDao.save(comment);
}
/*
* 更新一个评论
* */
public Comment updateComent(Comment comment){
//如果需要自定义主键,可以在这里指定主键,如果不指定主键,MongoDB会自动生成主键
//设置一些默认初始值、
//调用dao
return commentDao.save(comment);
}
/*
* 根据id删除评论
* */
public void deleteComent(String id){
//调用dao
commentDao.deleteById(id);
}
/*
* 根据id查询评论
* */
public Comment findComent(String id){
//调用dao
return commentDao.findById(id).get();
}
/*
* 查询所有评论
* */
public List<Comment> findCommentList(){
//调用dao
return commentDao.findAll();
}
}
在测试类进行测试
import com.mongodb.mongodb.pojo.Comment;
import com.mongodb.mongodb.service.CommentService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDateTime;
import java.util.List;
@SpringBootTest
class MongodbApplicationTests {
@Autowired
private CommentService commentService;
@Test
void contextLoads() {
List<Comment> commentList = commentService.findCommentList();
System.out.println(commentList);
}
@Test
void findById() {
Comment coment = commentService.findComent("62adb3de8adfd53d5fc5b580");
System.out.println(coment);
}
@Test
void saveComment() {
Comment comment = new Comment();
comment.setArticleid("10000");
comment.setContent("添加测试的数据");
comment.setCreatedatatime(LocalDateTime.now());
comment.setUserid("1003");
comment.setNicknane("凯撒大帝");
comment.setState("1");
comment.setLikenum(0);
comment.setReplynum(0);
commentService.saveComent(comment);
}
@Test
void Delete() {
commentService.deleteComent("62adb3de8adfd53d5fc5b580");
}
//修改
@Test
public void updateUser() {
Comment coment = commentService.findComent("62adb4806fa4c97e47e0a66e");
coment.setArticleid("13000");
coment.setContent("添加测试的数据");
coment.setCreatedatatime(LocalDateTime.now());
coment.setUserid("10");
coment.setNicknane("凯撒123大帝");
Comment save = commentService.updateComent(coment);
System.out.println(save);
}
}
分页功能
根据上级ID进行分页查询
commentdao新增方法定义
根据父id查询子评论的分页列表
Page<Comment>findByParentid(String partentid, Pageable pageable);
commentService
新增方法
public Page<Comment>findCommentListByParentid(String parentid,int page,int size){
return commentDao.findByParentid(parentid, PageRequest.of(page, size));
}
测试
//分页查询
@Test
public void testFindCommentByParentid(){
Page<Comment> page = commentService.findCommentListByParentid("2", 1, 2);
System.out.println(page.getTotalElements());
System.out.println(page.getTotalPages());
}
MongoTemplate实现评论点赞
如果使用CommentService新增updateThmbup方法
/*
* 点赞-效率低
* */
public void updateCommentbupToIncrementingOld(String id){
Comment comment = commentDao.findById(id).get();
comment.setLikenum(comment.getLikenum()+1);
commentDao.save(comment);
}
我们可以使用MongoTemplate类来实现对某列的操作
修改CommentService
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
/*
* 注入MongoTemplate
* */
@Autowired
private MongoTemplate mongoTemplate;
/*
* 点赞数+1
* */
@Test
public void updateCommentLikenum(String id){
//查询对象
Query query=Query.query(Criteria.where("_id").is(id));
//更新对象
Update update = new Update();
//局部刷新,相当于$set
//update.set(key,value);
//递增$inc
//update.inc("likenum",1);
update.inc("likenum");
//参数1:查询对象
//参数2:更新对象
//参数3:集合的名字或者实体类的类型Comment.class
mongoTemplate.updateFirst(query,update,"comment");
}
测试
/*
* 点赞数+1
* */
@Test
public void updateCommentLikenum(){
commentService.updateCommentLikenus("1");
}