- 浏览: 431638 次
- 性别:
- 来自: 杭州
文章分类
- 全部博客 (269)
- 原创 (7)
- Java (51)
- Java Concurrency (2)
- IDE (16)
- Linux (46)
- Database (23)
- NoSQL (35)
- Web服务器 (23)
- Log日志 (11)
- HTTP (11)
- HTML (2)
- XML (1)
- Test (7)
- Mina (0)
- Amoeba (4)
- Cobar (1)
- 序列化 (2)
- Python (5)
- PHP (1)
- Socket通信 (1)
- Network (3)
- Struts (2)
- Web前端 (10)
- Maven (6)
- SVN (15)
- Json (1)
- XMPP (2)
- Go (1)
- Other (4)
- 未整理 (5)
最新评论
-
u012374672:
[color=darkred][/color][flash=2 ...
Mongo的ORM框架的学习Morphia(annotations) -
b_l_east:
很有问题啊
利用redis的transaction功能,实现分布式下加锁
转自: http://www.blogjava.net/watchzerg/archive/2012/09/21/388291.html
最近研究mongoDB的各种pojo-mapping框架,中意的就两个:morphia和spring-data-mongodb。
本来想着spring-data-mongodb与spring的结合更紧密些,但悲剧的是其要求spring3.0.x以上版本,与生产环境不符。查了查stackoverflow,大家评价morphia更老牌更稳定一些,于是就用这个了。
研究了一番,果然与spring整合起来很麻烦。
首先看stackoverflow上的帖子,提问者跟我的想法完全一样:在spring里,我没有现成的办法调用ensureIndexes()这样的方法啊,肿么办?
http://stackoverflow.com/questions/5365315/using-morphia-with-spring
回答者给出的两个链接我也看了,真心没啥收获。
后来又搜到一篇帖子:
http://topmanopensource.iteye.com/blog/1449889
很粗略的看了一下,还不错,总之都得自己实现那些工厂类,完成与spring的集成。
看来网上这方面的需求还不少,甚至在google-code上找到一个项目叫“spring-morphia”,专门来解决这个问题:
http://code.google.com/p/spring-morphia/
貌似荒废已久,没有完成的可供下载的jar包,但是在其svn上,可以看到一些可供我们参考的类:
http://code.google.com/p/spring-morphia/source/browse/trunk/spring-morphia/src/main/java/com/so/smorphia/
本文基本上就是根据上面两个连接的思路写的,自己总结一下而已,不做过多解释了,代码里有注释。
首先我们需要一个生成和配置mongodb的工厂类:
1
public
class
MongoFactoryBean extends
AbstractFactoryBean<Mongo> {
2
3 // 表示服务器列表(主从复制或者分片)的字符串数组
4 private String[] serverStrings;
5 // mongoDB配置对象
6 private MongoOptions mongoOptions;
7 // 是否主从分离(读取从库),默认读写都在主库
8 private boolean readSecondary = false ;
9 // 设定写策略(出错时是否抛异常),默认采用SAFE模式(需要抛异常)
10 private WriteConcern writeConcern = WriteConcern.SAFE;
11
12 @Override
13 public Class<?> getObjectType() {
14 return Mongo.class ;
15 }
16
17 @Override
18 protected Mongo createInstance() throws Exception {
19 Mongo mongo = initMongo();
20
21 // 设定主从分离
22 if (readSecondary) {
23 mongo.setReadPreference(ReadPreference.secondaryPreferred());
24 }
25
26 // 设定写策略
27 mongo.setWriteConcern(writeConcern);
28 return mongo;
29 }
30
31 /**
32 * 初始化mongo实例
33 * @return
34 * @throws Exception
35 */
36 private Mongo initMongo() throws Exception {
37 // 根据条件创建Mongo实例
38 Mongo mongo = null ;
39 List<ServerAddress> serverList = getServerList();
40
41 if (serverList.size() == 0) {
42 mongo = new Mongo();
43 }else if (serverList.size() == 1){
44 if (mongoOptions != null ) {
45 mongo = new Mongo(serverList.get(0), mongoOptions);
46 }else {
47 mongo = new Mongo(serverList.get(0));
48 }
49 }else {
50 if (mongoOptions != null ) {
51 mongo = new Mongo(serverList, mongoOptions);
52 }else {
53 mongo = new Mongo(serverList);
54 }
55 }
56 return mongo;
57 }
58
59
60 /**
61 * 根据服务器字符串列表,解析出服务器对象列表
62 * <p>
63 *
64 * @Title: getServerList
65 * </p>
66 *
67 * @return
68 * @throws Exception
69 */
70 private List<ServerAddress> getServerList() throws Exception {
71 List<ServerAddress> serverList = new ArrayList<ServerAddress>();
72 try {
73 for (String serverString : serverStrings) {
74 String[] temp = serverString.split(":");
75 String host = temp[0];
76 if (temp.length > 2) {
77 throw new IllegalArgumentException(
78 "Invalid server address string: " + serverString);
79 }
80 if (temp.length == 2) {
81 serverList.add(new ServerAddress(host, Integer
82 .parseInt(temp[1])));
83 } else {
84 serverList.add(new ServerAddress(host));
85 }
86 }
87 return serverList;
88 } catch (Exception e) {
89 throw new Exception(
90 "Error while converting serverString to ServerAddressList",
91 e);
92 }
93 }
94
95 /* ------------------- setters --------------------- */
96 }
2
3 // 表示服务器列表(主从复制或者分片)的字符串数组
4 private String[] serverStrings;
5 // mongoDB配置对象
6 private MongoOptions mongoOptions;
7 // 是否主从分离(读取从库),默认读写都在主库
8 private boolean readSecondary = false ;
9 // 设定写策略(出错时是否抛异常),默认采用SAFE模式(需要抛异常)
10 private WriteConcern writeConcern = WriteConcern.SAFE;
11
12 @Override
13 public Class<?> getObjectType() {
14 return Mongo.class ;
15 }
16
17 @Override
18 protected Mongo createInstance() throws Exception {
19 Mongo mongo = initMongo();
20
21 // 设定主从分离
22 if (readSecondary) {
23 mongo.setReadPreference(ReadPreference.secondaryPreferred());
24 }
25
26 // 设定写策略
27 mongo.setWriteConcern(writeConcern);
28 return mongo;
29 }
30
31 /**
32 * 初始化mongo实例
33 * @return
34 * @throws Exception
35 */
36 private Mongo initMongo() throws Exception {
37 // 根据条件创建Mongo实例
38 Mongo mongo = null ;
39 List<ServerAddress> serverList = getServerList();
40
41 if (serverList.size() == 0) {
42 mongo = new Mongo();
43 }else if (serverList.size() == 1){
44 if (mongoOptions != null ) {
45 mongo = new Mongo(serverList.get(0), mongoOptions);
46 }else {
47 mongo = new Mongo(serverList.get(0));
48 }
49 }else {
50 if (mongoOptions != null ) {
51 mongo = new Mongo(serverList, mongoOptions);
52 }else {
53 mongo = new Mongo(serverList);
54 }
55 }
56 return mongo;
57 }
58
59
60 /**
61 * 根据服务器字符串列表,解析出服务器对象列表
62 * <p>
63 *
64 * @Title: getServerList
65 * </p>
66 *
67 * @return
68 * @throws Exception
69 */
70 private List<ServerAddress> getServerList() throws Exception {
71 List<ServerAddress> serverList = new ArrayList<ServerAddress>();
72 try {
73 for (String serverString : serverStrings) {
74 String[] temp = serverString.split(":");
75 String host = temp[0];
76 if (temp.length > 2) {
77 throw new IllegalArgumentException(
78 "Invalid server address string: " + serverString);
79 }
80 if (temp.length == 2) {
81 serverList.add(new ServerAddress(host, Integer
82 .parseInt(temp[1])));
83 } else {
84 serverList.add(new ServerAddress(host));
85 }
86 }
87 return serverList;
88 } catch (Exception e) {
89 throw new Exception(
90 "Error while converting serverString to ServerAddressList",
91 e);
92 }
93 }
94
95 /* ------------------- setters --------------------- */
96 }
其次我们需要一个产生和配置morphia对象的工厂类:
1
public
class
MorphiaFactoryBean extends
AbstractFactoryBean<Morphia> {
2 /**
3 * 要扫描并映射的包
4 */
5 private String[] mapPackages;
6
7 /**
8 * 要映射的类
9 */
10 private String[] mapClasses;
11
12 /**
13 * 扫描包时,是否忽略不映射的类
14 * 这里按照Morphia的原始定义,默认设为false
15 */
16 private boolean ignoreInvalidClasses;
17
18 @Override
19 protected Morphia createInstance() throws Exception {
20 Morphia m = new Morphia();
21 if (mapPackages != null ) {
22 for (String packageName : mapPackages) {
23 m.mapPackage(packageName, ignoreInvalidClasses);
24 }
25 }
26 if (mapClasses != null ) {
27 for (String entityClass : mapClasses) {
28 m.map(Class.forName(entityClass));
29 }
30 }
31 return m;
32 }
33
34 @Override
35 public Class<?> getObjectType() {
36 return Morphia.class ;
37 }
38
39 /* ----------------------setters----------------------- */
40 }
2 /**
3 * 要扫描并映射的包
4 */
5 private String[] mapPackages;
6
7 /**
8 * 要映射的类
9 */
10 private String[] mapClasses;
11
12 /**
13 * 扫描包时,是否忽略不映射的类
14 * 这里按照Morphia的原始定义,默认设为false
15 */
16 private boolean ignoreInvalidClasses;
17
18 @Override
19 protected Morphia createInstance() throws Exception {
20 Morphia m = new Morphia();
21 if (mapPackages != null ) {
22 for (String packageName : mapPackages) {
23 m.mapPackage(packageName, ignoreInvalidClasses);
24 }
25 }
26 if (mapClasses != null ) {
27 for (String entityClass : mapClasses) {
28 m.map(Class.forName(entityClass));
29 }
30 }
31 return m;
32 }
33
34 @Override
35 public Class<?> getObjectType() {
36 return Morphia.class ;
37 }
38
39 /* ----------------------setters----------------------- */
40 }
最后我们还需要一个产生和配置Datastore的工厂类:
1
public
class
DatastoreFactoryBean extends
AbstractFactoryBean<Datastore> {
2
3 private Morphia morphia; // morphia实例,最好是单例
4 private Mongo mongo; // mongo实例,最好是单例
5 private String dbName; // 数据库名
6 private String username; // 用户名,可为空
7 private String password; // 密码,可为空
8 private boolean toEnsureIndexes=false ; // 是否确认索引存在,默认false
9 private boolean toEnsureCaps=false ; // 是否确认caps存在,默认false
10
11
12 @Override
13 protected Datastore createInstance() throws Exception {
14 // 这里的username和password可以为null,morphia对象会去处理
15 Datastore ds = morphia.createDatastore(mongo, dbName, username,
16 password==null ?null :password.toCharArray());
17 if (toEnsureIndexes){
18 ds.ensureIndexes();
19 }
20 if (toEnsureCaps){
21 ds.ensureCaps();
22 }
23 return ds;
24 }
25
26 @Override
27 public Class<?> getObjectType() {
28 return Datastore.class ;
29 }
30
31 @Override
32 public void afterPropertiesSet() throws Exception {
33 super .afterPropertiesSet();
34 if (mongo == null ) {
35 throw new IllegalStateException("mongo is not set");
36 }
37 if (morphia == null ) {
38 throw new IllegalStateException("morphia is not set");
39 }
40 }
41
42 /* ----------------------setters----------------------- */
43 }
2
3 private Morphia morphia; // morphia实例,最好是单例
4 private Mongo mongo; // mongo实例,最好是单例
5 private String dbName; // 数据库名
6 private String username; // 用户名,可为空
7 private String password; // 密码,可为空
8 private boolean toEnsureIndexes=false ; // 是否确认索引存在,默认false
9 private boolean toEnsureCaps=false ; // 是否确认caps存在,默认false
10
11
12 @Override
13 protected Datastore createInstance() throws Exception {
14 // 这里的username和password可以为null,morphia对象会去处理
15 Datastore ds = morphia.createDatastore(mongo, dbName, username,
16 password==null ?null :password.toCharArray());
17 if (toEnsureIndexes){
18 ds.ensureIndexes();
19 }
20 if (toEnsureCaps){
21 ds.ensureCaps();
22 }
23 return ds;
24 }
25
26 @Override
27 public Class<?> getObjectType() {
28 return Datastore.class ;
29 }
30
31 @Override
32 public void afterPropertiesSet() throws Exception {
33 super .afterPropertiesSet();
34 if (mongo == null ) {
35 throw new IllegalStateException("mongo is not set");
36 }
37 if (morphia == null ) {
38 throw new IllegalStateException("morphia is not set");
39 }
40 }
41
42 /* ----------------------setters----------------------- */
43 }
我们来仿照morphia文档,写两个测试的POJO:
1
@Entity
2 public class Hotel {
3 @Id private ObjectId id;
4
5 private String name;
6 private int stars;
7
8 @Embedded
9 private Address address;
10
11 /* -----------gettters & setters---------- */
12 }
2 public class Hotel {
3 @Id private ObjectId id;
4
5 private String name;
6 private int stars;
7
8 @Embedded
9 private Address address;
10
11 /* -----------gettters & setters---------- */
12 }
1
@Embedded
2 public class Address {
3 private String street;
4 private String city;
5 private String postCode;
6 private String country;
7 /* -----------gettters & setters---------- */
8 }
2 public class Address {
3 private String street;
4 private String city;
5 private String postCode;
6 private String country;
7 /* -----------gettters & setters---------- */
8 }
还需要一个为测试POJO专门服务的DAO,这里继承morphia里的BasicDAO:
1
public
class
HotelDAO extends
BasicDAO<Hotel, ObjectId> {
2
3 protected HotelDAO(Datastore ds) {
4 super (ds);
5 }
6
7 /* ----------------以下是自定义的数据查询方法(finder)----------------- */
8 }
2
3 protected HotelDAO(Datastore ds) {
4 super (ds);
5 }
6
7 /* ----------------以下是自定义的数据查询方法(finder)----------------- */
8 }
最后是spring的XML文件:
1
<?
xml version="1.0" encoding="UTF-8"
?>
2 < beans xmlns ="http://www.springframework.org/schema/beans"
3 xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:p ="http://www.springframework.org/schema/p" xmlns:context ="http://www.springframework.org/schema/context"
4 xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
5 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd" >
6
7 <!-- 配置文件 -->
8 < context:property-placeholder location ="classpath:config.properties" />
9
10 <!-- mongoDB的配置对象 -->
11 < bean id ="mongoOptions" class ="com.mongodb.MongoOptions" >
12 <!-- 服务器是否自动重连,默认为false -->
13 < property name ="autoConnectRetry" value ="false" />
14 <!-- 对同一个服务器尝试重连的时间(毫秒),设为0时默认使用15秒 -->
15 < property name ="maxAutoConnectRetryTime" value ="0" />
16 <!-- 与每个主机的连接数,默认为10 -->
17 < property name ="connectionsPerHost" value ="10" />
18 <!-- 连接超时时间(毫秒),默认为10000 -->
19 < property name ="connectTimeout" value ="10000" />
20 <!-- 是否创建一个finalize方法,以便在客户端没有关闭DBCursor的实例时,清理掉它。默认为true -->
21 < property name ="cursorFinalizerEnabled" value ="true" />
22 <!-- 线程等待连接可用的最大时间(毫秒),默认为120000 -->
23 < property name ="maxWaitTime" value ="120000" />
24 <!-- 可等待线程倍数,默认为5.例如connectionsPerHost最大允许10个连接,则10*5=50个线程可以等待,更多的线程将直接抛异常 -->
25 < property name ="threadsAllowedToBlockForConnectionMultiplier" value ="5" />
26 <!-- socket读写时超时时间(毫秒),默认为0,不超时 -->
27 < property name ="socketTimeout" value ="0" />
28 <!-- 是socket连接在防火墙上保持活动的特性,默认为false -->
29 < property name ="socketKeepAlive" value ="false" />
30 <!-- 对应全局的WriteConcern.SAFE,默认为false -->
31 < property name ="safe" value ="true" />
32 <!-- 对应全局的WriteConcern中的w,默认为0 -->
33 < property name ="w" value ="0" />
34 <!-- 对应全局的WriteConcern中的wtimeout,默认为0 -->
35 < property name ="wtimeout" value ="0" />
36 <!-- 对应全局的WriteConcern.FSYNC_SAFE,如果为真,每次写入要等待写入磁盘,默认为false -->
37 < property name ="fsync" value ="false" />
38 <!-- 对应全局的WriteConcern.JOURNAL_SAFE,如果为真,每次写入要等待日志文件写入磁盘,默认为false -->
39 < property name ="j" value ="false" />
40 </ bean >
41
42 <!-- 使用工厂创建mongo实例 -->
43 < bean id ="mongo" class ="me.watchzerg.test.morphia.spring.MongoFactoryBean" >
44 <!-- mongoDB的配置对象 -->
45 < property name ="mongoOptions" ref ="mongoOptions" />
46
47 <!-- 是否主从分离(读取从库),默认为false,读写都在主库 -->
48 < property name ="readSecondary" value ="false" />
49
50 <!-- 设定写策略,默认为WriteConcern.SAFE,优先级高于mongoOptions中的safe -->
51 < property name ="writeConcern" value ="SAFE" />
52
53 <!-- 设定服务器列表,默认为localhost:27017 -->
54 < property name ="serverStrings" >
55 < array >
56 < value > ${mongoDB.server}</ value >
57 </ array >
58 </ property >
59 </ bean >
60
61
62 <!-- 使用工厂创建morphia实例,同时完成类映射操作 -->
63 < bean id ="morphia" class ="me.watchzerg.test.morphia.spring.MorphiaFactoryBean" >
64 <!-- 指定要扫描的POJO包路径 -->
65 < property name ="mapPackages" >
66 < array >
67 < value > me.watchzerg.test.morphia.pojo</ value >
68 </ array >
69 </ property >
70
71 <!-- 指定要映射的类 -->
72 <!-- <property name="mapClasses">
73 <array>
74 <value>me.watchzerg.test.morphia.pojo.Hotel</value>
75 <value>me.watchzerg.test.morphia.pojo.Address</value>
76 </array>
77 </property> -->
78
79 <!-- 扫描包时是否忽略不可用的类,默认为false -->
80 <!-- <property name="ignoreInvalidClasses" value="false"/> -->
81 </ bean >
82
83 <!-- 使用工厂创建datastore,同时完成index和caps的确认操作 -->
84 < bean id ="datastore" class ="me.watchzerg.test.morphia.spring.DatastoreFactoryBean" >
85 < property name ="morphia" ref ="morphia" />
86 < property name ="mongo" ref ="mongo" />
87
88 <!-- collection的名称 -->
89 < property name ="dbName" value ="${mongoDB.dbName}" />
90
91 <!-- 用户名和密码可以为空 -->
92 <!-- <property name="username" value="my_username"/>
93 <property name="password" value="my_password"/> -->
94
95 <!-- 是否进行index和caps的确认操作,默认为flase -->
96 < property name ="toEnsureIndexes" value ="true" />
97 < property name ="toEnsureCaps" value ="true" />
98 </ bean >
99
100 <!-- ===============以下是具体DAO的实现===================== -->
101
102 < bean id ="hotelDAO" class ="me.watchzerg.test.morphia.dao.impl.HotelDAO" >
103 < constructor-arg ref ="datastore" />
104 </ bean >
105
106 </ beans >
2 < beans xmlns ="http://www.springframework.org/schema/beans"
3 xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" xmlns:p ="http://www.springframework.org/schema/p" xmlns:context ="http://www.springframework.org/schema/context"
4 xsi:schemaLocation ="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
5 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd" >
6
7 <!-- 配置文件 -->
8 < context:property-placeholder location ="classpath:config.properties" />
9
10 <!-- mongoDB的配置对象 -->
11 < bean id ="mongoOptions" class ="com.mongodb.MongoOptions" >
12 <!-- 服务器是否自动重连,默认为false -->
13 < property name ="autoConnectRetry" value ="false" />
14 <!-- 对同一个服务器尝试重连的时间(毫秒),设为0时默认使用15秒 -->
15 < property name ="maxAutoConnectRetryTime" value ="0" />
16 <!-- 与每个主机的连接数,默认为10 -->
17 < property name ="connectionsPerHost" value ="10" />
18 <!-- 连接超时时间(毫秒),默认为10000 -->
19 < property name ="connectTimeout" value ="10000" />
20 <!-- 是否创建一个finalize方法,以便在客户端没有关闭DBCursor的实例时,清理掉它。默认为true -->
21 < property name ="cursorFinalizerEnabled" value ="true" />
22 <!-- 线程等待连接可用的最大时间(毫秒),默认为120000 -->
23 < property name ="maxWaitTime" value ="120000" />
24 <!-- 可等待线程倍数,默认为5.例如connectionsPerHost最大允许10个连接,则10*5=50个线程可以等待,更多的线程将直接抛异常 -->
25 < property name ="threadsAllowedToBlockForConnectionMultiplier" value ="5" />
26 <!-- socket读写时超时时间(毫秒),默认为0,不超时 -->
27 < property name ="socketTimeout" value ="0" />
28 <!-- 是socket连接在防火墙上保持活动的特性,默认为false -->
29 < property name ="socketKeepAlive" value ="false" />
30 <!-- 对应全局的WriteConcern.SAFE,默认为false -->
31 < property name ="safe" value ="true" />
32 <!-- 对应全局的WriteConcern中的w,默认为0 -->
33 < property name ="w" value ="0" />
34 <!-- 对应全局的WriteConcern中的wtimeout,默认为0 -->
35 < property name ="wtimeout" value ="0" />
36 <!-- 对应全局的WriteConcern.FSYNC_SAFE,如果为真,每次写入要等待写入磁盘,默认为false -->
37 < property name ="fsync" value ="false" />
38 <!-- 对应全局的WriteConcern.JOURNAL_SAFE,如果为真,每次写入要等待日志文件写入磁盘,默认为false -->
39 < property name ="j" value ="false" />
40 </ bean >
41
42 <!-- 使用工厂创建mongo实例 -->
43 < bean id ="mongo" class ="me.watchzerg.test.morphia.spring.MongoFactoryBean" >
44 <!-- mongoDB的配置对象 -->
45 < property name ="mongoOptions" ref ="mongoOptions" />
46
47 <!-- 是否主从分离(读取从库),默认为false,读写都在主库 -->
48 < property name ="readSecondary" value ="false" />
49
50 <!-- 设定写策略,默认为WriteConcern.SAFE,优先级高于mongoOptions中的safe -->
51 < property name ="writeConcern" value ="SAFE" />
52
53 <!-- 设定服务器列表,默认为localhost:27017 -->
54 < property name ="serverStrings" >
55 < array >
56 < value > ${mongoDB.server}</ value >
57 </ array >
58 </ property >
59 </ bean >
60
61
62 <!-- 使用工厂创建morphia实例,同时完成类映射操作 -->
63 < bean id ="morphia" class ="me.watchzerg.test.morphia.spring.MorphiaFactoryBean" >
64 <!-- 指定要扫描的POJO包路径 -->
65 < property name ="mapPackages" >
66 < array >
67 < value > me.watchzerg.test.morphia.pojo</ value >
68 </ array >
69 </ property >
70
71 <!-- 指定要映射的类 -->
72 <!-- <property name="mapClasses">
73 <array>
74 <value>me.watchzerg.test.morphia.pojo.Hotel</value>
75 <value>me.watchzerg.test.morphia.pojo.Address</value>
76 </array>
77 </property> -->
78
79 <!-- 扫描包时是否忽略不可用的类,默认为false -->
80 <!-- <property name="ignoreInvalidClasses" value="false"/> -->
81 </ bean >
82
83 <!-- 使用工厂创建datastore,同时完成index和caps的确认操作 -->
84 < bean id ="datastore" class ="me.watchzerg.test.morphia.spring.DatastoreFactoryBean" >
85 < property name ="morphia" ref ="morphia" />
86 < property name ="mongo" ref ="mongo" />
87
88 <!-- collection的名称 -->
89 < property name ="dbName" value ="${mongoDB.dbName}" />
90
91 <!-- 用户名和密码可以为空 -->
92 <!-- <property name="username" value="my_username"/>
93 <property name="password" value="my_password"/> -->
94
95 <!-- 是否进行index和caps的确认操作,默认为flase -->
96 < property name ="toEnsureIndexes" value ="true" />
97 < property name ="toEnsureCaps" value ="true" />
98 </ bean >
99
100 <!-- ===============以下是具体DAO的实现===================== -->
101
102 < bean id ="hotelDAO" class ="me.watchzerg.test.morphia.dao.impl.HotelDAO" >
103 < constructor-arg ref ="datastore" />
104 </ bean >
105
106 </ beans >
最后写一个测试类看看我们的成果:
1
public
class
MorphiaTest {
2 private static HotelDAO hotelDAO;
3
4 /**
5 * 测试Morphia的DAO层
6 *
7 * @param args
8 * @throws Exception
9 */
10 public static void main(String[] args) throws Exception {
11 // 初始化DAO
12 initDAO();
13
14 // 插入测试
15 saveTest();
16
17 // 更新测试
18 // updateTest();
19
20 // 删除测试
21 // deleteTest();
22
23 // 查询测试
24 // queryHotel();
25
26 System.out.println("done!");
27 }
28
29 /**
30 * 初始化DAO
31 * <p>
32 * @Title: initDAO
33 * </p>
34 */
35 private static void initDAO() {
36 ApplicationContext context = new ClassPathXmlApplicationContext(
37 "config.xml");
38 hotelDAO = (HotelDAO) context.getBean("hotelDAO");
39 }
40
41 /**
42 * 生成指定个数的hotelList
43 * <p>
44 * @Title: getHotelList
45 * </p>
46 *
47 * @param num
48 * @return
49 */
50 private static List<Hotel> getHotelList(int num) {
51 List<Hotel> list = new ArrayList<Hotel>();
52 for (int i = 0; i < num; i++) {
53 Hotel hotel = new Hotel();
54 hotel.setName("编号为[" + i + "]的旅店");
55 hotel.setStars(i % 10);
56 Address address = new Address();
57 address.setCountry("中国");
58 address.setCity("北京");
59 address.setStreet("上帝南路");
60 address.setPostCode("10000" + (i % 10));
61 hotel.setAddress(address);
62 list.add(hotel);
63 }
64 return list;
65 }
66
67 /**
68 * 将hotelList插入数据库
69 * <p>
70 * @Title: saveHotelList
71 * </p>
72 *
73 * @param hotelDAO
74 * @param hotelList
75 */
76 private static void saveTest() {
77 List<Hotel> hotelList = getHotelList(100);
78 for (Hotel hotel : hotelList) {
79 // Key<Hotel> key=hotelDAO.save(hotel,WriteConcern.SAFE);
80 Key<Hotel> key = hotelDAO.save(hotel);
81 System.out.println("id为[" + key.getId() + "]的记录已被插入");
82 }
83 }
84
85 /**
86 * 更新操作测试
87 * <p>
88 * @Title: updateTest
89 * </p>
90 *
91 * @throws Exception
92 */
93 private static void updateTest() throws Exception {
94 // 生成查询条件
95 Query<Hotel> q = hotelDAO.createQuery().field("stars")
96 .greaterThanOrEq(9);
97 // 生成更新操作
98 UpdateOperations<Hotel> ops = hotelDAO.createUpdateOperations()
99 .set("address.city", "shanghai").inc("stars");
100 // UpdateResults<Hotel> ur=hotelDAO.update(q, ops);
101 UpdateResults<Hotel> ur = hotelDAO.updateFirst(q, ops);
102 if (ur.getHadError()) {
103 System.out.println(ur.getError());
104 throw new Exception("更新时发生错误");
105 }
106 if (ur.getUpdatedExisting()) {
107 System.out.println("更新成功,更新条数为[" + ur.getUpdatedCount()
108 + "],插入条数为[" + ur.getInsertedCount() + "]");
109 } else {
110 System.out.println("没有记录符合更新条件");
111 }
112 }
113
114 /**
115 * 删除操作测试
116 * <p>
117 * @Title: deleteTest
118 * </p>
119 */
120 private static void deleteTest() {
121 ObjectId id = hotelDAO.findIds().get(0);
122 hotelDAO.deleteById(id);
123
124 Query<Hotel> q = hotelDAO.createQuery().field("stars")
125 .greaterThanOrEq(100);
126 hotelDAO.deleteByQuery(q);
127 }
128
129 /**
130 * 查询测试
131 * <p>
132 * @Title: queryHotel
133 * </p>
134 */
135 private static void queryHotel() {
136 // 显示所有记录
137 System.out.println("\nhotelDAO.find()=");
138 for (Hotel hotel : hotelDAO.find()) {
139 System.out.println(hotel);
140 }
141
142 // 统计star大于等于9的数目
143 System.out
144 .println("\nhotelDAO.count(hotelDAO.createQuery().field(\"stars\").greaterThanOrEq(9))="
145 + hotelDAO.count(hotelDAO.createQuery().field("stars")
146 .greaterThanOrEq(9)));
147
148 // 显示符合条件的记录ID
149 List<ObjectId> ids = hotelDAO.findIds("stars", 8);
150 System.out.println("\nhotelDAO.findIds(\"stars\", 8)=");
151 for (ObjectId id : ids) {
152 System.out.println(id);
153 }
154 }
155
156 }
2 private static HotelDAO hotelDAO;
3
4 /**
5 * 测试Morphia的DAO层
6 *
7 * @param args
8 * @throws Exception
9 */
10 public static void main(String[] args) throws Exception {
11 // 初始化DAO
12 initDAO();
13
14 // 插入测试
15 saveTest();
16
17 // 更新测试
18 // updateTest();
19
20 // 删除测试
21 // deleteTest();
22
23 // 查询测试
24 // queryHotel();
25
26 System.out.println("done!");
27 }
28
29 /**
30 * 初始化DAO
31 * <p>
32 * @Title: initDAO
33 * </p>
34 */
35 private static void initDAO() {
36 ApplicationContext context = new ClassPathXmlApplicationContext(
37 "config.xml");
38 hotelDAO = (HotelDAO) context.getBean("hotelDAO");
39 }
40
41 /**
42 * 生成指定个数的hotelList
43 * <p>
44 * @Title: getHotelList
45 * </p>
46 *
47 * @param num
48 * @return
49 */
50 private static List<Hotel> getHotelList(int num) {
51 List<Hotel> list = new ArrayList<Hotel>();
52 for (int i = 0; i < num; i++) {
53 Hotel hotel = new Hotel();
54 hotel.setName("编号为[" + i + "]的旅店");
55 hotel.setStars(i % 10);
56 Address address = new Address();
57 address.setCountry("中国");
58 address.setCity("北京");
59 address.setStreet("上帝南路");
60 address.setPostCode("10000" + (i % 10));
61 hotel.setAddress(address);
62 list.add(hotel);
63 }
64 return list;
65 }
66
67 /**
68 * 将hotelList插入数据库
69 * <p>
70 * @Title: saveHotelList
71 * </p>
72 *
73 * @param hotelDAO
74 * @param hotelList
75 */
76 private static void saveTest() {
77 List<Hotel> hotelList = getHotelList(100);
78 for (Hotel hotel : hotelList) {
79 // Key<Hotel> key=hotelDAO.save(hotel,WriteConcern.SAFE);
80 Key<Hotel> key = hotelDAO.save(hotel);
81 System.out.println("id为[" + key.getId() + "]的记录已被插入");
82 }
83 }
84
85 /**
86 * 更新操作测试
87 * <p>
88 * @Title: updateTest
89 * </p>
90 *
91 * @throws Exception
92 */
93 private static void updateTest() throws Exception {
94 // 生成查询条件
95 Query<Hotel> q = hotelDAO.createQuery().field("stars")
96 .greaterThanOrEq(9);
97 // 生成更新操作
98 UpdateOperations<Hotel> ops = hotelDAO.createUpdateOperations()
99 .set("address.city", "shanghai").inc("stars");
100 // UpdateResults<Hotel> ur=hotelDAO.update(q, ops);
101 UpdateResults<Hotel> ur = hotelDAO.updateFirst(q, ops);
102 if (ur.getHadError()) {
103 System.out.println(ur.getError());
104 throw new Exception("更新时发生错误");
105 }
106 if (ur.getUpdatedExisting()) {
107 System.out.println("更新成功,更新条数为[" + ur.getUpdatedCount()
108 + "],插入条数为[" + ur.getInsertedCount() + "]");
109 } else {
110 System.out.println("没有记录符合更新条件");
111 }
112 }
113
114 /**
115 * 删除操作测试
116 * <p>
117 * @Title: deleteTest
118 * </p>
119 */
120 private static void deleteTest() {
121 ObjectId id = hotelDAO.findIds().get(0);
122 hotelDAO.deleteById(id);
123
124 Query<Hotel> q = hotelDAO.createQuery().field("stars")
125 .greaterThanOrEq(100);
126 hotelDAO.deleteByQuery(q);
127 }
128
129 /**
130 * 查询测试
131 * <p>
132 * @Title: queryHotel
133 * </p>
134 */
135 private static void queryHotel() {
136 // 显示所有记录
137 System.out.println("\nhotelDAO.find()=");
138 for (Hotel hotel : hotelDAO.find()) {
139 System.out.println(hotel);
140 }
141
142 // 统计star大于等于9的数目
143 System.out
144 .println("\nhotelDAO.count(hotelDAO.createQuery().field(\"stars\").greaterThanOrEq(9))="
145 + hotelDAO.count(hotelDAO.createQuery().field("stars")
146 .greaterThanOrEq(9)));
147
148 // 显示符合条件的记录ID
149 List<ObjectId> ids = hotelDAO.findIds("stars", 8);
150 System.out.println("\nhotelDAO.findIds(\"stars\", 8)=");
151 for (ObjectId id : ids) {
152 System.out.println(id);
153 }
154 }
155
156 }
大功告成~
发表评论
-
mongodb 地理位置处理
2016-05-16 13:39 1430我只记录我用到的部分,没有完整分析mongodb对地理位置 ... -
Redis配置文件redis.conf
2014-11-14 14:10 1879# Redis configuration file ex ... -
Redis高可用部署及监控
2014-11-12 13:25 1111一、 Re ... -
JCS官方文档的简单笔记,仅供自己参考
2014-09-26 20:08 7851. 基本配置 jcs.default=DCjcs.de ... -
JCS基本配置
2014-09-26 19:39 9511、默认的内存缓存 ... -
NoSQL解决方案比较(MongoDB vs Redis, Tokyo Cabinet, and Berkeley DB)
2013-09-30 14:20 1350NoSQL解决方案比较 NoSQL Solution: E ... -
Mongo的ORM框架的学习Morphia(十五)Morphia+spring整合
2012-12-07 15:06 1666转自:http://topmanopensource.itey ... -
Mongo的ORM框架的学习Morphia(十二) morphia的Query和Update
2012-12-07 15:06 1890转自:http://topmanopensource.itey ... -
Mongo的ORM框架的学习Morphia(十) morphia应用
2012-12-05 14:47 1471转自:http://topmanopensource.itey ... -
Mongo的ORM框架的学习Morphia(九) morphia简单使用
2012-12-05 14:44 1388转自 http://topmanopensource.itey ... -
Mongo的ORM框架的学习Morphia(八) morphia数据库访问接口
2012-12-05 14:35 2026转自:http://topmanopensource.itey ... -
Mongo的ORM框架的学习Morphia(annotations)
2012-12-05 14:33 2553一:@Entity的使用 @Entity ... -
Instagram的Redis实践(内存占用优化)
2012-11-30 10:43 1211转自:http://blog.nosqlfan.com/htm ... -
SQL 和Mongo 对比图表
2012-11-28 14:54 2217参看官方说明: http://www.mongodb ... -
MongoDB 入门指南、示例
2012-11-23 10:38 860转自:http://www.cnblogs.com/hoojo ... -
mongodb中使用MapReduce
2012-11-23 10:12 1219MapReduce函数的用法如下: db.users.ma ... -
python的redis用法
2012-11-22 15:48 1178#! /usr/bin/env python #coding ... -
Python连接redis
2012-11-22 15:46 5627一、Redis是流行的NOSQL内存数据库,以Key-Valu ... -
【pipeline】【分布式的id生成器】【分布式锁【watch】【multi】】【redis分布式】
2012-08-29 10:42 1383转自 http://www.bwkeji.com/a/wang ... -
利用redis的transaction功能,实现分布式下加锁
2012-08-29 09:57 2424package memcached; import ja ...
相关推荐
6. **Spring整合**:Spring MVC和Morphia可以通过Spring的依赖注入(DI)进行整合,使你能在控制器中直接注入`Datastore`,简化代码并提高可测试性。 7. **RESTful API设计**:示例可能展示了如何使用Spring MVC...
Spring Data的Repository抽象层可以与Morphia的实体映射相结合,提供强大的功能。例如,通过实现自定义的Repository接口,我们可以利用Morphia的查询能力,同时享受Spring Data的自动化和灵活性。 在`spring-...
通过以上步骤,我们已经完成了Spring与MongoDB的集成,以及基于Maven的依赖管理和JUnit测试的配置。这只是一个基础的示例,实际应用中可能需要处理更多复杂场景,如分页、聚合查询、自定义查询等。在开发过程中,...
5. **Spring与Morphia的集成**:在项目中,Morphia可能被配置为Spring的数据访问层,利用Spring的IoC容器管理和初始化Morphia的数据访问对象(DAO),同时结合Spring的数据访问支持,如数据源配置、事务管理等。...
在Java开发中,Morphia是一个优秀的对象数据映射(ODM)框架,它简化了与MongoDB之间的交互,使得开发者可以像操作传统关系型数据库那样操作文档数据库。本文将深入探讨如何使用Morphia框架来操作MongoDB。 首先,...
morphia-0.99.jar 最新版本。
在本文中,我们将探讨MongoDB的ORM框架Morphia,并结合Spring Data MongoDB的使用来创建一个集成应用。ORM(对象关系映射)框架是将数据库操作转化为对象模型的方法,简化了开发过程,使得开发者可以专注于业务逻辑...
MongoDB是一个流行的开源、分布式文档数据库,而Morphia是一个Java对象数据映射(Object-Document Mapping, ODM)框架,用于简化与MongoDB的交互。在这个压缩文件中,我们有两个重要的jar包:mongo-2.7.3.jar和...
标题中的“morphia.jar”和“mongo.jar”指的是两个与MongoDB数据库操作相关的Java库文件。MongoDB是一个流行的开源、分布式文档型数据库,而Morphia则是Java开发人员用来操作MongoDB的一个对象数据映射(ODM)框架...
Morphia 是一个 Java 框架,它为 MongoDB 提供了对象数据映射(Object Data Mapping,简称 ODM)功能,使得开发者可以更方便地在 Java 对象与 MongoDB 文档之间进行转换。本篇文章将详细介绍如何使用 Morphia 和 ...
morphia基于mongodb的基本开发
在本文中,我们将深入探讨Morphia,一个用于Java的MongoDB对象数据映射(ODM)库,以及它如何与MongoDB数据库进行交互。Morphia简化了在MongoDB中存储和检索Java对象的过程,使得开发工作更为高效。 **一、Morphia...
morphia-1.3.2.jar
- Morphia 提供了将对象转换为 JSON 和从 JSON 反序列化的功能,可以方便地与 JSON 文档交互。 - 使用 `JSON.serialize()` 方法将 `DBObject` 或 Java 对象序列化为 JSON 字符串。 7. **异常处理** - 在实际操作...
6. **Morphia**: `Mongo_Morthia_Spring` 可能指的是使用 Morphia 框架集成 MongoDB 和 Spring。Morphia 是一个针对 MongoDB 的对象数据映射库,它简化了将 Java 对象与 MongoDB 文档之间的转换。虽然 Spring Data ...
6. **与其他框架的兼容性**:可与Guice、Spring等依赖注入框架无缝集成。 7. **扩展性**:提供多种扩展点,如新注解、转换器、行为映射和日志处理。 8. **不存储空值**:默认情况下,不存储Null或Empty值。 9. **GWT...
【MongoDB与Morphia简介】 MongoDB是一款流行的NoSQL数据库系统,以其灵活的数据模型、高可用性和可扩展性而受到广泛欢迎。Morphia是针对MongoDB的一个Java持久层框架,它提供了简单易用的API,使得开发者能够方便地...
morphia mongo db OR-mapping mongo db再带的CRUD 太麻烦了, 一个不错的框架 类似 Hibernate
Morphia 是一个 Java ORM(对象关系映射)库,用于简化 MongoDB 的数据操作,将数据模型与数据库文档之间的转换自动化。在本文中,我们将深入探讨如何使用 Morphia 进行 MongoDB 的操作。 首先,为了在 Java 项目中...
后续提交放在https://github.com/zdsiyan/watermelon 上, 用eclipse导入该工程需安装m2eclipse,jetty等查件. 另外.settings下的org.eclipse.wst.common.component文件如下: ...</project-modules>