NoSQL 之 Morphia 操作 MongoDB
NoSQL 之 Morphia 操作 MongoDB上两篇文章:http://www.cnblogs.com/hoojo/archive/2011/06/01/2066426.html http://www.cnblogs.com/hoojo/archive/2011/06/02/2068665.html 介绍到了在MongoDB的控制台完成MongoDB的数据操作、以及通过Java MongoDB 的驱动完成在Java中对MongoDB的操作,通过前两篇文章我们对MongoDB有了全面、深刻的认识和理解。现在我们就看看利用Morphia库来操作MongoDB。 开发环境: System:Windows IDE:eclipse、MyEclipse 8 Database:mongoDB 开发依赖库: JavaEE5、mongo-2.5.3.jar、junit-4.8.2.jar Email:hoojo_@126.com Blog:http://blog.csdn.net/IBM_hoojo http://hoojo.cnblogs.com/ 一、准备工作1、 首先,下载mongoDB对Java支持的驱动包 驱动包下载地址:https://github.com/mongodb/mongo-java-driver/downloads mongoDB对Java的相关支持、技术:http://www.mongodb.org/display/DOCS/Java+Language+Center 驱动源码下载:https://download.github.com/mongodb-mongo-java-driver-r2.6.1-7-g6037357.zip 在线查看源码:https://github.com/mongodb/mongo-java-driver Morphia jar包下载:http://code.google.com/p/morphia/downloads/list 2、 下面建立一个JavaProject工程,导入下载下来的驱动包。即可在Java中使用Morphia,目录如下: 二、Java操作MongoDB示例在本示例之前你需要启动mongod.exe的服务,在你安装mongoDB的目录中,找到mongod.exe启动服务后,下面的程序才能顺利执行; 1、 Java操作mongoDB数据库,操作索引 Mongo mongo = new Mongo(); 这样就创建了一个MongoDB的数据库连接对象,它默认连接到当前机器的localhost地址,端口是27017。 DB db = mongo.getDB(“test”); 这样就获得了一个test的数据库,如果mongoDB中没有创建这个数据库也是可以正常运行的。如果你读过上一篇文章就知道,mongoDB可以在没有创建这个数据库的情况下,完成数据的添加操作。当添加的时候,没有这个库,mongoDB会自动创建当前数据库。 得到了db,下一步我们要获取一个“聚集集合DBCollection”,通过db对象的getCollection方法来完成。 DBCollection users = db.getCollection("users"); 这样就获得了一个DBCollection,它相当于我们数据库的“表”。 查询所有数据 DBCursor cur = users.find(); while (cur.hasNext()) { System.out.println(cur.next()); } 用BasicDBObjectBuilder,向users对象中添加数据 user = BasicDBObjectBuilder.start("id",1546555) .append("name","jojo").add("address","gz") .append("email","hoojo_@126.com") .get(); 插入数据 users.insert(user); 可以利用JSON工具来序列化对象数据 JSON.serialize(cur) 完整源码 package com.hoo.test;
import java.net.UnknownHostException; import com.hoo.entity.User;
import com.hoo.util.BasicDBObjectUtils; import com.mongodb.BasicDBObjectBuilder; import com.mongodb.DB; import com.mongodb.DBCollection; import com.mongodb.DBCursor; import com.mongodb.DBObject; import com.mongodb.Mongo; import com.mongodb.MongoException; import com.mongodb.util.JSON; /** * <b>function:</b> Mongo实例对象的相关方法测试 * @author hoojo * @createDate 2011-5-24 下午02:42:29 * @file MongoDBTest.java * @package com.hoo.test * @project MongoDB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_@126.com * @version 1.0 */ public class MongoDBTest {
static void main(String[] args) throws UnknownHostException,MongoException { Mongo mg = new Mongo();
System.out.println("查询所有的Database的名称");
for (String name : mg.getDatabaseNames()) {
System.out.println("dbName: " + name);
} System.out.println("查询test库中的所有collection集合(表)名称");
DB db = mg.getDB("test");
for (String name : db.getCollectionNames()) { "collectionName: " + name); "添加测试数据"); DBCollection users = db.getCollection("users");
try { // 用自定义BasicDBObjectUtils工具类,将User Enity对象转换成DBObject
DBObject user = BasicDBObjectUtils.castModel2DBObject(new User("345567","jack",22,128)">"beijin")); users.insert(user); // 用BasicDBObjectBuilder构建一个DBObject对象
user = BasicDBObjectBuilder.start("id",1546555).append("name",128)">"jojo").add("address",128)">"gz").append("email",128)">"hoojo_@126.com").get(); users.insert(user); } catch (Exception e) {
e.printStackTrace(); } "游标查询所有users集合数据"); DBCursor cur = users.find(); while (cur.hasNext()) {
System.out.println(cur.next()); "查询游标相关内容"); System.out.println(cur.count()); System.out.println(cur.getCursorId()); System.out.println(cur.getOptions()); System.out.println(cur.getQuery()); System.out.println(cur.getSizes().listIterator()); System.out.println(cur.itcount()); //System.out.println(cur.length()); System.out.println(cur.size()); System.out.println(cur.numGetMores()); System.out.println(cur.curr()); //System.out.println(cur.toArray().get(0)); "显示游标查询到的所有内容: " + JSON.serialize(cur)); } } 工具类,将带有getter、setter方法的Java类序列化成DBObject对象 package com.hoo.util;
import java.lang.reflect.Method; import com.mongodb.BasicDBObject; * <b>function:</b> 将Entity/Model转换成DBObject * @createDate 2011-5-30下午01:53:08 * @file BasicDBObjectUtil.java * @package com.hoo.util publicclass BasicDBObjectUtils { static<T> DBObject castModel2DBObject(T entity) throws Exception { Method[] method = entity.getClass().getMethods(); DBObject dbObject = new BasicDBObject();
for (Method m : method) { //System.out.println(m.getName()); if (m.getName().startsWith("get")) {
String name = m.getName().replace("get",128)">"");
for (Method m2 : method) {
if (m2.getName().equals("set" + name)) { name = name.substring(0,1).toLowerCase() + name.substring(1); Object returnVal = m.invoke(entity,255)">new Object[] {}); if (returnVal != null) {
//System.out.println(name + " : " + m.invoke(shipping,new Object[] {}));
dbObject.put(name,returnVal); } } } } "dbObject: " + dbObject); return dbObject; } 2、 完成索引操作,首先建立一个MongoDB4IndexTest.java,基本测试代码如下: import java.util.ArrayList;
import java.util.List; import org.bson.types.ObjectId; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.mongodb.Bytes; import com.mongodb.QueryOperators; * <b>function:</b> 实现MongoDB的Index操作 * @createDate 2011-6-2 下午03:21:23 * @file MongoDB4IndexTest.java class MongoDB4IndexTest { private Mongo mg = null; private DB db; private DBCollection users; @Before void init() { mg = //mg = new Mongo("localhost",27017);
catch (UnknownHostException e) { catch (MongoException e) { //获取temp DB;如果默认没有创建,mongodb会自动创建 db = mg.getDB("temp");
//获取users DBCollection;如果默认没有创建,mongodb会自动创建 users = db.getCollection( }
@After void destory() { if (mg != null) mg.close(); mg = null; db = null; users = null; System.gc(); void print(Object o) { System.out.println(o); } 3、 下面完成对象Collection的index的操作 * <b>function:</b> 测试Collection的index相关操作
* @createDate 2012-2-16 下午08:32:26 @Test void testIndex() { query(); for (DBObject index : coll.getIndexInfo()) { print("IndexInfo: " + index);
coll.dropIndexes(); //创建索引 coll.createIndex(new BasicDBObject("idx_name")); print(coll.findOne("haha")));
coll.createIndex(coll.findOne( DBObject o = "unique",true);
//coll.createIndex(coll.findOne(),o); // 修改索引,如果存在就修改不存在就添加 coll.ensureIndex(o); coll.ensureIndex("age_1");
coll.ensureIndex("age3_1",6),128)">"ts",-1));
"age_2",1),255)">new BasicDBObject( "password",2),128)">"z",128)">"idx" ));
"etc",0)">// 创建唯一索引 "emial",false)); // 创建索引,指定索引名称default_index "default_index")); // 创建索引对象,索引名称user_index coll.ensureIndex(coll.findOne("hoho")),128)">"user_index");
// 唯一索引 "hehe")),128)">"users_index_unique",0)">// 查询所有索引 print(
print(DBCollection.genIndexName(coll.findOne())); //coll.dropIndex(coll.findOne()); print(DBCollection.genIndexName(//coll.dropIndex(DBCollection.genIndexName(new BasicDBObject("password",2)));
//coll.dropIndexes(); //coll.dropIndexes("assword_1"); } 三、Morphia基本操作1、 morphia可以利用annotation对JavaEntity进行注解,那样我们就可以用morphia操作JavaEntity对象 package com.hoo.entity;
import com.google.code.morphia.annotations.Entity; import com.google.code.morphia.annotations.Id; * <b>function:</b> JavaEntity对象 * @createDate 2011-5-31上午11:45:21 * @file User.java * @package com.hoo.entity * @project Morphia //利用morphia的annotation进行注解 @Entity class User { @Id private long id;
private String name; boolean sex; int age; private String address; public User() { public User(long id,String name,255)">boolean sex,255)">int age,String address) {
super(); this.id = id; this.name = name; this.sex = sex; this.age = age; this.address = address; //getter、setter @Override public String toString() { return this.id + "#" + this.name + this.age + this.sex + this.address; } 2、 对Morphia对象一些简单的使用,看看该对象提供了哪些基本的操作方法 package com.hoo.test.morphia;
import com.google.code.morphia.Datastore; import com.google.code.morphia.EntityInterceptor; import com.google.code.morphia.Morphia; import com.google.code.morphia.mapping.MappedClass; import com.google.code.morphia.mapping.Mapper; import com.google.code.morphia.mapping.cache.EntityCache; * <b>function:</b> morphia对象的简单测试 * @createDate 2011-5-31上午11:30:20 * @file MorphiaTest.java class MorphiaTest { private Mongo mongo; private Morphia morphia; @Before mongo = morphia = new Morphia();
if (o != null) { System.out.println(o.toString()); * <b>function:</b> morphia对象的简单测试 * @author hoojo */ @SuppressWarnings("deprecation")
@Test void testMorphia() { // 创建一个Datastore,过时的方法不推荐使用 Datastore ds = morphia.createDatastore("myTestDB");
"createDatastore: " + ds); // 创建ds ds = morphia.createDatastore(mongo,0)">// 创建一个带用户名、密码的ds //ds = morphia.createDatastore(mongo,"myTestDB","admin",new char[] { '1','2','3','4','5','6' }); // 设置操作资源对象,这里设置User.class 就可以完成对User的一系列操作 //morphia.map(User.class); //morphia.mapPackage("com.hoo.entity");//会把整个包下面的类都加载进来 // 将对象转成DBObject "toDBObject: " + morphia.toDBObject(new User(System.currentTimeMillis(),128)">"jackson",true,null)));
// 将参数2转换成参数1的类型 "fromDBObject: " + morphia.fromDBObject(User.class,BasicDBObjectBuilder.start("sex",true).get())); "getMapper: " + morphia.getMapper()); "isMapped: " + morphia.isMapped(User.class));
* <b>function:</b> 对Mapper对象相关操作 * @createDate 2012-2-16下午10:20:38 void testMapper() { Mapper mapper = morphia.getMapper(); // 添加对象映射 "addMappedClass: " + mapper.addMappedClass(User.//print(mapper.addMappedClass(mapper.addMappedClass(User.class));
// 创建实体缓存 "createEntityCache: " + mapper.createEntityCache()); print(mapper.getCollectionName("myTestDB"));
print(mapper.getConverters()); User user = user.setId(1306814012734L);
print(mapper.getId(user)); for (EntityInterceptor ei : mapper.getInterceptors()) { System.out.println("EntityInterceptor: " + ei);
// 查询主键 "getKey: " + mapper.getKey(user)); // 所有已经映射的class for (MappedClass mc : mapper.getMappedClasses()) { "getMappedClasses: " + mc); "mcMap: " + mapper.getMCMap()); "getOptions: " + mapper.getOptions()); "keyToRef: " + mapper.keyToRef(mapper.getKey(user))); "refToKey: " + mapper.refToKey(mapper.keyToRef(mapper.getKey(user)))); * <b>function:</b> 实体缓存 @Test void testEntityCache() { EntityCache ec = morphia.getMapper().createEntityCache(); "EntityCache: " + ec); Datastore ds = morphia.createDatastore(mongo,244)"> User user = user.setId(1306814012734L);
// 添加实体 ec.putEntity(ds.getKey(user),user); // 代理 ec.putProxy(ds.getKey(user),128)">"getKey: " + ds.getKey(user)); "getProxy: " + ec.getProxy(ds.getKey(user))); "getEntity: " + ec.getEntity(ds.getKey(user))); print(ec.exists(ds.getKey(user))); "stats: " + ec.stats()); @After mongo = null; morphia = null; } 四、利用Morphia完成对Datastore对象的CRUD操作1、 首先添加如下准备代码,随后的方法直接添加到该文件中即可 package com.hoo.test.ds;
import com.google.code.morphia.Key; import com.google.code.morphia.query.UpdateOperations; * <b>function:</b> Datastore增删改查操作 * @createDate 2011-5-31下午06:29:04 * @fileDatastore DatastoreTest.java * @package com.hoo.test.ds class DatastoreTest { private Datastore ds; morphia.map(User.class);
* <b>function:</b> 查询所有 * @author hoojo * @createDate 2012-2-16 下午10:36:13 */ void query() { Iterable<User> it = ds.createQuery(User.class).fetch();
while(it.iterator().hasNext()) { print("fetch: " + it.iterator().next());
mongo = null; morphia = null; ds = null; } 2、 增删改CUD操作 * <b>function:</b> CUD增删改
* @createDate 2012-2-16 下午10:46:08 void testCUD() { // 添加测试数据 for (int i = 0; i < 50; i++) {
User u = new User(System.currentTimeMillis() + i,128)">"test-" + i,((i % 2 == 0)? true: false),18 + i,128)">"china-gz#" + i);
print(ds.save(u)); //ds.delete(ds.createQuery(User.class)); List<User> users = new ArrayList<User>();
users.add(new User(1306907246518L,128)">"zhangsan",128)">"china-gz"));
User user = new User(System.currentTimeMillis() + 3,128)">"zhaoliu",29,128)">"china-beijin");
users.add(user); users.add(new User(System.currentTimeMillis() + 6,128)">"wangwu",24,128)">"china-shanghai"));
new User(System.currentTimeMillis() + 9,128)">"lisi",26,128)">"china-wuhan")); //添加集合 print("save: " + ds.save(users));
//添加数组 print("save: " + ds.save(users.toArray()));
this.query(); "getKey: " + ds.find(User.//修改操作
UpdateOperations<User> uo = ds.createUpdateOperations(User."update: " + ds.update(ds.find(User. uo.add("zhaoliuliu").set("age",29).set("gzz"); "update: " + ds.update(ds.createQuery(User.class).field("id").equal(1306907246518L),1306907246518L),244)"> uo = ds.createUpdateOperations(User. uo.set("zhaoqq").set("fzz"); // 修改第一个对象 "updateFirst: " + ds.updateFirst(ds.createQuery(User.//当参数createIfMissing为true的时候,如果修改的对象不存在就会添加这条数据,如果为false的情况下,不存在也不添加
"id").equal(1306907246519L),244)"> user.setId(1306907246518L); user.setId(1306916670518L); // 合并 "merge: " + ds.merge(user).getId()); //删除 "delete: " + ds.delete(ds.createQuery(User."id").equal(1306907246518L)).getN());
"delete: " + ds.delete(ds.find(User.//print("delete: " + ds.delete(User.class,1306911594631L).getN());
} 3、 Find查询操作 * <b>function:</b> find查询
* @createDate 2012-2-16 下午10:45:55 void testFind() { "find: " + ds.find(User.class).asList());
//like "find-contains: " + ds.find(User."name").contains("test-1").asList()); //忽略大小写 "find-containsIgnoreCase: " + ds.find(User."name").containsIgnoreCase("ja").asList()); "find-endsWith: " + ds.find(User."name").endsWith("22").asList()); "find-endsWithIgnoreCase: " + ds.find(User."name").endsWithIgnoreCase("CK").asList()); //过滤null或是没有name属性的 "find-doesNotExist: " + ds.find(User."name").doesNotExist().asList());
//查询name有值的数据 "name").exists().asList()); //age > 48 "find-greaterThan: " + ds.find(User."age").greaterThan(66).asList());
//age >= 48 "age").greaterThanOrEq(66).asList()); List<Integer> ageList = new ArrayList<Integer>();
ageList.add(22); ageList.add(55); ageList.add(66); //all "find-hasAllOf: " + ds.find(User."age").hasAllOf(ageList).asList());
//in "find-hasAnyOf: " + ds.find(User."age").hasAnyOf(ageList).asList());
//not in "find-hasNoneOf: " + ds.find(User."age").hasNoneOf(ageList).asList());
//elemMatch //print("find-hasThisElement: " + ds.find(User.class).field("age").hasThisElement(55).asList()); "find-hasThisOne: " + ds.find(User."age").hasThisOne(55).asList());
"find-in: " + ds.find(User."age").in(ageList).asList());
"find-lessThan: " + ds.find(User."age").lessThan(20).asList());
"find-lessThanOrEq: " + ds.find(User."age").lessThanOrEq(18).asList());
//print("find-lessThanOrEq: " + ds.find(User.class).field("age").near(.2,.8).asList());
4、 Query查询操作 * <b>function:</b> query查询
* @createDate 2012-2-16 下午10:40:10 void testQuery() { // 查询所有 "query: " + ds.createQuery(User."query key: " + ds.createQuery(User.class).asKeyList()); // 结果集数量 class).countAll()); // 抓取查询所有记录 Iterable<User> it = ds.createQuery(User.// null
it = ds.createQuery(User.class).fetchEmptyEntities();
"fetchEmptyEntities: " + it.iterator().next()); // all key Iterable<Key<User>> itkeys = ds.createQuery(User.class).fetchKeys();
while(itkeys.iterator().hasNext()) { "fetchKeys: " + itkeys.iterator().next()); // age > 24 class).filter("age > ",24).asList());
// age in (20,28) "age in ",newint[] { 20,28 }).asList()); // limit 3 class).limit(3).asList()); // 分页类似MySQL class).offset(11).limit(5).asList()); // order排序,默认asc class).order("age").asList());
//desc "-age").asList()); // 组合排序 order by age,name "age,name").asList()); class).queryNonPrimary().asList()); class).queryPrimaryOnly().asList()); //如果include 为true就表示取该属性的值,其他的默认null,反之为false则该属性为null,取其他的值 class).retrievedFields(false,244)">} 5、 get和count查询 * <b>function:</b> get查询
* @createDate 2012-2-16 下午10:39:09 void testGet() { User user = new User();
"get: " + ds.get(user)); List<Long> ids = new ArrayList<Long>();
ids.add(1306907246519L); ids.add(1306916670524L); // 通过id集合查询相当于in () "get: " + ds.get(User.// id查询
} * <b>function:</b> count查询 * @createDate 2012-2-16 下午10:38:02 @Test void testGetCount() { user.setId(1306916670518L); "getCount: " + ds.getCount(user)); "getCount: " + ds.getCount(User. List<Long> ids = ids.add(1306907246519L);
ids.add(1306916670524L); "getCount: " + ds.getCount(ds.get(User.// age > 22的记录
"getCount: " + ds.getCount(ds.createQuery(User.// 所有
"countAll: " + ds.get(User."countAll: " + ds.find(User.} 6、 其他操作 void testOthers() {
query(); /** 索引 */ ds.ensureIndexes(); // 同时用annotation也可以给指定的属性建立索引 // 只需用在JavaEntity建立索引的属性上添加annotation /*@Indexed(value = IndexDirection.ASC,name = "address_index") String address; // 建立唯一索引 @Indexed(value = IndexDirection.ASC,name = "bandName",unique = true) String name;*/ ds.ensureCaps(); "getDB: " + ds.getDB()); "getDefaultWriteConcern: " + ds.getDefaultWriteConcern()); "DBColl: " + ds.getCollection(User.class)); // 查询User对象对应的集合 Key<User> key = ds.getKey(user); // 主键
"getKey: " + key); "exists: " + ds.exists(user)); //是否存在该对象
"exists: " + ds.exists(ds.getKey(user))); "getByKey: " + ds.getByKey(User. List<Key<User>> keys = new ArrayList<Key<User>>();
keys.add(key); user.setId(1306916670521L); keys.add(ds.getKey(user)); "getByKey: " + ds.getByKeys(keys)); "getByKey: " + ds.getByKeys(User.}
用Morphia操作对象相对比较简单,它对MongoDB对Java的操作进行了一些封装,特别是查询这方面的。有没有感觉像是在用Hibernate? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |