MongoDB的入门操作02
1.聚合操作
MongoDB聚合框架(Aggregation Framewordk) 是一个计算框架,他可以作用在一个或集合集合中
对集合中的数据进行一系列运算将这些数据转化为期望的形式
从效果而言, 聚合框架相当于SQL查询中Group by left join
2.文档设计
1>数据库三范式
第一范式:数据库的原子性,在同一列中,每一行只能有一个值,比如列名为hobby,该列的每行就只能有一个值
第二范式:要求每一行或实例都要被一个唯一的主键进行区别
第三范式:要求在表中不能包含其他表的非主键字段信息,外键要拿其他表的主键连
2>打破第三范式(设计冗余字段)
在非关系型数据库中,为了减少连表所增多的CRUD代码,打破第三范式,增加的外键可以不是其他集合的主键,设计冗余字段。
3>mongodb 文档怎么体现关联关系 (一对一,多对一,多对多)
一对一
多对多(多对一)
3.springboot集成
1>集成操作步骤
导入依赖,配置application.properties,配置主配置文件;配置Mongodb的接口文件,里面有很多集成好的方法
/**
* 继承的MongoRepository接口中,
* 泛型1是对应的domain包中的实体类
* 泛型2是该类的对应的文档主键
* 记得贴上Repository注解,该类的对象交由spring容器管理
*/
@Repository
public interface UserRepository extends MongoRepository<User,ObjectId> {
User findByName(String name);
}
2>用户的CRUD(mongodb版)
@Service
public class UserServiceImpl implements IUserService {
@Autowired
private UserRepository repository;
public void save(User user) {
repository.save(user);
}
public void delete(String id) {
repository.deleteById(new ObjectId(id));
}
public void update(User user) {
repository.save(user);
}
public User get(String id) {
Optional<User> User = repository.findById(new ObjectId(id));
return User.orElse(null);
}
public List<User> list() {
List<User> list = repository.findAll();
return list;
}
注意:
1)添加或者更新都是使用save方法,因为insert会额外报一个异常
insert: 若新增数据的主键已经存在,则会抛 org.springframework.dao.DuplicateKeyException 异常提示主键重复,不保存当前数据。
save: 若新增数据的主键已经存在,则会对当前已经存在的数据进行修改操作。
2)在进行findById(new ObjectId(id))操作时,返回的是一个Optional类型的对象
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
Optional 类的引入很好的解决空指针异常。
此时再使用**T orElse(T other)**方法,判断容器内的值,如果存在该值,返回值, 否则返回 other。
3>JPA查询规范
通过调用Repository接口中的方法来进行查询,或者调用继承Repository接口的类的方法来进行对数据库的CRUD操作,就是JPA查询规范了,比如上面的Impl类,还可以在其中添加一个方法
@Repository
public interface UserRepository extends MongoRepository<User,ObjectId> {
User findByName(String name); //添加查询姓名的方法
}
/impl/UserImpl
public User findByName(String name) {
return repository.findByName(name);
}
4>MongoTmeplate查询操作(当Repository接口的方法满足不了复杂的查询操作)
//MongoDB所有数据操作都可以
@Autowired
private MongoTemplate template;
//查询所有name含有zou并且30<=age<=32的文档
public void testQuery(){
//查询对象 :理解MQL语句拼接对象
Query query = new Query();
//Criteria :条件封装对象
Criteria criteria = new Criteria();
criteria.andOperator(
Criteria.where("name").regex("fei"),
Criteria.where("age").lte(32).gte(30)
);
query.addCriteria(criteria);
List<User> list = template.find(query, User.class, "users");
}
4.JPA规范,里面所有的关键词,建议自定义对应方法
关键字 | 例子 | JPQL |
---|---|---|
And | findByNameAndAge(String name,Integer age) | where name = ? and age = ? |
Or | findByNameOrAge(String name,Integer age) | where name = ? or age = ? |
Is | findByName(String name) | where name = ? |
Between | findByAgeBetween(Integer min,Integer max) | where age between ? and ? |
LessThan | findByAgeLessThan(Integer age) | where age < ? |
LessThanEqual | findByAgeLessThanEqual(Integer age) | where age <= ? |
IsNull | findByNameIsNull | where name is null |
Like | findByNameLike(String name) | where name like ? |
StartingWith | findByNameStartingWith(String name) | where name like ‘?%’ |
Containing | findByNameContaining(String name) | where name like ‘%?%’ |
OrderByXx[desc] | findByIdOrderByXx[desc](Long id) | where id = ? order by Xx [desc] |
Not | findByNameNot(String name) | where name != ? |
In | findByIdIn(List ids) | where id in (…) |
True | findByXxTrue() | where Xx = true |
False | findByFalse() | where Xx =false |
IgnoreCase | findByNameIgnoreCase(String name) | where name = ? (忽略大小写) |