【学习笔记】MongoDB与java整合

1. MongoDB入门

1.1 MongoDB 概念

1.1.1 什么是MongoDB

MongoDB 是在2007年由DoubleClick公司的几位核心成员开发出的一款分布式文档数据库,由C++语言编写。目的是为了解决数据大量增长的时候系统的可扩展性和敏捷性。MongoDB要比传统的关系型数据库简单很多。
在MongoDB中数据主要的组织结构就是数据库、集合和文档,文档存储在集合当中,集合存储在数据库中。MongoDB中每一条数据记录就是一个文档,数据结构由键值(key=>value)对组成。文档类似于 JSON 对象,它的数据结构被叫做BSON(Binary JSON)。

下表将帮助您更容易理解MongoDB中的一些概念:

RDBMSMongoDB
数据库数据库
表格集合
文档
字段
表联合嵌入文档
主键_id

1.1.2 MongoDB适用场景

MongoDB不需要去明确指定一张表的具体结构,对字段的管理非常灵活,有很强的可扩展性。

支持高并发、高可用、高可扩展性,自带数据压缩功能,支持海量数据的高效存储和访问。

支持基本的CRUD、数据聚合、文本搜索和地理空间查询功能。

适用场景:

  • 网站数据:Mongo非常适合实时的插入,更新与查询,并具备网站实时数据存储所需的复制及高度伸缩性。
  • 高伸缩性的场景:Mongo非常适合由数十或数百台服务器组成的数据库。
  • 大尺寸,低价值的数据:使用传统的关系型数据库存储一些数据时可能会比较昂贵,在此之前,很多时候程序员往往会选择传统的文件进行存储。
  • 缓存:由于性能很高,Mongo也适合作为信息基础设施的缓存层。在系统重启之后,由Mongo搭建的持久化缓存层可以避免下层的数据源过载。

例如:

弹幕、直播间互动信息、朋友圈信息、物流场景等

不适用场合:

  • 高度事务性系统:例如银行系统。传统的关系型数据库目前还是更适用于需要大量原子性复杂事务的应用程序。
  • 传统的商业智能应用:针对特定问题的BI数据库会对产生高度优化的查询方式。对于此类应用,数据仓库可能是更合适的选择。

1.2 安装和启动(docker方式)

1.2.1 拉取镜像

docker pull mongo:7.0.0

1.2.2 创建和启动容器

需要在宿主机建立文件夹

rm -rf /opt/mongo

mkdir -p /opt/mongo/data/db

docker run -d --restart=always -p 27017:27017 --name mongo -v /opt/mongo/data/db:/data/db mongo:7.0.0

1.2.3 进入容器

docker exec -it mongo mongosh

1.2.4 基本命令

show dbs
db.version() #当前db版本
db.getMongo() #查看当前db的链接机器地址
db.help() #帮助
quit() #退出命令行

1.3 数据库操作

1.3.1、创建数据库

如果数据库不存在,则创建数据库,否则切换到指定数据库。

use testdase

1.3.2 查看当前数据库

db.getName()

1.3.3 显示当前数据库状态

db.stats()

1.3.4 删除当前数据库

db.dropDatabase()

1.4 集合操作

1.4.1 创建集合

db.createCollection("User")

1.4.2 删除集合

db.User.drop()

1.5 文档操作

文档是一组键值(key-value)对。MongoDB 的文档不需要设置相同的字段,并且相同的字段不需要相同的数据类型,这与关系型数据库有很大的区别,也是 MongoDB 非常突出的特点。

需要注意的是:

1、MongoDB区分类型和大小写。

2、MongoDB的文档不能有重复的键。

1.5.1 insert

向User集合插入一条记录。可以预先使用createCollection方法创建集合,也可以不创建集合,直接插入数据,那么集合会被自动创建

db.User.insert({name:'zhangsan',age:21,sex:true})

1.5.2 query

查询当前User集合中所有的记录

db.User.find()

查询当前User集合中name是zhangsan的记录

db.User.find({name:"zhangsan"})

1.5.3 update

只更新匹配到的第一条记录

db.User.update({age:20}, {$set:{name:100}}) 

更新匹配到的所有记录

db.User.update({age:21}, {$set:{age:99}}, {multi: true})

1.5.4 remove

移除一个文档

db.User.remove(id)

移除所有文档

db.User.remove({}) 

更多命令参考:https://www.runoob.com/mongodb/mongodb-tutorial.html

2. SpringBoot集成MongoDB

spring-data-mongodb提供了MongoTemplateMongoRepository两种方式访问mongodb,MongoRepository操作简单,MongoTemplate操作灵活,我们在项目中可以灵活使用这两种方式操作mongodb。

2.1 集成spring-data-mongodb

2.1.1 导入依赖pom.xml:

     <!--mongodb-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-mongodb</artifactId>
     </dependency>

2.1.2 添加配置文件 application.yml

spring:
  data:
    mongodb:
      database: daijia
      host: 192.168.137.128
      port: 27017

2.1.3 添加实体

@Data
@Document("user") //指定mongodb中的集合名字
public class User {

    @Id //指定集合对应的主键
    private ObjectId id;
    private String name;
    private Integer age;
    private String email;
    private Date createDate;
}

2.2 MongoRepository

2.2.1 添加Repository类

类似MP模式,继承父类MongoRepository得到其中封装好的操作方法,就可以直接调用

//泛型第一个参数指代操作的实体类对象
//泛型第二个参数指代操作的实体类对象的主键类型是什么
public interface UserRepository extends MongoRepository<User, ObjectId> {
}

2.2.2 创建测试类

test目录创建测试类:MongoRepositoryTest

@SpringBootTest
public class MongoRepositoryTest {

    @Autowired
    private UserRepository userRepository;  
}
2.2.2.1 插入
    @Test
    public void testCreateUser(){

        User user = new User();
        user.setName("cc");
        user.setAge(20);
        user.setCreateDate(new Date());
        userRepository.save(user);
    }
2.2.2.2 查询所有
    @Test
    public void testFindAll(){
        List<User> userList = userRepository.findAll();
        System.out.println(userList);
    }
2.2.2.3 根据id查询
    @Test
    public void testFindById(){

        Optional<User> optional = userRepository.findById(
                new ObjectId("64eee9dfadni823c62b4faf")
        );
        boolean present = optional.isPresent();
        if(present){
            User user = optional.get();
            System.out.println(user);
        }
    }
2.2.2.4 条件查询
    @Test
    public void testFindAllExample(){

        User user = new User();
        user.setAge(19);
        //封装条件对象Example
        Example<User> example = Example.of(user);
        List<User> userList = userRepository.findAll(example);
        System.out.println(userList);
    }
2.2.2.5 排序查询
    @Test
    public void testFindAllSort(){
   		 //根据age字段降序排列
        Sort sort = Sort.by(Sort.Direction.DESC, "age");
        List<User> userList = userRepository.findAll(sort);
        System.out.println(userList);
    }
2.2.2.6 分页查询
    @Test
    public void testFindAllPage(){
		//pagereques作为一个分页请求器规定数据按照从0开始每页十条记录返回
        PageRequest pageRequest = PageRequest.of(0, 10);
        Page<User> page = userRepository.findAll(pageRequest);
        int totalPages = page.getTotalPages();
        List<User> userList = page.getContent();
        System.out.println(userList);
        System.out.println(totalPages);
    }
2.2.2.7 更新
    @Test
    public void testUpdateUser(){

        //注意:先查询,再更新
        Optional<User> optional = userRepository.findById(
                new ObjectId("64eee9dff317c823c62b4faf")
        );
        if(optional.isPresent()){
            User user = optional.get();
            user.setAge(100);
            //user中包含id,就会执行更新
            userRepository.save(user);
            System.out.println(user);
        }
    }
2.2.2.8 删除
    @Test
    public void testDeleteUser(){
        userRepository.deleteById(
                new ObjectId("64eee9dff317c823c62b4faf")
        );
    }
2.2.2.9 自定义方法

命名规则:

  1. 查询方法名称 以 get | find | read开头
  2. 后面查询字段名称,满足驼峰式命名,比如OrderId
  3. 字段查询条件添加关键字,比如Like OrderBy Asc等
	//在其中直接声明方法,而不用写具体逻辑!!!
	userRepository.findOrderIdOrderByCreateTimeAsc(orderId);

2.3 MongoTemplate

test目录创建测试类:MongoTemplateTest

@SpringBootTest
public class MongoTemplateTest {

    @Autowired
    private MongoTemplate mongoTemplate;
}

2.3.1 添加

    @Test
    public void testCreateUser(){
        User user = new User();
        user.setAge(20);
        user.setName("test");
        user.setEmail("test@qq.com");
        mongoTemplate.insert(user);
        System.out.println(user);
    }

2.3.2 查询所有

    @Test
    public void testFindUser() {
        List<User> userList = mongoTemplate.findAll(User.class);
        System.out.println(userList);
    }

2.3.3 根据id查询

    @Test
    public void testFindUserById(){
        User user = mongoTemplate.findById("64eeeae31711344f35635788", User.class);
        System.out.println(user);
    }

2.3.4 删除

    @Test
    public void testRemove() {
    	//条件器可以一直and拼接条件下去
        Criteria criteria = Criteria.where("_id").is("64eeeae31711344f35635788");
        Query query = new Query(criteria);
        DeleteResult result = mongoTemplate.remove(query, User.class);
        long count = result.getDeletedCount();
        System.out.println(count);
    }

2.3.5 条件查询 and

    @Test
    public void findUserList() {
		//WHERE 'name' = "test" AND 'age' = 20;
        Criteria criteria = Criteria.where("name").is("test").and("age").is(20);
        Query query = new Query(criteria);

        List<User> userList = mongoTemplate.find(query, User.class);
        System.out.println(userList);
    }

2.3.6 分页查询

    @Test
    public void findUsersPage() {
        Query query = new Query();
        //先查询总记录数
        long count = mongoTemplate.count(query, User.class);
        System.out.println(count);
        //后查询分页列表
        List<User> userList = mongoTemplate.find(query.skip(0).limit(2), User.class);
        System.out.println(userList);
    }

2.3.7 修改

    @Test
    public void testUpdateUser() {
        Criteria criteria = Criteria.where("_id").is("64eeeae31711344f35635788");
        Query query = new Query(criteria);
        Update update = new Update();
        update.set("name", "zhangsan");
        update.set("age", 99);
        UpdateResult result = mongoTemplate.upsert(query, update, User.class);//改一条
        //UpdateResult result = mongoTemplate.updateMulti(query, update, User.class);//改多条
        long count = result.getModifiedCount();
        System.out.println(count);
    }
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值