`

mongoDb的写和读

 
阅读更多

1. 首先说一下为什么要用mongodb:

 

   数据结构能体现开发者的程序和构想,所以我们始终在寻找方法,让数据结构更有表达力,从而更好地进行应用的建模。所以回到 MongoDB为何流行的话题上,并不是它的扩展性有多好,而是因为数据结构。

   同其他的NoSQL数据库技术相比,MongoDB的扩展性并不是最出色 的,但是它在数据结构上的创新,能够让我们更加轻松地、更直观地对事物进行建模,这对于应用是最重要的 ,也是MongoDB流行的真正原因。

   像MongoDB这样的数据库,在未来将成为操作型数据存储的主要数据库范式,而关系型数据库将起到专用工具的作用。

  举个例子:

  假如一个旅游产品有多个推荐行程,按照我们惯有的面向对象思想建模,我们会建一张产品表来存储产品信息,再建行程表来存储行程信息,两表通过外键productId(产品id)来关联。当需要查询产品名称和行程名称

  的时候,需要两句sql才能查询出结果。如果在mongodb里面,这样的情况你可以直接把产品名称和行程名称以数组的形式存在产品下面,查询的时候只要查到产品,名称就都知道了,只需要一次查询。

 

2.怎么用:

  2.1 一般先新建一个properties文件,这里是mongo.properties.并在此文件中配置好mongodb的访问ip地址以及端口号(把对数据库,缓存等的访问配置在properties文件中便于统一管理)

#mongotest
#访问ip:端口号
mongodb1=10.10.a.aa:aaaa
mongodb2=10.10.x.xx:XXXX

   2.2 引入mongodb的支持jar包。这里用的是mongo-2.7.3.jar。然后接下来的是在spring文件中配置好访问主机,访问端口(就是加载2.1的properties文件),配置如下:

  

<beans>
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
            <value>/WEB-INF/conf/mongo.properties</value>//先加载mongo.properties文件,用了spring的jar包读取
        </property>
    </bean>
    <bean id="server1" class="com.mongodb.ServerAddress">
	  <constructor-arg index="0" value="${mongodb1}" />//读取访问ip+端口号,读取语法${mongodb1}有点像jQuery
    </bean>

     <bean id="server2" class="com.mongodb.ServerAddress">
	 <constructor-arg index="0" value="${mongodb2}" />
     </bean>

     <bean id="mongo" class="com.mongodb.Mongo">//将server1和server2以构造器形式注入进 com.mongodb.Mongo		
               <constructor-arg index="0">
			<list>
 				<ref bean="server1" />
				<ref bean="server2" /> 
			</list>
		</constructor-arg>
	</bean>

	<bean id="mongoTemplate" class="com.mangocity.mongodbhelper.MongoTemplate">//将mango注入进MongoTemplate		
                <property name="mongo" ref="mongo" />
		<property name="databaseName" value="xxx1" />//注意了,这里的databaseName指的是MongoDb里面的数据库名
	</bean>
</beans>

   2.3上面通过${mongodb1}将mongodb1的内容加载进来(10.10.a.aa:aaaa),然后以构造器的形式传进ServerAddress,那么ServerAddress的代码是怎么样的呢?让我们看看:

  

    ServerAddress.java:

 public ServerAddress(String host, int port)//构造器
    throws UnknownHostException
  {
    if (host == null)
      host = defaultHost();
    host = host.trim();
    if (host.length() == 0) {
      host = defaultHost();
    }
    int idx = host.indexOf(":");
    if (idx > 0) {
      if (port != defaultPort())
        throw new IllegalArgumentException("can't specify port in construct and via host");
      port = Integer.parseInt(host.substring(idx + 1));//这里会以:分割得出主机号和端口号
      host = host.substring(0, idx).trim();
    }

    this._host = host;
    this._port = port;
    this._all = _getAddress(this._host);
    this._addr = new InetSocketAddress(this._all[0], this._port);
  }

   2.4 然后将server注入进mango,看看Mongo源码是怎么实现的(Mongo根据注入的server获取Mongo的连接):

  

    Mango.java:

public Mongo(ServerAddress left, ServerAddress right)//构造函数,调用Mongo(ServerAddress left, ServerAddress right, MongoOptions options)
throws MongoException
{
this(left, right, new MongoOptions());
}

@Deprecated
public Mongo(ServerAddress left, ServerAddress right, MongoOptions options) //将两个server(即server1和server2)set给全局变量_addrs
throws MongoException
{
this._addr = null;
this._addrs = Arrays.asList(new ServerAddress[] { left, right });
this._options = options;
_applyMongoOptions();
this._connector = new DBTCPConnector(this, this._addrs); //获取这两台主机的连接,这里就不再深入怎么获取到连接了,有空了再分析
this._connector.start();//连接开始

this._cleaner = new DBCleanerThread();
this._cleaner.start();
}

    2.5上面获取到Mongo的连接,还要把Mongo注入到MongoTemplate(用过Hibernate 的人应该知道,Hibernate也有一个hibernateTemplate,需要注入dataSource和sessionFactory),这里可以看下源代码:

   

   MongoTemplate.java:

public class MongoTemplate
  implements MongoOperations
{  
  public static final String IDENTITY = "_id";
  private Mongo mongo;
  private String databaseName = "test";//前面spring配置文件中的配置名称xxx1
  private boolean slaveOk = false;

  public MongoTemplate()//空构造器
  {
  }
  public MongoTemplate(Mongo mongo, String databaseName) { //构造函数,需要那个MongoDB和数据库名称,这里在前面spring的配置文件中 已经注入进去
    this.mongo = mongo;
    this.databaseName = databaseName;
  }
 public <T> T findAndModify(Query query, Update update, Class<T> entityClass, String collectionName)//查找
  {
    DBCollection col = getDB().getCollection(collectionName);
    DBObject updateObj = update.getUpdateObject();
    for (String key : updateObj.keySet()) {
      updateObj.put(key, DBObjectConverter.toDBObjectTypeConvert(updateObj.get(key)));
    }
    DBObject dBObject = col.findAndModify(query.getQueryObject(), updateObj);
    Object obj = DBObjectConverter.fromDBObject(entityClass, dBObject, true);
    return obj;
  }

  public void insert(Object objectToSave, String collectionName) {//插入,调用插入2的方法
    List list = new ArrayList();
    list.add(objectToSave);
    insert(list, collectionName);
  }
   public void insert(Collection<? extends Object> batchToSave, String collectionName) {//插入2,获取DB连接,然后进行插入,有木有像Hibernate的session的感觉!
    DBCollection col = getDB().getCollection(collectionName);
    List list = new ArrayList();
    for (Iterator localIterator = batchToSave.iterator(); localIterator.hasNext(); ) { Object obj = localIterator.next();
      DBObject dBObject = DBObjectConverter.toDBObject(obj, true);
      list.add(dBObject);
    }
    col.insert(list);
  }

  public void update(Query query, Update update, String collectionName) {//更新,获取DB的连接。这里的collectionName就相当于oracle的表名
    DBCollection col = getDB().getCollection(collectionName);
    DBObject updateObj = update.getUpdateObject();
    for (String key : updateObj.keySet()) {
      updateObj.put(key, DBObjectConverter.toDBObjectTypeConvert(updateObj.get(key)));
    }
    col.update(query.getQueryObject(), updateObj);
  }
}
....

    2.6接下来就是把MongoTemplate注入到Hibernate封装好的对数据库访问的bean中,(这里也可以叫DAO),则该DAO获取到了对MongoDb访问的权限,如:
   
<bean id="productDao" class="*.dao.xxxMongoDaoImpl">
	<property name="mongoTemplate" ref="mongoTemplate" />
</bean>
   
    3.MongoDb读、写实例(可以结合MongoTemplate来看)
    读:
    MongoTemplate读的代码:
  public <T> T findById(Object id, Class<T> entityClass, String collectionName) { //先创建Criteria对象,并往对象填值,然后new一个Query对象,
    Criteria criteria = Criteria.where("_id").is(id);                             //并把criteria对象set进Query对象,再调用find方法进行查询,这里entityClass是javaBean,而collectionName是MongoDb的'表名'
    List list = find(new Query(criteria).limit(1), entityClass, collectionName);
    if (list.size() == 1) {
      return list.get(0);
    }
    return null;
  } 

public <T> List<T> find(Query query, Class<T> entityClass, String collectionName) {
    DBCollection col = getDB().getCollection(collectionName);

    DBCursor cursor = col.find(query.getQueryObject(), query.getFieldsObject());//查询得出cursor(list)
    if (query.getSkip() > 0) {
      cursor.skip(query.getSkip());
    }
    if (query.getLimit() > 0) {
      cursor.limit(query.getLimit());
    }
    if (query.getSortObject() != null) {
      cursor.sort(query.getSortObject());
    }

    List newList = new ArrayList();
    for (DBObject dBObject : cursor) {//遍历转化为对象
      Object obj = DBObjectConverter.fromDBObject(entityClass, dBObject, true);
      newList.add(obj);
    }
    return newList;
  }

   MongoDb读实例:
 
 public List<Product> getProduct(Map params) {
    	Criteria criteria = new Criteria();//创建Criteria 对象
    	criteria.and("type").is(params.get("type"));//往criteria set值
    	criteria.and("departure").is(params.get("departure"));
    	criteria.and("destination").is(params.get("destination"));
    	if(params.containsKey("keys")){
    		criteria.and("key").in((Collection)params.get("keys"));
    	}else{
        	criteria.and("key").is(params.get("key"));
    	}
        Query query = new Query(criteria);
        query.skip(int fromIdx);//从哪里开始
        query.limit(int size);//限制多少条
...
    	return getMongoTemplate().find(query , Product.class, "product");//getMongoTemplate()获取MongoTemplate的实例,即可获取MongoDb 的操作权限,
                                                                         //三个参数分别是query对象,对应的javaBean类以及类所对应的MongoDb 的'表名'
    }
   读操作主要关注两个类:Criteria.java和Query.java,有兴趣的可以看源码加深一下理解,这里就不一一展示了。

   写:

   写的话也大概一样,不过先从oracle数据库读出数据,然后进行转换成与MongoDb字段一一对应的javaBean,然后调用MongoTemplate的保存方法即可!

 

public void saveProduct(Product product) {
    getMongoTemplate().save(product, "product");//两个参数分别是Product.java的引  
                                                //用和MongoDb的'表名'(collection)
  }

   

 

 

 

 

分享到:
评论

相关推荐

    MongoDb多数据中心

    2. 部署模式:MongoDB支持多种多数据中心部署模式,包括单写多读模式、多写多读模式以及混合模式。每种模式都针对不同的应用场景和需求提供了灵活性和优化方案。 3. 运营自动化:为了简化跨数据中心的管理,MongoDB...

    Mongodb常用命令和java调用

    MongoDB 是一种流行的开源、高性能、无模式的文档型数据库,设计用于处理大规模数据并提供高可用性和可扩展性。它的名称来源于“humongous”的一部分,暗示了它在处理大量数据上的能力。MongoDB 结合了键值存储的...

    mongodb 复制集搭建实例

    复制集包含一个主节点(primary)和多个从节点(secondary),主节点负责所有写操作,从节点则同步主节点的数据并提供读操作。 2. **系统需求** 在开始搭建之前,你需要准备至少三台服务器或虚拟机,每台都安装了...

    MongoDB集群负载均衡资料(mongodb副本集)

    MongoDB是一种流行的开源文档数据库系统,它以高性能、高可用性和可扩展性著称。在大规模数据处理场景中,为了实现负载均衡和高可用性,MongoDB提供了副本集(Replica Set)的功能。副本集是MongoDB中的一个关键概念...

    mongodb高可用完全分布集群搭建

    mongodb的读和写操作需要分离,以便提高mongodb的高性能和高可用性。 mongodb高可用完全分布集群的搭建需要合理的架构设计和部署。需要考虑到高可用性、高性能和可扩展性三个方面,选择合适的mongodb版本和架构设计...

    深入剖析 MongoDB 架构

    MongoDB 使用 BSON(Binary JSON)格式存储数据,这是一种高效的二进制表示JSON数据的方式,既保留了JSON的易读性,又提高了存储和检索效率。BSON支持多种数据类型,如字符串、数字、日期、数组等,甚至自定义对象。...

    5.2 MongoDB的三种集群模式1

    MongoDB 是一个流行的开源NoSQL数据库系统,以其灵活性、高性能和可扩展性而著称。在MongoDB中,集群模式是实现高可用性和水平扩展的关键技术。本文将深入探讨MongoDB的三种集群模式之一——主从(master-slave)...

    mongodb-windows-x86-64-6.0.5最新稳定版本

    - 文档型:MongoDB以BSON(二进制JSON)格式存储数据,这种格式既能保持JSON的易读性,又能提高存储效率。 - 弹性:MongoDB支持动态schema,允许在不更改数据结构的情况下进行快速迭代开发。 - 高性能:采用内存...

    NoSQL数据库-MongoDB和Redis

    ### NoSQL数据库-MongoDB和Redis #### 一、NoSQL简述 NoSQL数据库的出现是为了应对传统关系型数据库无法解决的一些问题,特别是在大规模数据处理方面。CAP理论(Consistency,Availability,Partition Tolerance)...

    MongoDB主从环境搭建

    MongoDB是一种流行的开源文档数据库系统,它以其高性能、高可用性和可扩展性而备受赞誉。在企业级应用中,为了确保数据的安全性和服务的连续性,通常会采用主从复制(Replication)架构。主从环境搭建是MongoDB高...

    mongodb_replica

    MongoDB 是一个高性能、分布式、开源的文档型数据库,它以JSON格式存储数据,支持丰富的查询语法和灵活的数据模型。在高可用性场景下,MongoDB 提供了副本集(Replica Set)功能,用于实现数据冗余和故障转移。在本...

    Memcached Redis MongoDB对比

    Memcached适用于动态系统中减轻数据库负载、提升性能的场景,适合读多写少的应用,并且可以通过分片技术应对大数据量的读写。MongoDB则主要解决海量数据的访问效率问题,适用于需要处理大量数据的存储和分析场景。 ...

    MongoDB设置访问权限、设置用户

    常见的角色有读(read)、读写(readWrite)、数据库管理员(dbAdmin)和集群管理员(clusterAdmin)等。例如,为特定数据库创建一个只具有读写权限的用户: 1. 切换到目标数据库: ```javascript use ...

    MySQL与MongoDB多文档事务支持对比分析.docx

    3. **隔离性**:MySQL提供了四种隔离级别:读未提交、读已提交、可重复读和串行化,以防止并发事务间的脏读、不可重复读和幻读问题。MongoDB在4.0版本开始支持多文档事务,但默认使用的是可重复读隔离级别,类似于...

    mongodb-linux-x86_64-ubuntu1404-3.6.4

    6. **性能提升**:在读写性能上进行了优化,尤其是对于读操作,如范围查询和索引扫描,性能得到了显著提升。 7. **新查询操作符**:增加了诸如`$expr`等新查询操作符,使得在查询表达式中可以使用聚合操作符。 8. ...

    mongoDB简介.doc

    MongoDB 是一种流行的开源、非关系型数据库管理系统,专为处理大量数据和实现高性能而设计。MongoDB 的名称来源于“Humongous”,强调其处理大规模数据的能力。由 10gen 公司(现MongoDB Inc.)开发,MongoDB 的设计...

    NoSQL主流数据库-MongoDB.pptx

    MongoDB 的写操作包括插入、更新和删除三个操作。插入操作可以使用 insert 语句将数据插入到数据库中,更新操作可以使用 update 语句更新已有的数据,删除操作可以使用 remove 语句删除指定的数据。 MongoDB 的读...

    mongodb数据库安装包

    4. **高性能**:MongoDB采用内存映射技术,数据读写速度快,尤其适合读多写少的应用场景。 5. **强大的查询能力**:MongoDB支持丰富的查询语言,可以进行复杂的聚合操作,提供了类似SQL的查询功能,同时支持地理...

    MongoDB TPCC事务性能基准测试.pptx

    - `writeConcern`定义了MongoDB在确认写操作成功之前需要满足的条件,例如`majority`确保大多数节点接收到数据,保证数据一致性。 - `readConcern`决定了读操作返回的数据一致性级别,如`primary`只读主节点,`...

    《MongoDB权威指南》读书笔记1

    2. **类型和大小写敏感**:MongoDB区分数据类型和大小写,因此键不能重复,且键的大小写必须一致。 3. **集合和模式**:集合是MongoDB中的基本存储单元,类似于关系型数据库的表,但集合是无模式的,即不需要预先...

Global site tag (gtag.js) - Google Analytics