`
279704390
  • 浏览: 11956 次
社区版块
存档分类
最新评论

morphia与spring的整合

阅读更多
首先我们需要一个生成和配置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 }

 

其次我们需要一个产生和配置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 }

 

最后我们还需要一个产生和配置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 }

 

我们来仿照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 }

 

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 }

 

还需要一个为测试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 }

 

最后是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> 

 

最后写一个测试类看看我们的成果:

 

  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 }
分享到:
评论

相关推荐

    spring MVC morphia mongo 整合的例子

    6. **Spring整合**:Spring MVC和Morphia可以通过Spring的依赖注入(DI)进行整合,使你能在控制器中直接注入`Datastore`,简化代码并提高可测试性。 7. **RESTful API设计**:示例可能展示了如何使用Spring MVC...

    spring-mongodb-morphia:springdata-mongo morphia mongodb 学习

    Spring Data的Repository抽象层可以与Morphia的实体映射相结合,提供强大的功能。例如,通过实现自定义的Repository接口,我们可以利用Morphia的查询能力,同时享受Spring Data的自动化和灵活性。 在`spring-...

    Spring整合MongoDB基于Maven

    通过以上步骤,我们已经完成了Spring与MongoDB的集成,以及基于Maven的依赖管理和JUnit测试的配置。这只是一个基础的示例,实际应用中可能需要处理更多复杂场景,如分页、聚合查询、自定义查询等。在开发过程中,...

    morphia-example-1:Java中使用Morphia ODM和Spring的示例项目

    5. **Spring与Morphia的集成**:在项目中,Morphia可能被配置为Spring的数据访问层,利用Spring的IoC容器管理和初始化Morphia的数据访问对象(DAO),同时结合Spring的数据访问支持,如数据源配置、事务管理等。...

    使用Morphia框架操作mongodb

    在Java开发中,Morphia是一个优秀的对象数据映射(ODM)框架,它简化了与MongoDB之间的交互,使得开发者可以像操作传统关系型数据库那样操作文档数据库。本文将深入探讨如何使用Morphia框架来操作MongoDB。 首先,...

    morphia-0.99.jar

    morphia-0.99.jar 最新版本。

    Mongo的ORM框架的学习Morphia

    在本文中,我们将探讨MongoDB的ORM框架Morphia,并结合Spring Data MongoDB的使用来创建一个集成应用。ORM(对象关系映射)框架是将数据库操作转化为对象模型的方法,简化了开发过程,使得开发者可以专注于业务逻辑...

    morphia所用到的jar包

    MongoDB是一个流行的开源、分布式文档数据库,而Morphia是一个Java对象数据映射(Object-Document Mapping, ODM)框架,用于简化与MongoDB的交互。在这个压缩文件中,我们有两个重要的jar包:mongo-2.7.3.jar和...

    morphia.jar和mongo.jar

    标题中的“morphia.jar”和“mongo.jar”指的是两个与MongoDB数据库操作相关的Java库文件。MongoDB是一个流行的开源、分布式文档型数据库,而Morphia则是Java开发人员用来操作MongoDB的一个对象数据映射(ODM)框架...

    使用 Morphia 和 MongoDB 实现域模型持久性(ZZ)

    Morphia 是一个 Java 框架,它为 MongoDB 提供了对象数据映射(Object Data Mapping,简称 ODM)功能,使得开发者可以更方便地在 Java 对象与 MongoDB 文档之间进行转换。本篇文章将详细介绍如何使用 Morphia 和 ...

    morphia基于mongodb的基本开发

    morphia基于mongodb的基本开发

    Morphia和MongoDB学习总结<三>

    在本文中,我们将深入探讨Morphia,一个用于Java的MongoDB对象数据映射(ODM)库,以及它如何与MongoDB数据库进行交互。Morphia简化了在MongoDB中存储和检索Java对象的过程,使得开发工作更为高效。 **一、Morphia...

    morphia-1.3.2.jar

    morphia-1.3.2.jar

    Morphia操作MongoDB

    - Morphia 提供了将对象转换为 JSON 和从 JSON 反序列化的功能,可以方便地与 JSON 文档交互。 - 使用 `JSON.serialize()` 方法将 `DBObject` 或 Java 对象序列化为 JSON 字符串。 7. **异常处理** - 在实际操作...

    Mongo集成Spring

    6. **Morphia**: `Mongo_Morthia_Spring` 可能指的是使用 Morphia 框架集成 MongoDB 和 Spring。Morphia 是一个针对 MongoDB 的对象数据映射库,它简化了将 Java 对象与 MongoDB 文档之间的转换。虽然 Spring Data ...

    Morphia开发简介.pdf

    6. **与其他框架的兼容性**:可与Guice、Spring等依赖注入框架无缝集成。 7. **扩展性**:提供多种扩展点,如新注解、转换器、行为映射和日志处理。 8. **不存储空值**:默认情况下,不存储Null或Empty值。 9. **GWT...

    Morphia 操作 MongoDB.docx

    【MongoDB与Morphia简介】 MongoDB是一款流行的NoSQL数据库系统,以其灵活的数据模型、高可用性和可扩展性而受到广泛欢迎。Morphia是针对MongoDB的一个Java持久层框架,它提供了简单易用的API,使得开发者能够方便地...

    morphia-1.00-SNAPSHOT.jar

    morphia mongo db OR-mapping mongo db再带的CRUD 太麻烦了, 一个不错的框架 类似 Hibernate

    Morphia 操作 MongoDB.pdf

    Morphia 是一个 Java ORM(对象关系映射)库,用于简化 MongoDB 的数据操作,将数据模型与数据库文档之间的转换自动化。在本文中,我们将深入探讨如何使用 Morphia 进行 MongoDB 的操作。 首先,为了在 Java 项目中...

    mongodb+springmvc+morphia

    后续提交放在https://github.com/zdsiyan/watermelon 上, 用eclipse导入该工程需安装m2eclipse,jetty等查件. 另外.settings下的org.eclipse.wst.common.component文件如下: ...&lt;/project-modules&gt;

Global site tag (gtag.js) - Google Analytics