MongoDB的基本介绍及SpringBoot整合MongoDB

MongoDB的基本介绍及SpringBoot整合MongoDB

1 MongoDB基本概念

1.1 NoSQL

NoSQL(Not Only SQL),意为反SQL。

NoSQL好处:

  1. 对数据库高并发读写
  2. 对海量数据的高效率存储和访问
  3. 对数据库的高可扩展性和高可用性

NoSQL不足:

  1. 数据库事务的一致性需求
  2. 数据库的写实性和读时性需求
  3. 对复杂的SQL查询,特别时多表联查的需求

1.2 MongoDB

1.2.1 与关系型数据库对应关系

MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。
在高负载的情况下,添加更多的节点,可以保证服务器性能。
MongoDB 旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB 将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

在这里插入图片描述

  • 部分术语:
    在这里插入图片描述

  • 与关系型数据库的对应关系:
    在这里插入图片描述

注意:

1. 文档中键/值对是有序的
2. 文档中的值不仅可以是String还是可以其他的【类比JSON】
3. MongoDB区分大小写
4. MongoDB不能有重复的键
5. 文档的键是字符串。(存在特例)

文档键命名规范:
1、键不能含有\0 (空字符)。这个字符用来表示键的结尾。
2、.和$有特别的意义,只有在特定环境下才能使用。
3、以下划线"_"开头的键是保留的(不是严格要求的)。

1.2.2 数据类型

在这里插入图片描述
在这里插入图片描述

1.2.3 适用场景
  • 适用场景:
    • 网站数据:Mongo适合实时的插入、更新与查询数据
    • 缓存:性能高,可以作为缓存使用
    • 数据价值低:传统的RDB有些比较昂贵
    • 高伸缩:适合由十台或数百台组成的数据库
    • 存储对象或JSON
  • 不适用:
    • 高事务性系统
    • 传统的商业智能应用
1.2.4 基于Docker安装和使用MongoDB
  1. 启动docker
sudo systemctl start docker
  1. 拉取mongoDB镜像

此处拉取最新的mongo镜像

docker pull mongo:latest

在这里插入图片描述

  1. 创建和启动容器
docker run -d --restart=always -p 27017:27017 --name mymongo -v/data/db:/data/db -d mongo

在这里插入图片描述

  1. 进入容器
docker exec -it mymongo /bin/bash
  1. 进入mongo自带的客户端进行操作(就像登录MySQL的客户端一样)
mongo

在这里插入图片描述

常见命令汇总:

1、 Help查看命令提示 
db.help();
2、 切换/创建数据库
use test
如果数据库不存在,则创建数据库,否则切换到指定数据库
3、 查询所有数据库 
show dbs;
4、 删除当前使用数据库 
db.dropDatabase();
5、 查看当前使用的数据库 
db.getName();
6、 显示当前db状态 
db.stats();
7、 当前db版本 
db.version();
8、 查看当前db的链接机器地址 
db.getMongo〇;

在这里插入图片描述

【1】Insert
> db.User.save({name:'zhangsan',age:21,sex:true})
> db.User.find()
{"_id": Objectld("4f69e680c9106ee2ec95da66"), "name": "zhangsan", "age": 21,
"sex": true}

MongoDB会自动为我们生成ID
在这里插入图片描述

【2】Query
1、 Where
# select * from User where name = 'zhangsan'
> db.User.find({name:"zhangsan"})

2、 FIELDS
# select name, age from User where age = 21
> db.User.find({age:21}, {'name':1, 'age':1})

3、SORT
`在 MongoDB 中使用 sort() 方法对数据进行排序,sort() 方法可以通过参数指定排序的字段,
并使用 1 和 -1 来指定排序的方式,其中 1 为升序排列,而 -1 是用于降序排列。`
# select * from User order by age
> db.User.find().sort({age:1})

4、SUCE(分页)
在 MongoDB 中使用 limit()方法来读取指定数量的数据,skip()方法来跳过指定数量的数据
# select * from User skip 2 limit 3
> db.User.find().skip(0).limit(3)

5、IN
# select * from User where age in (21, 26, 32)
> db.User.find({age:{$in:[21,26,32]}})

6、COUNT
# select count(*) from User where age >20
> db.User.find({age:{$gt:20}}).count()

7、OR
# select * from User where age = 21 or age = 28
> db.User.find({$or:[{age:21}, {age:28}]})
【4】UPDATE
# update Userset age = 100, sex = 0 where name = 'user1'
> db.User.update({name:"zhangsan"}, {$set:{age:100, sex:0}})

Update()有几个参数需要注意。
db.collection.update(criteria, objNew, upsert, mult)
criteria:需要更新的条件表达式
objNew:更新表达式
upsert:如FI标记录不存在,是否插入新文档。 
multi:是否更新多个文档。
【5】REMOVE
> db.User.remove(id)
//移除对应id的行
> db.User.remove({})
//移除所有

2 SpringBoot整合MongoDB

2.1 创建项目引入依赖

创建一个Boot项目,在pom文件中,引入依赖

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

    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>

    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.10.1</version>
    </dependency>

    <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>
</dependencies>

2.2 修改配置文件为Mongo地址

spring.data.mongodb.uri=mongodb://47.93.118.241:27017/test

2.3 使用封装好的类完成CRUD开发

2.3.1 基于MongoTemplate开发CRUD

①添加实体

@Data
@Document("User")
public class User {

    @Id
    private String id;
    private String name;
    private Integer age;
    private String email;
    private String createDate;
}

②实现
常用方法及Query对象:

常用方法
mongoTemplate.findAll(User.class): 查询User文档的全部数据
mongoTemplate.findById(<id>, User.class): 查询User文档id为id的数据
mongoTemplate.find(query, User.class);: 根据query内的查询条件查询
mongoTemplate.update(query, update, User.class): 修改
mongoTemplate.remove(query, User.class): 删除
mongoTemplate.insert(User): 新增

Query对象
1、创建一个query对象(用来封装所有条件对象),再创建一个criteria对象(用来构建条件)
2、 精准条件:criteria.and(“key”).is(“条件”)
模糊条件:criteria.and(“key”).regex(“条件”)
3、封装条件:query.addCriteria(criteria)
4、大于(创建新的criteria):Criteria gt = Criteria.where(“key”).gt(“条件”)
小于(创建新的criteria):Criteria lt = Criteria.where(“key”).lt(“条件”)
5、Query.addCriteria(new Criteria().andOperator(gt,lt));
6、一个query中只能有一个andOperator()。其参数也可以是Criteria数组。
7、排序 :query.with(new Sort(Sort.Direc

update 为更新操作符
upsert 为布尔型可选项,表示如果不存在 update 的记录,是否插入这个新的文档。true 为插入;默认为 false,不插入

【Insert、Query】
@SpringBootTest
public class DemomogoApplicationTests {

    @Autowired
    private MongoTemplate mongoTemplate;

    //添加
    @Test
    public void createUser() {
        User user = new User();
        user.setAge(20);
        user.setName("test");
        user.setEmail("4932200@qq.com");
        User user1 = mongoTemplate.insert(user);
        System.out.println(user1);
        //自动生成的id:6339085189a1b05972d7682b
    }

    //查询所有
    @Test
    public void findUser(){
        //再添加一个用户
        User user = new User();
        user.setAge(23);
        user.setName("CR7");
        mongoTemplate.insert(user);
        List<User> userList = mongoTemplate.findAll(User.class);
        System.out.println(userList);
        //[User(id=6339085189a1b05972d7682b, name=test, age=20, email=4932200@qq.com, createDate=null),
        // User(id=633953a28d2c574bbf3e0d1e, name=CR7, age=23, email=null, createDate=null)]
    }

    //根据id查询
    @Test
    public void getById(){
        User user = mongoTemplate.findById("6339085189a1b05972d7682b", User.class);
        System.out.println(user);
        //User(id=6339085189a1b05972d7682b, name=test, age=20, email=4932200@qq.com, createDate=null)
    }

    @Test
    public void findUserByCon(){
        //构造条件,相当于where后面的语句
        Query query = new Query(Criteria.where("name").is("test")
                .and("age").is(20));
        List<User> userList = mongoTemplate.find(query, User.class);
        System.out.println(userList);
        //[User(id=6339085189a1b05972d7682b, name=test, age=20, email=4932200@qq.com, createDate=null)]
    }


    //模糊查询
    @Test
    public void findUsersLikeName(){
        String name = "est";
        //正则
        String regex = String.format("%s%s%s", "^.*", name, ".*$");
        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        Query query = new Query(Criteria.where("name").regex(pattern));
        List<User> userList = mongoTemplate.find(query, User.class);
        System.out.println(userList);
    }

    //分页查询
    @Test
    public void findUserByPage(){
        String name = "est";
        int pageNo = 1;
        int pageSize = 10;

        Query query = new Query();
        String regex = String.format("%s%s%s", "^.*", name, ".*$");
        Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
        query.addCriteria(Criteria.where("name").regex(pattern));
        int totalCount = (int)mongoTemplate.count(query, User.class);
        List<User> userList = mongoTemplate.find(query.skip((pageNo - 1) * pageSize).limit(pageSize), User.class);

        Map<String, Object> pageMap = new HashMap<>();
        pageMap.put("list", userList);
        pageMap.put("totalCount", totalCount);
        System.out.println(pageMap);
        //{list=[User(id=6339085189a1b05972d7682b, name=test, age=20, email=4932200@qq.com, createDate=null)], totalCount=1}
    }
}
【UPDATE、REMOVE】
    //修改
    @Test
    public void updateUser(){
        User user = mongoTemplate.findById("6339085189a1b05972d7682b", User.class);
        user.setName("Neymar");
        user.setAge(28);
        user.setEmail("28172349@qq.com");
        Query query = new Query(Criteria.where("_id").is(user.getId()));
        Update update = new Update();
        update.set("name", user.getName());
        update.set("age", user.getAge());
        update.set("email", user.getEmail());
        //upsert与update不同,upsert	为布尔型可选项,表示如果不存在 update 的记录,
        // 是否插入这个新的文档。true 为插入;默认为 false,不插入
        UpdateResult result = mongoTemplate.upsert(query, update, User.class);
        long count = result.getModifiedCount();
        System.out.println(count);//1
    }


    //删除操作
    @Test
    public void delete(){
        Query query = new Query(Criteria.where("_id").is("6339085189a1b05972d7682b"));
        DeleteResult result = mongoTemplate.remove(query, User.class);
        long count = result.getDeletedCount();
        System.out.println(count);//1
    }

2.3.2 基于MongoRepository开发CRUD

SpringData提供了对Mongodb数据访问的支持,我们继承MongoRepository类,按照SpringData规范就可以了,默认会帮我们实现

SpringData定义方法规范:
在这里插入图片描述
在这里插入图片描述

1、 不是随便声明的,而需要符合一定的规范
2、 查询方法以find | read | get开头
3、 涉及条件查询时,条件的属性用条件关键字连接
4、 要注意的是:条件属性首字母需要大写
5、 支持属性的级联查询,但若当前类有符合条件的属性则优先使用,而不使用级联属性,
	若需要使用级联属性,则属性之间使用_强制进行连接

①创建对应记录(相当于实体类)

@Data
@Document("User")
public class User {

    @Id
    private String id;
    private String name;
    private Integer age;
    private String email;
    private String createDate;
}

②创建UserRepository

@Repository
public interface UserRepository extends MongoRepository<User, String> {
}

③创建测试类

@SpringBootTest
public class MongoTestApplication2 {

    @Autowired
    private UserRepository userRepository;

    //添加
    @Test
    public void createUser(){
        User user = new User();
        user.setAge(24);
        user.setName("张三");
        user.setEmail("41324213@qq.com");
        User user1 = userRepository.save(user);
    }

    //根据id查询
    @Test
    public void getById(){
        User user = userRepository.findById("63395d16b77a6d19b73d6855").get();
        System.out.println(user);
    }

    //条件查询
    @Test
    public void findUserByCon(){
        User user = new User();
        user.setName("张三");
        Example<User> userExample = Example.of(user);
        List<User> userList = userRepository.findAll(userExample);
        System.out.println(userList);
        //User(id=63395d16b77a6d19b73d6855, name=张三, age=24, email=41324213@qq.com, createDate=null)
    }

    //模糊查询
    @Test
    public void findUserLikeName(){
        //创建匹配器
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)//改变默认匹配方式:模糊查询
                .withIgnoreCase(true);//改变默认大小写忽略方式:忽略大小写
        User user = new User();
        user.setName("三");
        Example<User> userExample = Example.of(user, matcher);
        List<User> userList = userRepository.findAll(userExample);
        System.out.println(userList);
    }


    //分页查询
    @Test
    public void findUserPage(){
        Sort sort = Sort.by(Sort.Direction.DESC, "age");
        PageRequest pageable = PageRequest.of(0, 10, sort);//0为第一页
        //创建匹配器
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)//用模糊查询
                .withIgnoreCase(true);//忽略大小写
        User user = new User();
        user.setName("三");
        //创建实例
        Example<User> example = Example.of(user, matcher);
        Page<User> pages = userRepository.findAll(example, pageable);
        System.out.println(pages.getTotalElements());//1
    }

    //修改
    @Test
    public void update(){
        User user = userRepository.findById("63395d16b77a6d19b73d6855").get();
        user.setName("张三儿~");
        user.setAge(29);
        User save = userRepository.save(user);
        System.out.println(save);
        //User(id=63395d16b77a6d19b73d6855, name=张三儿~, age=29, email=41324213@qq.com, createDate=null)
    }

    //删除
    @Test
    public void delete(){
        userRepository.deleteById("63395d16b77a6d19b73d6855");
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值