java使用mongodb存储数据

Mongodb使用json格式存储数据,不像关系型数据库用记录来表示,它是一种nosql数据库。数据存储用key:value形式存储,这样表示好处就是简单。

在项目中,有一个用户的实体User,他有很多朋友,当然他的朋友也在数据库里,为了建立关系,如果在关系数据库中我们会建立一个关系表UserFriend来表示这2个关系,这样表示的优点是结构清晰,缺点也显而易见,必须多执行一次查询才能获得好友id列表。。。而且要想更新好友关系那就更复杂了点,需要批量删除修改。。。

在mongodb里,就可以直接把好友id以数组形式加到用户信息的一个字段里了,这样在获取用户信息时,好友信息就直接获取,大大减少了查询请求,更新时也可以直接设值。这也就是为什么在互联网应用中倾向于使用nosql而不是关系型数据库的原因!简单、高效!

java的语法似乎不怎么喜欢json格式,通常定义一个对象,用setter和getter来操作数据,比较繁琐,却也不得已而为之!(相对来说,python等脚本语言用json很酷,可以直接用a["key"]来获取和设置字段值)。可惜这个项目已经用java来做了,用python估计不太可能了。

mongodb提供的java driver里,存取数据用DBObject,它使用类似map操作方法,把字段和值一个个put进去,读取的话可以用get方法,当时第一次接触,我就想到了用反射(reflect)来操作,获取pojo的每个字段值然后put到DBObject里,于是就写了个互相转化的方法,后来在项目中也就是这样使用了,可我写的这个方法只能处理简单类,字段只能为Integer,Long,String这集中类型,不支持数组和map。。做了一段时间,才发现我在用nosql
数据库实现关系数据库,因为我确实用了一个usrfriend集合来存储用户好友关系。。。

最近才若有所思的发现,我不该这么做,好友id列表应该直接放到用户信息里的。

在mongodb官网发现有很多第三方工具,其中有个morphia的项目,打开首页(http://code.google.com/p/morphia/),一目了然的看到了如何定义实体以及存储和查找,用了下比我这个方便多了,于是毫不犹豫的开始重构代码。。。

下面介绍下如何使用morphia

1.下载最新版本的morphia-xxx.jar 并且加入的 path里。

2.在pojo类用注解@Entity定义一个实体,用@Embedded定义一个潜入类。


3.可以直接存储数组,和map。非常方便的可以嵌套很多信息。原先要建关系表的,可以统统取消了。只用一个

查询就可以把所有信息返回了,在高并发时非常实用。

4.morphia提供了一个dao可以拓展或者实例化使用,我没有拓展,因为用了spring,有依赖注入关系,而拓展这

个DAO需要Datastore,在构造函数里无法给它。只有在注入完毕后我才可以给它。于是只有这样了

public void afterPropertiesSet() throws Exception {
this.ds = morphia.getDataStore() ;
dao = new DAO<T, String>(clazz, this.ds);
}

5.编写好一些常用接口:


/**
* 增加
*/
public void add(T t){
dao.save(t);
}
/**
* 创建一个查询
*/
protected Query<T> createQuery(){
return dao.createQuery();
}
/**
* 根据_id查询
*/
protected Query<T> createIdQuery(Object _id){
return dao.createQuery().field("_id").equal(_id);
}
/**
* 查找一个实体
*/
protected T findOne(Query<T> q){
return dao.findOne(q);
}

/**
* 根据_id查找
*/
public T findById(ObjectId _id){
return dao.findOne("_id", _id);
}
/**
* 可查找多个实体
*/
protected QueryResults<T> find(Query<T> q){
return dao.find(q);
}
/**
* 返回全部实体
*/
public List<T> getAll(){
return this.find(this.createQuery()).asList();
}
/**
* 分页查找
*/
protected QueryResults<T> find(Query<T> q, Page page){
if(page != null){
q.limit(page.getPageSize()).offset((page.getPageIndex() - 1) *

page.getPageSize());
page.setTotalCount((int) q.countAll());
}
return dao.find(q);
}
/**
* 删除实体
*/
protected void delete(T t){
dao.delete(t);
}
/**
* 根据查询删除
*/
protected void delete(Query<T> q){
dao.deleteByQuery(q);
}

/**
* 根据_id删除
*/
public void delById(ObjectId id){
Query<T> q = this.createIdQuery(id);
dao.deleteByQuery(q);
}
/**
* 更新
*/
protected void update(Query<T> q, UpdateOperations<T> ops){
dao.update(q, ops);
}
/**
* 已知_id进行添加就是更新覆盖
*/
public void update(T t){
dao.save(t);
}
/**
* 创建一个更新操作
*/
protected UpdateOperations<T> createUpdateOperations(){
return dao.createUpdateOperations();
}



这样,在具体使用时,直接定义一个User类,它里面的字段可以使用很多其他类,也可以使用数组,然后直接

save,而query时也会一起带出来,很方便,也可以大大较少数据库请求操作。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值