`
jorwen_fang
  • 浏览: 51843 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MongoDB学习笔记(十三):SpringData-Mongodb

阅读更多

最完整原版教程:http://docs.spring.io/spring-data/data-mongo/docs/1.4.0.RELEASE/reference/html/mongo.core.html 
范例中的MetaDBMongoFactory是我自己写的,你也可以通过Spring配置文件获得。如下 
http://www.blogjava.net/wangxinsh55/archive/2012/03/29/372987.html 

1.单表增删查改 
@Id - 文档的唯一标识,在mongodb中为ObjectId,它是唯一的,通过时间戳+机器标识+进程ID+自增计数器(确保同一秒内产生的Id不会冲突)构成。 
@Document - 把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档。 
@DBRef - 声明类似于关系数据库的关联关系。ps:暂不支持级联的保存功能,当你在本实例中修改了DERef对象里面的值时,单独保存本实例并不能保存DERef引用的对象,它要另外保存,如下面例子的Person和Account。 
@Indexed - 声明该字段需要索引,建索引可以大大的提高查询效率。 
@CompoundIndex - 复合索引的声明,建复合索引可以有效地提高多字段的查询效率。 
@GeoSpatialIndexed - 声明该字段为地理信息的索引。 
@Transient - 映射忽略的字段,该字段不会保存到mongodb。 
@PersistenceConstructor - 声明构造函数,作用是把从数据库取出的数据实例化为对象。该构造函数传入的值为从DBObject中取出的数据。 
文档版本: @Version (建议用Long) 

范例: 
新建实体:

01.public class User
02.{
03.@Id  
04.private ObjectId id;  
05.@Indexed(unique = true)  
06.private String ssn;
07.@Indexed  
08.private String userName;  
09.private String password;
10.private Integer age;  
11.@Transient  
12.private Integer accountTotal;  
13.//其它set,get略......
14.}

增删查改

01.public void testCurd()
02.{
03.MongoTemplate template = MetaDBMongoFactory.getInstance().getMongoTemplate();
04.User user = new User();        
05.user.setSsn(...);//唯一性内容
06.user.setPassword("123456");
07.user.setUsername("张三");
08. 
09.//增加
10.template.save(user);
11.System.out.println("1. user : " + user);
12. 
13.//查询
14.Query searchUserQuery = new Query(Criteria.where("username").is("张三"));
15.User savedUser = template.findOne(searchUserQuery, User.class);
16.System.out.println("2. find - savedUser : " + savedUser);
17. 
18.//修改
19.template.updateFirst(searchUserQuery, Update.update("password", "45678"), User.class);
20.User updatedUser = template.findOne(searchUserQuery, User.class);
21.System.out.println("3. updatedUser : " + updatedUser);
22. 
23.//删除
24.template.remove(searchUserQuery, User.class);
25.List<User> listUser = template.findAll(User.class);
26.System.out.println("4. Number of user = " + listUser.size());
27.}

在看个更多功能的实体类

01.@Document(collection="person")  
02.@CompoundIndexes({  //组合索引
03.@CompoundIndex(name = "age_idx", def = "{'lastName': 1, 'age': -1}")  
04.})  
05.public class sample {  
06. 
07.@Id  
08.private String id;  
09.@Indexed(unique = true)  
10.private Integer ssn;  
11.private String firstName;  
12.@Indexed  
13.private String lastName;  
14.private Integer age;  
15.@Transient  
16.private Integer accountTotal;  
17.@DBRef  
18.private List<Account> accounts;  
19. 
20......set and get
21.}

 

2.关联方式1:DBRef 一对一,一对多 
多对多就是对方表也放个list一起保存呗 

User.java

01.public class User
02.{
03.@Id
04.private ObjectId id;
05.@Indexed
06.private String name;
07.private Integer age;
08.@DBRef
09.private Weapon weapon;//一对一
10.@DBRef
11.private List<Item> items;//一对多
12.//set,get略......
13.}

Weapon.java

1.public class Weapon
2.{
3.@Id
4.private ObjectId id;
5.private String name;
6.private int power;
7.//set,get略......
8.}

Item.java

1.public class Item
2.{
3.@Id
4.private ObjectId id;
5.private String name;
6.private String desc;
7.//set,get略......
8.}

添加:

01.private voidsave()
02.{
03.MongoTemplate template = MetaDBMongoFactory.getInstance().getMongoTemplate();
04. 
05.User user = new User();
06.user.setName("张三");
07.user.setAge(30);
08. 
09.List<Item> items = new ArrayList<Item>();
10.for (int i = 0; i < 10; i++)
11.{
12.Item item = new Item();
13.item.setName("道具" + i);
14.item.setDesc("描述");
15.template.save(item);
16.items.add(item);
17.}
18. 
19.Weapon weapon = new Weapon();
20.weapon.setName("武器");
21.weapon.setPower(99);
22.template.save(weapon);
23. 
24.user.setWeapon(weapon);
25.user.setItems(items);
26.template.save(user);
27.}

查询 
一对多的对象会全部拿出来,所以如果关联的对象特别多超过几千,请用lazy=true的方式,懒惰加载

1.User user = template.findOne(new Query(Criteria.where("id").is(id)), User.class);

DBRef查询

1.ObjectId id = user.getId();Weapon myWeapon = template.findOne(new Query(Criteria.where("name").is("武器1")),Weapon.class);
2.Query query = new Query(Criteria.where("id").is(id).and("myWeapon").is(myWeapon));
3.User queryResult = template.findOne(query, User.class);

DBRef原生查询

1.Query query = new BasicQuery("{'id':'"+id.toString()+"', 'weapon' : {'$ref':'weapon','$id':{'$oid':'52e9affffad134ac3ee2e02a'}} }");
2.User queryResult = template.findOne(query, User.class);

排序

1.Query query = new Query(Criteria.where("id").is(id));
2.query.with(new Sort(Sort.Direction.DESC, "name"));
3.......

分页,表示每页最多10条,从第3页开始

1.Query query = new Query(Criteria.where("id").is(id));
2.query.limit(10);
3.query.skip(20);

懒惰加载(1.4.0新功能,棒极了,大大提高效率)

1.@DBRef(lazy = true)
2.private List<Item> myItems;//一对多

 

3.关联方式2:集合属性 
比起DBRef模式的好处在于通过elemMatch能查询过滤。但缺点就是数据冗余。 
表字段性除了基本属性,还可以是任何对象,Map,List,这点是关系数据库做不到的。 

范例是获取用户信息,并且只取出名字是道具1的道具,如果道具特别多,这种写法可以有效加强性能

01.public class User
02.{
03.@Id
04.private ObjectId id;
05.@Indexed
06.private String name;
07.private Integer age;
08.private List<Item> items;
09.}

查询:

1.Query query = new Query(Criteria.where("id").is(id));
2.query.fields().include("items").include("name").elemMatch("items",Criteria.where("name").is("道具1"));
3.User user = template.findOne(query, User.class);

.include("items").include("name")表示查询结果集只需要这2列数据,这种做法可以减少读取的io字节大小 
elemMatch是过滤返回的items是一部分而不需要全部

 

4.聚合查询 

1).分组Group

1.GroupByResults<XObject> results =  template.group("user", GroupBy.key("age").initialDocument("{ count: 0 }").reduceFunction("function(doc, prev) { prev.count += 1 }"), XObject.class);

最后结果集里,比如看到,但最多只能处理2万条数据 
"retval":[{"age":13.0,"count":2.0},{"age":14.0,"count":1.0},{"age":30.0,"count":33.0}],"count":36.0 


2).MapReduce统计

1.MapReduceResults<User> asd = template.mapReduce("user", "function(){emit( this.id , { count : 1 } )}",
2."function(key, values){var total=0;values.forEach(function(val){total += val.count;});return {count : total};}", User.class);

3).Aggregation 
范例是统计User每个用户多少条记录,类似于oracle的group

1.class UserStats {
2.String id;
3.Integer totalCount;
4.//其它set get
5.}
1.import static org.springframework.data.mongodb.core.aggregation.Aggregation.*;
2.Aggregation agg = newAggregation(
3.User.class,
4.group("name").count().as("totalCount"),
5.sort(Sort.Direction.ASC, previousOperation(), "totalCount"),
6.match(new Criteria(.....))//过滤条件
7.);
8.AggregationResults<UserStats> aggregateResult = template.aggregate(agg, "user", UserStats.class);

结果集: 
"mappedResults":[{"id":"方佳玮","totalCount":12}]

 

5.副本集群模式下,读写分离 

统一配置:

1.template.setReadPreference(ReadPreference.nearest());
2.Weapon myWeapon = template.findOne(new Query(Criteria.where("name").is("武器1"))

原生Api

1.DBObject dbObject = coll.findOne(object, null , preference);

说明: 
primary:默认参数,只从主节点上进行读取操作; 
primaryPreferred:大部分从主节点上读取数据,只有主节点不可用时从secondary节点读取数据。 
secondary:只从secondary节点上进行读取操作,存在的问题是secondary节点的数据会比primary节点数据“旧”。 
secondaryPreferred:优先从secondary节点进行读取操作,secondary节点不可用时从主节点读取数据; 
nearest:不管是主节点、secondary节点,从网络延迟最低的节点上读取数据。

 

 

 

6.文件读写(Gridfs)

 

01.public void save(File file, String fileName) throws FileNotFoundException
02.{
03.GridFsTemplate gridFsTemplate = MetaDBMongoFactory.getInstance().getGridFsTemplate();
04.MongoTemplate template = MetaDBMongoFactory.getInstance().getMongoTemplate();
05.SinitekFiles sinitekFiles = new SinitekFiles();
06.sinitekFiles.setDesc("描述");
07.gridFsTemplate.store(new FileInputStream(file), fileName,sinitekFiles);
08.}
09. 
10.public GridFSDBFile query(String fileName) throws FileNotFoundException
11.{
12.GridFsTemplate gridFsTemplate = MetaDBMongoFactory.getInstance().getGridFsTemplate();
13.return gridFsTemplate.findOne(Query.query(Criteria.where("filename").is(fileName)));
14.}
下面是原生api方式
1.DB db = mongoDbFactory.getDb();  
保存文件(其中FS_NAME相当于gridfs文件系统的表名,可以有多个)
01.public boolean saveFile(File file, String fileName, String contentType,
02.DBObject metaData) {
03. 
04.GridFSInputFile gfsInput;
05.try {   
06.gfsInput = new GridFS(db, FS_NAME).createFile(file);
07.gfsInput.setFilename(fileName);
08.gfsInput.setContentType(contentType);
09.gfsInput.setMetaData(metaData);
10.gfsInput.save();
11.} catch (IOException e) {
12.log.error(e, e);
13.return false;
14.}
15.return true;
16.}
通过文件名读取文件
01.public GridFSDBFile findFileByName(String fileName){
02.GridFSDBFile gfsFile ;
03.try {      
04.gfsFile = new GridFS(db, FS_NAME).findOne(fileName);
05.} catch (Exception e) {
06.log.error(e, e);
07.return null;
08.}
09.return gfsFile;
10.}
通过id读取文件
01.public GridFSDBFile findFileById(String id){
02.GridFSDBFile gfsFile ;
03.try {      
04.gfsFile = new GridFS(db, FS_NAME).find(new ObjectId(id));
05.} catch (Exception e) {
06.log.error(e, e);
07.return null;
08.}
09.return gfsFile;
10.}
输出文件到OutputStream
01.private boolean writeToOutputStream(OutputStream out, GridFSDBFile gfsFile) {
02.try {     
03.gfsFile.writeTo(out);
04.} catch (IOException e) {
05.log.error(e, e);
06.return false;
07.}
08.return true;
09.}

 

 

 

 

 

7.文件读写(Document)

 

我偷懒范例选自网络,用的原生api,估计spring momgodb也差不多 

保存:
01.public static void main(String[] args) {
02.try {
03.Mongo mongo = new Mongo();
04.DB db = mongo.getDB("company");
05.DBCollection collection = db.getCollection("userinfo");
06.BasicDBObject employees = new BasicDBObject();
07.File file = new File("d://shuimohua01.jpg");
08.FileInputStream input = new FileInputStream(file);
09.byte[] files = new byte[input.available()];
10.while (input.read(files)>0) {
11.input.read(files);
12.}
13.input.close();
14.employees.put("no", "1015");
15.collection.remove(employees);
16.employees.put("member", files);
17.employees.put("filename", file.getName());
18.System.out.println(files.length);
19.collection.insert(employees);
20.} catch (UnknownHostException e) {
21.// TODO Auto-generated catch block
22.e.printStackTrace();
23.} catch (MongoException e) {
24.// TODO Auto-generated catch block
25.e.printStackTrace();
26.} catch (FileNotFoundException e) {
27.// TODO Auto-generated catch block
28.e.printStackTrace();
29.} catch (IOException e) {
30.// TODO Auto-generated catch block
31.e.printStackTrace();
32.}
33.}
34.}
读取:
01.public static void main(String[] args) {
02.try {
03.Mongo mongo = new Mongo();
04.DB db = mongo.getDB("company");
05.DBCollection collection = db.getCollection("userinfo");
06.DBObject employees = new BasicDBObject();
07.employees.put("no", "1015");
08.employees = collection.findOne(employees);
09.byte[] files = (byte[]) employees.get("member");
10.ByteArrayInputStream input = new ByteArrayInputStream(files);
11.File f = new File("e://" + employees.get("filename"));
12.FileOutputStream output = new FileOutputStream(f);
13.byte[] b=new byte[input.available()];
14.while (input.read(b)>0) {
15.input.read(b);
16.output.write(files);
17.}
18.input.close();
19.output.close();
20.} catch (UnknownHostException e) {
21.// TODO Auto-generated catch block
22.e.printStackTrace();
23.} catch (MongoException e) {
24.// TODO Auto-generated catch block
25.e.printStackTrace();
26.} catch (IOException e) {
27.// TODO Auto-generated catch block
28.e.printStackTrace();
29.}
30.}
31.}

 

分享到:
评论

相关推荐

    spring-data-mongodb-master:基于spring-data-mongodb 框架设计与实现

    本项目"spring-data-mongodb-master"深入探讨了如何利用Spring Data MongoDB框架进行数据访问层的设计与实现。首先,我们需要理解Spring Data MongoDB的核心概念,包括MongoTemplate和MongoRepository。Mongo...

    spring Data笔记和代码

    通过学习和应用Spring Data,开发者可以更专注于业务逻辑,而不是数据访问层的实现细节,从而提高开发效率和代码质量。无论是使用关系型数据库还是NoSQL数据库,Spring Data都能提供一致的编程模型和强大的查询能力...

    Spring-data-jpa 学习笔记.docx

    #### 三、SpringData方法定义规范 Spring Data JPA 通过定义方法名的约定来推断方法的行为。以下是一些常用的方法名前缀和示例: - **查询所有数据**:`findAll()` 或 `findUsers()`(假设实体类名为 User)。 - *...

    spring-data的学习笔记

    ### SpringData知识点详解 #### SpringData简介 SpringData是Spring框架下的一个重要子项目,它的主要目标是为开发者提供一种统一的方式来访问不同的数据存储系统。通过SpringData,开发者能够以一致的方式处理不同...

    springboot学习思维笔记.xmind

    springboot学习笔记 spring基础 Spring概述 Spring的简史 xml配置 注解配置 java配置 Spring概述 Spring的模块 核心容器CoreContainer Spring-Core Spring-Beans ...

    java版商城源码下载-Study-Notes:学习笔记

    jQuery-: Ajax: Vue: 微信小程序: 动态网页: 编程强化 JVM优化: 数据结构算法: 软件项目管理 Maven: SVN: Git: Jenkins: 热门技术框架 SSM: Mybatis-Plus : Spring Data: Spring: 分布式架构 Dubbo、...

    Assessment:Linux夏令营-Spring Notes-评估

    Linux夏令营的Spring笔记评估是对学员们学习成果的一次检验,旨在确保他们掌握了Spring框架的基础和高级概念。这次评估将涵盖Spring的核心组件,如IoC容器、AOP(面向切面编程)、MVC(模型-视图-控制器)架构以及...

    mongodb一些笔记

    MongoDB是一种流行的开源文档数据库系统,属于...这些笔记和教程涵盖了MongoDB的基础知识到高级用法,对于学习和理解MongoDB的操作和特性非常有帮助。通过阅读提供的文档,可以深入学习MongoDB的使用技巧和最佳实践。

    java框架学习笔记spring笔记

    8. **Spring Data**:Spring Data 提供了一种统一的方式来访问各种数据存储,如 JPA、MongoDB、Neo4j 等。它简化了 CRUD 操作,支持自定义查询,并与 Spring MVC 集成,方便构建数据驱动的 Web 应用。 9. **Spring ...

    Spring学习笔记

    这份“Spring学习笔记”涵盖了Spring框架的核心概念和技术,旨在帮助初学者和经验丰富的开发者深入理解并掌握Spring。以下是对笔记内容的详细概述: 一、Spring框架概述 Spring是一个开源的企业级Java应用框架,它...

    Spring学习笔记.zip

    Spring Data支持多种持久化技术,包括JPA(Java Persistence API)、MongoDB等,提供了统一的API和CRUD操作,以及强大的查询构造器。 **Spring Security** Spring Security是Spring生态中的安全框架,它提供了认证...

    Spring5笔记与代码.zip

    《Spring5笔记与代码》是针对Spring框架第五个主要版本的学习资源,包含了理论知识和实践代码,旨在帮助用户深入理解并掌握Spring5的核心概念和技术。本文将详细解析这些知识点,并结合提供的文件进行深入探讨。 ...

    spring入门学习笔记

    Spring Data项目旨在简化数据访问层的开发,支持多种数据存储技术,如JPA、MongoDB、Neo4j等,提供统一的API,减少开发者编写底层操作的代码。 通过以上介绍,我们可以看到Spring框架的广泛功能和灵活性,无论是...

    spring框架学习笔记

    Spring Data提供了一种统一的访问各种数据存储的方式,包括JPA、MongoDB、Redis等,大大简化了数据访问层的开发。 10. **Spring Security**: Spring Security是一个强大的安全框架,用于保护Web应用免受常见的...

    spring笔记 spring开发教程

    2. **Spring Data**:与各种数据存储系统(如JPA、MongoDB)的集成,简化了数据访问层的开发。 3. **Spring Cloud**:为分布式系统提供工具集,包括服务发现、配置管理、断路器模式等。 4. **Spring Integration**...

    尚硅谷spring boot基础篇.zip

    《尚硅谷Spring Boot基础篇》是一份全面介绍Spring Boot技术的资源集合,包含了代码实例、学习笔记和相关文档,旨在帮助初学者快速掌握这一流行的Java开发框架。Spring Boot以其简化Spring应用初始搭建以及运行过程...

    SpringBootLearn:Spring boot学习过程源码和笔记,原理之后补充

    5. **Spring Data**:Spring Boot与Spring Data结合,可以快速地实现对各种数据库(如JPA、MongoDB等)的操作。Spring Data JPA提供了强大的Repository抽象,简化了数据访问层的代码。 6. **Cloud Connectors**:...

    spring5学习笔记

    本学习笔记将深入探讨Spring 5的各个方面,包括基本概念、配置、核心组件以及最新特性。 首先,我们来了解一下Spring框架的核心概念。Spring的核心是IoC(Inversion of Control)容器,它负责管理对象的生命周期和...

    达内,tarena,spring笔记,springPPT课件,达内spring笔记

    8. **Spring Data**:一套用于简化数据访问的库,支持多种数据存储技术,如JPA、MongoDB等,提供了一致的API来处理各种数据源。 9. **Spring Integration**:提供异步处理、消息驱动和企业服务总线(ESB)功能,...

    Spring5 源码分析2020.zip

    4. **Spring Data JPA更新**:Spring Data项目针对JPA进行了优化,增强了对现代数据库系统的支持,如Spring Data MongoDB和Spring Data Elasticsearch,使得数据访问更加便捷。 5. **Cloud Support增强**:Spring ...

Global site tag (gtag.js) - Google Analytics