NoSql
NoSQL(NoSQL = Not Only SQL ),即"不仅仅是SQL"
非关系型的数据库
MongoDB
MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。
MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。
MongoDB 将数据存储为一个文档,数据结构由键值(key,value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。
MongoDB 安装
Windows MongoDB
MongoDB 在 SpringBoot中的使用
spring-data-mongodb 注解
@Id
/*主键,不可重复,自带索引,可以在定义的列名上标注,需要自己生成并维护不重复的约束。
如果自己不设置@Id主键,mongo会自动生成一个唯一主键,并且插入时效率远高于自己设置主键。
在实际业务中不建议自己设置主键,应交给mongo自己生成,自己可以设置一个业务id,如int型字段,用自己设置的业务id来维护相关联的表。*/
@Document //标注在实体类上,类似于entity注解,标明由mongo来维护该表
@Indexed //声明该字段需要加索引,加索引后以该字段为条件检索将大大提高速度
@CompoundIndex //复合索引,加复合索引后通过复合索引字段查询将大大提高速度。
@Field //代表一个字段,可以不加,不加的话默认以参数名为列名
@Transient //被该注解标注的,将不会被录入到数据库中。只作为普通的javaBean属性。
@DBRef //关联另一个document对象
1 引入依赖
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2. 添加MongoDB配置
application.yml
spring:
data:
mongodb:
uri: mongodb://localhost:27017/databaseName
#有安全验证写法:
uri:mongodb://username:password@localhost:27017/databaseName
3. 测试
MongoTemplateTest
3.1 集合(Collection)操作
public class MongoTemplateTest extends MongoDbTestApplicationTests{
@Autowired
MongoTemplate mongoTemplate;
// 创建集合
@Test
public void testCreateCollection(){
if (!mongoTemplate.collectionExists("users")){
mongoTemplate.createCollection("users");
}
}
// 删除集合
@Test
public void testDropCollection(){
mongoTemplate.dropCollection("users");
}
}
3.2 文档(Document)操作
前置准备
创建entity包,创建User类
@Data
@Document("users")
public class User {
@Id
private Integer id;
@Field("username")
private String name;
@Field
private Double salary;
@Field
private Date birthday;
public User(Integer id, String name, Double salary, Date birthday) {
this.id = id;
this.name = name;
this.salary = salary;
this.birthday = birthday;
}
}
插入操作
save()
插入重复数据时,对已有数据进行更新;
批处理操作时,需要遍历整个数据,依次插入或更新,效率较低
insert()
插入重复数据时,提示主键(_id)重复;
批处理操作时,可以一次性插入整个数据,效率较高
@Test
public void testSave(){
// save
User user = new User(1, "张三", 1500d, new Date());
mongoTemplate.save(user);
// insert
User user2 = new User(2, "李四", 1600d, new Date());
mongoTemplate.insert(user2);
// 批处理
List<User> users = Arrays.asList(
new User(3, "张三", 1500d, new Date()),
new User(4, "李四", 1600d, new Date())
);
/*
参数1:批量数据
参数2:指明放入那个集合
* */
// mongoTemplate.insert(users,"users");
mongoTemplate.insert(users,User.class);
}
}
查询操作
查询所有 findALl
@Test
public void testFind(){
/*查询所有 findALl 指定查询某个集合
若实体没有@Document("users")注解,也可以在findAll方法中指定查询users表
List<User> users = mongoTemplate.findAll(User.class,"users");
*/
List<User> users = mongoTemplate.findAll(User.class);
users.forEach(System.out::println);
}
根据Id查询 findById
//根据Id查询 findById
User user = mongoTemplate.findById(1,User.class);
System.out.println(user);
条件查询 find
//条件查询 find 参数1:查询条件 参数2:返回类型/查询的集合
List<User> users = mongoTemplate.find(new Query(),User.class);
users.forEach(System.out::println);
等值查询
Query query = Query.query(Criteria.where("name").is("张三"));
List<User> users = mongoTemplate.find(query,User.class);
//List<User> users = mongoTemplate.find(Query.query(Criteria.where("name").is("张三")),User.class);
users.forEach(System.out::println);
>,<,>=,<=
>gt<lt>=gte<=lte
List<User> users = mongoTemplate.find( Query.query(Criteria.where("salary").lt(1550));,User.class);
users.forEach(System.out::println);
and 查询
Query query = Query.query(Criteria.where("name").is("张三").and("salary").lte(1500));
List<User> users = mongoTemplate.find(query,User.class);
users.forEach(System.out::println);
or 查询
Criteria criteria = new Criteria();
criteria.orOperator(
Criteria.where("name").is("张三"),
Criteria.where("name").is("李四")
);
List<User> users = mongoTemplate.find(Query.query(criteria),User.class);
users.forEach(System.out::println);
and & or
//这个表示的时 在"name"为"张三" 的基础上在查询"name"为"李四"的
Query query = Query.query(Criteria.where("name").is("张三").orOperator(Criteria.where("name").is("李四")));
List<User> users = mongoTemplate.find(query,User.class);
users.forEach(System.out::println);
排序
Query querySort = new Query();
querySort.with(Sort.by(Sort.Order.desc("salary"))); //asc desc
List<User> users = mongoTemplate.find(querySort,User.class);
users.forEach(System.out::println);
分页
Query querySortPage = new Query();
Integer pageSize=2;
querySortPage.with(Sort.by(Sort.Order.desc("salary")))
.with(Pageable.ofSize(pageSize));
List<User> users = mongoTemplate.find(querySortPage,User.class);
users.forEach(System.out::println);
Query querySortPage = new Query();
querySortPage.with(Sort.by(Sort.Order.desc("salary")))
.skip(0)
.limit(2); //pageSize
List<User> users = mongoTemplate.find(querySortPage,User.class);
users.forEach(System.out::println);
查询总数
long count = mongoTemplate.count(new Query(), User.class);
System.out.println(count);
long count2 = mongoTemplate.count(Query.query(Criteria.where("name").is("张三")), User.class);
System.out.println(count2);
去重
//去重 参数1:查询条件 参数2:去重的字段 参数3:查询的集合 参数4:返回的类型
List<String> stringList = mongoTemplate.findDistinct(new Query(), "name", User.class, String.class);
stringList.forEach(System.out::println);
使用 json 字符串方式查询
/*这种方式还可以支持 设定返回字段,不设置便全返回
*_id 默认显示
*投影中不可以同时 包容和排斥
* "{name:0,salary:0}" √ "{name:1,salary:1}" √
* "{name:1,salary:0}" ×
*/
BasicQuery basicQuery = new BasicQuery("{$or:[{name:'张三'},{salary:1600}]}","{id:0,salary:0}");
List<User> users = mongoTemplate.find(basicQuery, User.class);
users.forEach(System.out::println);
更新操作
更新查找到的第一条 updateFirst
@Test
public void testUpdate(){
Update update = new Update();
update.set("salary",2000);
mongoTemplate.updateFirst(Query.query(Criteria.where("name").is("张三")),update,User.class);
}
多条更新 updateMulti
Update update = new Update();
update.set("salary",2000);
mongoTemplate.updateMulti(Query.query(Criteria.where("name").is("张三")),update,User.class);
插入跟新 upsert
没有符合条件时 插入数据
Update update = new Update();
update.setOnInsert("id",5); //当插入时,指定字段值
update.set("salary",1500);
mongoTemplate.upsert(Query.query(Criteria.where("name").is("王五")),update,User.class);
//返回值
System.out.println(updateResult.getModifiedCount());//获取本次修改的记录
System.out.println(updateResult.getMatchedCount());//获取本次匹配的记录
System.out.println(updateResult.getUpsertedId());//获取插入数据的id
删除操作
@Test
public void testDelete(){
//删除所有
mongoTemplate.remove(new Query(),User.class);
//条件删除
mongoTemplate.remove(Query.query(Criteria.where("name").is("王五")),User.class);
}