zoukankan      html  css  js  c++  java
  • Mongodb-SpringData


    -------------------------------------------------------------------------------------

    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());
    }

  • 相关阅读:
    gain 基尼系数
    luogu P5826 【模板】子序列自动机 主席树 vector 二分
    牛客挑战赛39 树与异或 离线 树上莫队 树状数组 约数
    4.22 省选模拟赛 三元组 manacher 回文自动机
    4.22 省选模拟赛 最优价值 网络流 最大权闭合子图
    4.18 省选模拟赛 消息传递 树剖 倍增 线段树维护等比数列
    luogu P4008 [NOI2003]文本编辑器 splay 块状链表
    牛客挑战赛39 密码系统 后缀数组
    luogu P1526 [NOI2003]智破连环阵 搜索+最大匹配+剪枝
    luogu P4095 [HEOI2013]Eden 的新背包问题 多重背包 背包的合并
  • 原文地址:https://www.cnblogs.com/Bkxk/p/9371758.html
Copyright © 2011-2022 走看看