-------------------------------------------------------------------------------------
MongoDB简介
MongoDB是为快速开发互联网Web应用而设计的数据库系统
设计目标是既极简、灵活、作为Web应用栈的一部分
数据模型是面向文档的,所谓文档是一种类似于"JSON"的结构,简单理解Mongodb这个数据库中存的是各种各样的JSON(BSON)
三个概念:数据库(database)数据库是一个仓库,在仓库中可以存放集合 (比如数据库)
集合(collection)集合类似于数据,在集合中可以存放文档。 (比如表)
文档(document) 文档数据库中的最小单位,我们存储的操作的内容都是文档 (比如row一行数据)
SQL
- 结构化查询语言
- 关系数据库全都同SQL来操作
1.安装MongoDBhttps://www.mongodb.com/download-center/community
- 安装
- 配置环境变量
C:Program FilesMongoDBServer3.2in
- 在c盘根目录
- 创建一个文件夹 data
- 在data中创建一个文件夹db
- 打开cmd命令行窗口
- 输入 mongod 启动mongodb服务器
- 32位注意:
启动服务器时,需要输入如下内容
mongod --storageEngine=mmapv1
mongod --dbpath 数据库路径 --port 端口号
- 在打开一个cmd窗口
- 输入 mongo 连接mongodb ,出现 >
- 数据库(database)
- 数据库的服务器
- 服务器用来保存数据
- mongod 用来启动服务器
- 数据库的客户端
- 客户端用来操作服务器,对数据进行增删改查的操作
- mongo 用来启动客户端
- 将MongoDB设置为系统服务,可以自动在后台启动,不需要每次都手动启动
1.在c盘根目录创建data
- 在data下创建db和log文件夹
2.创建配置文件
在目录 C:Program FilesMongoDBServer3.2 下添加一个配置文件
mongod.cfg
3.以管理员的身份打开命令行窗口
4.执行如下的命令
sc.exe create MongoDB binPath= ""C:Program FilesMongoDBServer3.2inmongod.exe" --service --config="C:Program FilesMongoDBServer3.2mongod.cfg"" DisplayName= "MongoDB" start= "auto"
sc.exe create MongoDB binPath= ""mongod的bin目录mongod.exe" --service --config="mongo的安装目录mongod.cfg"" DisplayName= "MongoDB" start= "auto"
5.启动mongodb服务
6.如果启动失败,证明上边的操作有误,
在控制台输入 sc delete MongoDB 删除之前配置的服务
然后从第一步再来一次
- 基本概念
数据库(database)
集合(collection)
文档(document)
- 在MongoDB中,数据库和集合都不需要手动创建,
当我们创建文档时,如果文档所在的集合或数据库不存在会自动创建数据库和集合
- 基本指令
show dbs
show databases
- 显示当前的所有数据库
use 数据库名
- 进入到指定的数据库中
db
- db表示的是当前所处的数据库
show collections
- 显示数据库中所有的集合
- 数据库的CRUD(增删改查)的操作
- 向数据库中插入文档
db.<collection>.insert(doc)
- 向集合中插入一个文档
- 例子:向test数据库中的,stus集合中插入一个新的学生对象
{name:"孙悟空",age:18,gender:"男"}
db.stus.insert({name:"孙悟空",age:18,gender:"男"})
db.<collection>.find()
- 查询当前集合中的所有的文档
安装客户端操作工具:NoSQL Manager for MongoDB
插入文档
use test
//注意:mongodb创建文档时才会创建数据库
//使用数据库
use test1
show dbs
show collection
db
db.user.insertOne() //插入一个文档对象
db.user.insertMany()//插入多个文档对象
db.user.insert({name:"王路凯",age:24,gender:"男"});
db.user.insert([
{name:"白骨精",age:22,gender:"女"},
{name:"蜘蛛精",age:23,gender:"女"}
])
//默认有id,但也可以自定义,确保数据唯一,建议使用默认
db.user.insert({_id:"Object",name:"王凯",age:23,gender:"女"})
db.user.find();
查询文档
/*
//find()可以接受一个对象作为条件参数
{}表示查询集合中所有的文档
{属性:值}查询属性是指定值的文档
*/
db.user.find({_id:"Object"});
db.user.find({age:23,name:"王凯"})
db.user.findOne({age:23})//返回的是一个文档对象,find是返回数据,所有
db.user.find({}).count();//查询所有数量, db.user.find({}).count//查看代码
修改文档
//db.user.update(参数1,参数2)//1是条件,2是要修改的列
//$set 可以用来修改文档中的指定数据, $unset 可以用来删除文档中的指定数据
//db.user.updateOne()修改一个
//db.user.updateMany()同时修改多个符合条件的
db.user.update(//默认情况下会使用新对象来替换旧的对象
{"name":"王凯"},
{
$set:{age:22}
}
)
db.user.update(//默认情况下会使用新对象来替换旧的对象
{"name":"王凯"},
{
$set:{age:22}
}
{
multi:true//同时修改多个符合条件的
}
)
删除文档
/*
db.user.remove()//默认情况下会删除多个符合条件的参数,如果参数2是true则只删除一个
db.user.deleteOne()删除一个
db.user.deleteMany()条件相同时删除多个
*/
db.user.find()
//db.user.remove({}) 清空集合
//db.user.drop 删除集合
//db.dropDatabase() 删除数据库
//db.user.remove({name:"白骨精"},true)
db.user.remove({name:"白骨精"})
db.user.deleteOne()
db.user.deleteMany()
/*
一般数据库中的数据都不会删除,所以删除的方法很少调用
一般会在数据中添加一个字段,来表示数据是否被删除
*/
db.user.insert([
{name:"你好",isDel:0},
{name:"你好1",isDel:0},
{name:"你好2",isDel:0}
]);
db.user.find()
db.user.updateOne({name:"你好2"},{$set:{isDel:1}})
db.user.find({isDel:0})
/*
文档之间的关系
一对多(one to many)文章-评论
多对一(many to one)订单-用户
多对多(many to many)分类-商品
属性变成数组(内嵌文档)
*/
/*
sort和投影
1升序,-1降序
db.user.find({}).sort({sal:1,empno:-1});用来指定文档排序的规则,需要传递一个对象来指定排序规则
//limit skip sort 可以任意顺序进行调用
在查询时,可以在第二个参数的位置来设置查询结果的 投影
db.user.find({},{name:1,id:0,sal:1})
*/
mongoose的好处:
可以为文档创建一个模式结构Schema
可以对模型中的对象/文档进行验证
数据可以通过类型转换 转换 为对象模型
可以使用中间件来应用业务逻辑挂钩
比Node原生的MongoDB驱动更容易
mongoose中为我们提供了几个新的对象
Schema(模式对象)
Schema对象定义约束了数据库中的文档结构
Model(是个构造函数)
Model对象作为集合中的所有文档的表示
相当于MongoDB数据库中的集合collection
Document
Document表示集合中的具体文档,
相当于集合中的一个具体的文档
mongoose.js
1.安装mongoose
npm i mongoose --save
2.在项目中引入mongoose
var mongoose = require("mongoose");
3.连接Mongodb数据库 //如果端口是默认端口27017,则可以省略不写
mongoose.connect('mongodb://localhost:端口号/test',(useMongoClient:true));
4.断开数据库连接(一般不需要调用)
mongoose.disconnect();
监听MongoDB数据的连接状态:mongoose对象中的connection
mongoose.connection.once("open",function(){});连接成功的事件
mongoose.connection.once("close",function(){});断开的事件
//引入
var moogoose = require("mongoose");
//连接数据库
mongoose.connect("mongodb://localhost/test",{useMongoClient:true})
mongoose.connection.once("open",function(){
console.log("数据库连接成功");
})
//创建Schema(约束对象)
var Schema = mongoose.Schema;
var stuSchema = new Schema({
name:String,
age:number,
gender:{
type:String,
default:"female"
},
address:String
});
//通过Schema来创建Model
//Model代表数据库中的集合,通过Model再能对数据库进行操作
//mongoose.model(modelName,schema);
//modelName就是要映射的集合名 mongoose会自动将集合名变成复数
var StuModel = mongoose.model("student",stuSchema);
//向数据库中插入一个文档
//StuModel.create(doc,function(err){});
StuModel.create({
name:"孙悟空",
age:18,
gender:"male",
address:"花果山"
},function(err){
if(!err){
console.log("插入成功");
}
});
mongoose.connection.once("close",function(){
console.log("数据库连接已断开");
})
//断开数据库连接(非关系型数据库、一般不会断开连接、)
mongoose.disconnect();
model.js
Model.create(doc(s),{callback});
//用来创建一个或多个文档并添加到数据库中
//参数:
doc() 可以使一个文档对象,也可以是一个文档对象的数组
callback 操作完成后的回调函数
StuModel.create([
{
name:"猪八戒",
age:22,
gender:"male",
address:"高老庄"
},
{
name:"唐僧";
}
],funtion(err){
if(!err){
console.log("插入成功");
}
});
查询:
Model.find(conditions,{projection},{options},{callback})
--查询所有符合条件的文档
Model.findById(id,{projection},{options},{callback})
--根据文档的Id查询文档
Model.FindOne({conditions},{projection},{options},{callback})
--查询符合条件的第一个文档
conditiond 查询的条件
projection 投影:需要获取到的字段
--两种方式:{name:1, id:0}
"name - id"
options 查询选项(skip limit):{skip:3,limit:1}
callback 回调函数
//文档就是模型的实例
console.log(doc(Document) instanoeof StuModel);
StuModel.find({},function(err,do){})
修改:
//Model.update(conditions,{callback})
//Model.updateMany(conditions,{callback})
//Model.updateOne(conditions,{callback})
--参数:conditions查询条件
doc 修改后的对象
options 配置参数
callback 回调函数
StuModel.updateOne({name:"唐僧"},{$set:{age:20}},function(err){
if(!err){
console.log("修改成功");
}
})
删除:
Model.remove(conditions,{callback})
Model.deleteOne(conditions,{callback})
Model.deleteMany(conditions,{callback})
StuModel.remove({name:"小白"},function(err){
if(!err){
console.log("删除成功");
}
});
统计文档的数量:
Model.count(conditions,{callback})
StuModel.count({},function(err,count){
if(!err){
console.log(count);
}
});
document.js
Document对象的方法:
equals(doc)
id
get
set
update
save
remove
isNew
isInit
toJSON:转换为JSON对象
toObject
//创建一个Document
var stu = new StuModel({
name:"奔波霸",
age:48,
gender:"male",
address:"玉渊潭"
});
console.log(stu);
stu.save(function(err){
if(!err){
console.log("保存成功");
}
});
StuModel.findOne({},function(err,doc){
if(!err){
doc.update({$set:{age:28}},function(err){
if(!err){
console.log("修改成功");
}
});
doc.remove(function(err){
if(!err){
c console.log("大师兄再见!");
}
})
doc.get("age")
doc.age
doc.set("name","朱晓晓")
doc.name="haha"
doc.toJSON()
var o = doc.toObject();
delete o.address;
}
});
/*定义一个模块,用来连接MongoDB数据库*/
conn_mongo.js
var mongoose = require("mongoose");
mongoose.connect("mongodb://127.0.0.1/mongoose_test");
mongoose.connection.once("open",function(){
console.log("数据库连接成功!");
});
index.js
/*引入这个定义模块*/
require("./tools/conn_mongo");
var Student = require("./models/student").model;
Student.find({},function(err,docs){
if(!err){
console.log(docs);
}
});
student.js
/*定义Student的模型*/
var mongoose = require("mongoose");
var Schema = mongoose.Schema;
var stuSchema = new Schems({
name:String,
age:Number,
gender:{
type:String,
default:"female"
},
address.String
});
//定义模型
var StuModel = mongoose.model("student",stuSchema);
//外部可接收,
exports.model = StuModel;
两种方式:
//var Student = require("./models/student");
//module.exports = StuModel;
-----------------------------------------------------------------------------
Sprint-Data 是其Sprint的子项目,是基于Spring的ORM(对象关系映射)框架
而不拘泥于是关系型数据库还是NoSQL 数据存储
SprintData提供的编程接口如下:
Repository:最顶层接口,是一个空接口,目的是为了统一所有的Repository的类型,并能让组件扫描的时候自动识别。
CrudRepository:提供基础的增删改查操作;
PagingAndSortingRepository:提供分页和排序的操作;
JpaRepository:增加了批量删除功能;
JpaSpecificationExecutor:组合查询条件,提供原生SQL查询;
依次是继承关系!
SpringData-JPA
环境搭建
1.引入jar包
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.8.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.6.Final</version>
</dependency>
<beans>
//配置数据源
~~~~~~~~
//配置EntityManagerFactory
<!--1.配置数据源-->
<bean id = "dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="password" value="1678697149"/>
<property name="url" value="jdbc:mysql:///spdataring_data"/>
</bean>
<!--2.配置EntityManagerFactory-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
</property>
<property name="packagesToScan" value="com.imooc"/>
<property name="jpaProperties">
<props>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>//对应实体类,如果没该表、就自动生成表
</props>
</property>
</bean>
<!--3.配置事务管理器-->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!--4.配置支持注解的事务-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!--5.配置Spring data-->
<jpa:repositories base-package="com.imooc" entity-manager-factory-ref="entityManagerFactory"/>
<context:component-scan base-package="com.imooc"/>//都可扫描到
</beans>
实体类 通过JPA 先开发实体类===》自动生成数据表
@Entity
public class Employee{
private Integer id;
private String name;
private Integer age;
@GeneratedValue
@Id
public Integer getId(){
return id;
}
@Column(length = 20) //生成数据表列的字段,长度控制为20
public void setId(Integer id){
this.id = id;
}
......省略
}
测试类
public Class SpringDataTest{
private ApplicationContext ctx = null;
@Before
public void setup(){
ctx = new ClassPathXmlApplicationContext("beans.xml");
System.out.println("setup");
}
@After
public void tearDown(){
ctx = null;
System.out.println("tearDown");
}
@Test
public void testEntityManagerFactory(){//执行方法,测试是否创建了数据库表
}
}
Repository接口讲解
@Query("select o from Employee o where id=(select max(id) from Employee t1)")
public Employee getEmployeeByMaxId();
@Query("select o from Employee o where o.name=?1 and o.age=?2")
public List<Employee> queryParams1(String name,Integer age);
@Query("select o from Employee o where o.name=:name and o.age=:age")
public List<Employee> queryParams2(@Param("name")String name,@Param("age")Integer age);
@Query("select o from Employee o where o.name like %?1%")
public List<Employee> querLike1(String name);
@Query("select o from Employee o where o.name like %:name%")
public List<Employee> querLike2(@Param("name")String name);
@Query(nativeQuery = true, value = "select count(1) from employee")
public long getcount();
更新及删除操作整合事务的使用
@Modifying注解使用
@Modifying结合@Query注解执行更新操作
@Transactional在Spring Data中的使用
@Modifying
@Query("update Employee o set o.age= :age where o.id = :id")
public void update("@Param("id")Integer id,@Param("age")Integer age")
事务在Spring data中的使用:
1.事务一般是在Service层
2.@Query、@Modifying、@Transactional的综合使用
CrudRepository接口使用详情
save(entity) save(entityes)
findOne(id) exists(id)
findAll() delete(id)
delete(entity)delete(entities)
deleteAll()
PagingAndSortingRespository接口
该接口包含分页和排序功能
带排序的查询:findAll(Sort sort)
带排序的分页查询:findAll(Pageable pageable)
Sort.Order order = new Sort.Order(Sort.Direction.DESC,"id");
Sort sort = new Sort(order);
Pageable pageable = new PageRequest(0,5,sort);
Page<Employee> page = employeePagingAndSortingRepository.findAll(pageable);
System.out.println("查询的总页数:"+page.getTotalPages());
System.out.println("查询的总记录数:"+page.getTotalElements());
System.out.println("查询的当前第几页:"+(page.getNumber()+1));
System.out.println("查询的当前页面的集合:"+page.getContent());
System.out.println("查询的当前页面的记录数:"+page.getNumberOfElements());
JpaRepository接口
findAll findAll(Sort sort)
save(entities) flush
deleteInBatch(entities)
JpaSpecificationExecutor接口
Specification封装了JPA Criteria查询条件
private ApplicationContext ctx = null;
private EmployeeJpaSpecificationExecutorRepository employeeJpaSpecificationExecutorRepository = null;
@Before
public void setup(){
ctx = new ClassPathXmlApplicationContext("beans-new.xml");
employeeJpaSpecificationExecutorRepository = ctx.getBean(EmployeeJpaSpecificationExecutorRepository.class);
System.out.print("setup");
}
@After
public void tearDown(){
ctx = null;
System.out.print("tearDown");
}
@Test
public void testQuery(){
Sort.Order order = new Sort.Order(Sort.Direction.DESC,"id");
Sort sort = new Sort(order);
Pageable pageable = new PageRequest(0,5,sort);
Specification<Employee> specification = new Specification<Employee>(){
@Override
public Predicate toPredicate(Root<Employee> root,//查询类型
CriteriaQuery<?> query,//查询条件
CriteriaBuildeer cb){//构建Predicate
Path path = root.get("age");
return cb.gt(path,50);
}
};
Page<Employee> page = employeeJpaSpecificationExecutorRepository.findAll(specification,pageable);
System.out.println("查询的总页数:"+page.getTotalPages());
System.out.println("查询的总记录数:"+page.getTotalElements());
System.out.println("查询的当前第几页:"+(page.getNumber()+1));
System.out.println("查询的当前页面的集合:"+page.getContent());
System.out.println("查询的当前页面的记录数:"+page.getNumberOfElements());
}