MongoDb 关系型数据库Mysql
数据库(databases) 数据库(databases)
集合(collections) 表(table)
文档(document) 行(row)
下表是MongoDB与MySQL数据库逻辑结构概念的对比
window系统MongoDB安装
双击“资源\微服务相关\配套软件\mongodb”中的“mongodb-win32-x86_64-2008plus�ssl-3.2.10-signed.msi” 按照提示步骤安装即可。安装完成后,软件会安装在C:\Program
Files\MongoDB 目录中。
我们要启动的服务程序就是C:\Program Files\MongoDB\Server\3.2\bin目录下的
mongod.exe,为了方便我们每次启动,我将C:\Program
Files\MongoDB\Server\3.2\bin 设置到环境变量path中。
启动
(1)首先打开命令提示符,创建一个用于存放数据的目录
md d:\data
(2)启动服务
mongod ‐‐dbpath=d:\data
我们在启动信息中可以看到,mongoDB的默认端口是27017
在命令提示符输入即可完成登录 mongo
退出mongodb exit
Docker 环境下MongoDB安装
docker run ‐di ‐‐name=tensquare_mongo ‐p 27017:27017 mongo
远程登陆 命令提示符 mongo 192.168.184.134
常用命令
use spitdb #选择和创建数据库
db.集合名称.insert(数据) #以插入以下测试数据
db.spit.insert({content:"听说十次方课程很给力呀",userid:"1011",nickname:"小
雅",visits:NumberInt(902)})
db.spit.find() #查询素有数据
这里你会发现每条文档会有一个叫_id的字段,这个相当于我们原来关系数据库中表的主
键,当你在插入文档记录时没有指定该字段,MongoDB会自动创建,其类型是ObjectID
类型。如果我们在插入文档记录时指定该字段也可以,其类型可以是ObjectID类型,也
可以是MongoDB支持的任意类型。
输入以下测试语句:
db.spit.insert({_id:"1",content:"我还是没有想明白到底为啥出
错",userid:"1012",nickname:"小明",visits:NumberInt(2020)});
db.spit.insert({_id:"2",content:"加班到半夜",userid:"1013",nickname:"凯
撒",visits:NumberInt(1023)});
db.spit.insert({_id:"3",content:"手机流量超了咋
办?",userid:"1013",nickname:"凯撒",visits:NumberInt(111)});
db.spit.insert({_id:"4",content:"坚持就是胜利",userid:"1014",nickname:"诺
诺",visits:NumberInt(1223)});
如果我想按一定条件来查询,比如我想查询userid为1013的记录,怎么办?很简单!只
要在find()中添加参数即可,参数也是json格式,如下:
db.spit.find({userid:'1013'})
如果你只需要返回符合条件的第一条数据,我们可以使用findOne命令来实现
db.spit.findOne({userid:'1013'})
如果你想返回指定条数的记录,可以在find方法后调用limit来返回结果,例如:
db.spit.find().limit(3)
修改与删除文档
db.集合名称.update(条件,修改后的数据)
db.spit.update({_id:"1"},{visits:NumberInt(1000)})
执行后,我们会发现,这条文档除了visits字段其它字段都不见了,为了解决这个问题,
我们需要使用修改器$set来实现,命令如下
db.spit.update({_id:"2"},{$set:{visits:NumberInt(2000)}})
删除文档的语法结构:
db.集合名称.remove(条件)
以下语句可以将数据全部删除,请慎用
db.spit.remove({})
如果删除visits=1000的记录,输入以下语句
db.spit.remove({visits:1000})
统计记录条件使用count()方法。以下语句统计spit集合的记录数
db.spit.count()
如果按条件统计 ,例如:统计userid为1013的记录条数
db.spit.count({userid:"1013"})
模糊查询
db.spit.find({content:/流量/})
如果要查询吐槽内容中以“加班”开头的,代码如下:
db.spit.find({content:/^加班/})
大于 小于 不等于
<, <=, >, >= 这个操作符也是很常用的,格式如下:
db.集合名称.find({ "field" : { $gt: value }}) // 大于: field > value
db.集合名称.find({ "field" : { $lt: value }}) // 小于: field < value
db.集合名称.find({ "field" : { $gte: value }}) // 大于等于: field >= value
db.集合名称.find({ "field" : { $lte: value }}) // 小于等于: field <= value
db.集合名称.find({ "field" : { $ne: value }}) // 不等于: field != value
示例:查询吐槽浏览量大于1000的记录
db.spit.find({visits:{$gt:1000}})
包含与不包含
包含使用$in操作符。
示例:查询吐槽集合中userid字段包含1013和1014的文档
db.spit.find({userid:{$in:["1013","1014"]}})
不包含使用$nin操作符。
示例:查询吐槽集合中userid字段不包含1013和1014的文档
db.spit.find({userid:{$nin:["1013","1014"]}})
条件连接
示例:查询吐槽集合中visits大于等于1000 并且小于2000的文档
db.spit.find({$and:[ {visits:{$gte:1000}} ,{visits:{$lt:2000} }]})
如果两个以上条件之间是或者的关系,我们使用 操作符进行关联,与前面and的使用
方式相同
示例:查询吐槽集合中userid为1013,或者浏览量小于2000的文档记录
db.spit.find({$or:[ {userid:"1013"} ,{visits:{$lt:2000} }]})
列值增长
如果我们想实现对某列值在原有值的基础上进行增加或减少,可以使用$inc运算符来实现
db.spit.update({_id:"2"},{$inc:{visits:NumberInt(1)}} )
Java操作MongoDB
创建工程 mongoDemo, 引入依赖
<dependencies>
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb‐driver</artifactId>
<version>3.6.3</version>
</dependency>
</dependencies>
创建测试类
/**
* MongoDb入门小demo
*/
public class MongoDemo {
public static void main(String[] args) {
MongoClient client=new MongoClient("192.168.184.134");//创建连接
MongoDatabase spitdb = client.getDatabase("spitdb");//打开数据库
MongoCollection<Document> spit = spitdb.getCollection("spit");//
获取集合
FindIterable<Document> documents = spit.find();//查询记录获取文档集
合
for(Document document:documents){ //
System.out.println("内容:"+ document.getString("content"));
System.out.println("用户ID:"+document.getString("userid"));
System.out.println("浏览量:"+document.getInteger("visits"));
}
client.close();//关闭连接
}
}
条件查询
BasicDBObject对象:表示一个具体的记录,BasicDBObject实现了DBObject,是key�value的数据结构,用起来和HashMap是基本一致的。
查询userid为1013的记录
获取集合
BasicDBObject bson=new BasicDBObject("userid","1013");// 构建查询
条件
FindIterable<Document> documents = spit.find(bson);//查询记录获取结
果集合
for(Document document:documents){ //
System.out.println("内容:"+ document.getString("content"));
System.out.println("用户ID:"+document.getString("userid"));
System.out.println("浏览量:"+document.getInteger("visits"));
}
client.close();//关闭连接
}
查询浏览量大于1000的记录
获取集合
BasicDBObject bson=new BasicDBObject("visits",new
BasicDBObject("$gt",1000) );// 构建查询条件
FindIterable<Document> documents = spit.find(bson);//查询记录获取结
果集合
for(Document document:documents){ //
System.out.println("内容:"+ document.getString("content"));
System.out.println("用户ID:"+document.getString("userid"));
System.out.println("浏览量:"+document.getInteger("visits"));
}
client.close();//关闭连接
}
插入数据
获取集合
Map<String,Object> map=new HashMap();
map.put("content","我要吐槽");
map.put("userid","9999");
map.put("visits",123);
map.put("publishtime",new Date());
Document document=new Document(map);
spit.insertOne(document);//插入数据
client.close();
}
SpringDataMongoDB
####### pom.xml引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐data‐mongodb</artifactId>
</dependency>
<dependency>
<groupId>com.tensquare</groupId>
<artifactId>tensquare_common</artifactId>
<version>1.0‐SNAPSHOT</version>
</dependency>
创建application.yml
server:
port: 9006
spring:
application:
name: tensquare‐spit #指定服务名
data:
mongodb:
host: 192.168.184.134
database: spitdb
创建启动类
创建实体类
/**
* 吐槽
* @author Administrator
*
*/
public class Spit implements Serializable{
@Id
private String _id; //mongodb默认主键带_
private String content;
private Date publishtime;
private String userid;
private String nickname;
private Integer visits;
private Integer thumbup;
private Integer share;
private Integer comment;
private String state;
private String parentid;
// getter and setter .....
}
dao
/**
* 吐槽数据访问层
* @author Administrator
*
*/
public interface SpitDao extends MongoRepository<Spit, String>{
}
创建业务逻辑类
@Service
public class SpitService {
@Autowired
private SpitDao spitDao;
@Autowired
private IdWorker idWorker;
/**
* 查询全部记录
* @return
*/
public List<Spit> findAll(){
return spitDao.findAll();
}
/**
* 根据主键查询实体
* @param id
* @return
*/
public Spit findById(String id){
Spit spit = spitDao.findById(id).get();
return spit;
}
/**
* 增加
* @param spit
*/
public void add(Spit spit) {
spit.set_id(idWorker.nextId()+""); //主键值
spitDao.save(spit);
}
/**
* 修改
* @param spit
*/
public void update(Spit spit) {
北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090
(4)com.tensquare.spit包下创建controller类
public void update(Spit spit) {
spitDao.save(spit);
}
/**
* 删除
* @param id
*/
public void deleteById(String id) {
spitDao.deleteById(id);
}
}
创建controller类
@RestController
@CrossOrigin
@RequestMapping("/spit")
public class SpitController {
@Autowired
private SpitService spitService;
/**
* 查询全部数据
* @return
*/
@RequestMapping(method= RequestMethod.GET)
public Result findAll(){
return new Result(true, StatusCode.OK,"查询成
功",spitService.findAll());
}
/**
* 根据ID查询
* @param id ID
* @return
*/
@RequestMapping(value="/{id}",method=RequestMethod.GET)
public Result findOne(@PathVariable String id){
return new Result(true,StatusCode.OK,"查询成
功",spitService.findById(id));
}
/**
* 增加
* @param spit
*/
@RequestMapping(method=RequestMethod.POST)
public Result add(@RequestBody Spit spit ){
spitService.add(spit);
return new Result(true,StatusCode.OK,"增加成功");
}
/**
北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090
4.2.3 根据上级ID查询吐槽列表
(1)SpitDao新增方法定义
(2)SpitService新增方法
* 修改
* @param spit
*/
@RequestMapping(value="/{id}",method=RequestMethod.PUT)
public Result update(@RequestBody Spit spit,@PathVariable String id )
{
spit.set_id(id);
spitService.update(spit);
return new Result(true,StatusCode.OK,"修改成功");
}
/**
* 删除
* @param id
*/
@RequestMapping(value="/{id}",method=RequestMethod.DELETE)
public Result deleteById(@PathVariable String id ){
spitService.deleteById(id);
return new Result(true,StatusCode.OK,"删除成功");
}
}
根据上级ID查询吐槽列表
dao
/**
* 根据上级ID查询吐槽列表(分页)
* @param parentid
* @param pageable
* @return
*/
public Page<Spit> findByParentid(String parentid,Pageable pageable);
SpitService新增方法
/**
* 根据上级ID查询吐槽列表
* @param parentid
* @param page
* @param size
* @return
*/
public Page<Spit> findByParentid(String parentid,int page, int size){
PageRequest pageRequest = PageRequest.of(page‐1, size);
return spitDao.findByParentid(parentid, pageRequest);
}
SpitController新增方法
/**
* 根据上级ID查询吐槽分页数据
* @param page
* @param size
* @return
*/
@RequestMapping(value="/comment/{parentId}/{page}/{size}",method=RequestM
ethod.GET)
public Result findByParentid(@PathVariable String parentId,
@PathVariable int page,@PathVariable int size){
Page<Spit> pageList = spitService.findByParentid(parentId,page,
size);
return new Result(true,StatusCode.OK,"查询成功",new
PageResult<Spit>(pageList.getTotalElements(), pageList.getContent() ) );
}
吐槽点赞
我们看一下以下点赞的代码: SpitService 新增updateThumbup方法
/**
* 点赞
* @param id
*/
public void updateThumbup(String id){
Spit spit = spitDao.findById(id).get();
spit.setThumbup(spit.getThumbup()+1);
spitDao.save(spit);
}
以上方法虽然实现起来比较简单,但是执行效率并不高,因为我只需要将点赞数加1就可
以了,没必要查询出所有字段修改后再更新所有字段。
我们可以使用MongoTemplate类来实现对某列的操作。
修改SpitService
@Autowired
private MongoTemplate mongoTemplate;
/**
* 点赞
* @param id
*/
public void updateThumbup(String id){
Query query=new Query();
query.addCriteria(Criteria.where("_id").is(id));
Update update=new Update();
update.inc("thumbup",1);
mongoTemplate.updateFirst(query,update,"spit");
}
SpitController新增方法
/**
* 点赞
* @param id
* @return
*/
@RequestMapping(value="/thumbup/{id}",method=RequestMethod.PUT)
public Result updateThumbup(@PathVariable String id){
spitService.updateThumbup(id);
return new Result(true,StatusCode.OK,"点赞成功");
}
通过redis控制不能重复点赞
首先引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring‐boot‐starter‐data‐redis</artifactId>
</dependency>
修改application.yml
redis:
host: 192.168.184.135
修改SpitController代码逻辑
@Autowired
private RedisTemplate redisTemplate;
/**
* 吐槽点赞
* @param id
* @return
*/
@RequestMapping(value = "/thumbup/{id}", method = RequestMethod.PUT)
public Result updateThumbup(@PathVariable String id){
//判断用户是否点过赞
String userid="2023";// 后边我们会修改为当前登陆的用户
if(redisTemplate.opsForValue().get("thumbup_"+userid+"_"+
id)!=null){
return new Result(false,StatusCode.REPERROR,"你已经点过赞了");
}
spitService.updateThumbup(id);
redisTemplate.opsForValue().set( "thumbup_"+userid+"_"+ id,"1");
return new Result(true,StatusCode.OK,"点赞成功");
}
修改SpitService的add方法
/**
* 发布吐槽(或吐槽评论)
* @param spit
*/
public void add(Spit spit){
spit.set_id( idWorker.nextId()+"" );
spit.setPublishtime(new Date());//发布日期
spit.setVisits(0);//浏览量
spit.setShare(0);//分享数
spit.setThumbup(0);//点赞数
spit.setComment(0);//回复数
spit.setState("1");//状态
if(spit.getParentid()!=null && !"".equals(spit.getParentid())){//
如果存在上级ID,评论
Query query=new Query();
query.addCriteria(Criteria.where("_id").is(spit.getParentid()));
Update update=new Update();
update.inc("comment",1);
mongoTemplate.updateFirst(query,update,"spit");
}
spitDao.save(spit);
}
网友评论