morphia与spring的整合

简单的来说Morphia与MongoDB的关系就如Hibernate与关系数据库的关系, 是一个实现Java对象到MongoDB双向映射的类库。

首先我们需要一个生成和配置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. }  
public class MongoFactoryBean extends AbstractFactoryBean<Mongo> {

    // 表示服务器列表(主从复制或者分片)的字符串数组
    private String[] serverStrings;
    // mongoDB配置对象
    private MongoOptions mongoOptions;
    // 是否主从分离(读取从库),默认读写都在主库
    private boolean readSecondary = false;
    // 设定写策略(出错时是否抛异常),默认采用SAFE模式(需要抛异常)
    private WriteConcern writeConcern = WriteConcern.SAFE;

    @Override
    public Class<?> getObjectType() {
        return Mongo.class;
    }

    @Override
    protected Mongo createInstance() throws Exception {
        Mongo mongo = initMongo();
        
        // 设定主从分离
        if (readSecondary) {
            mongo.setReadPreference(ReadPreference.secondaryPreferred());
        }

        // 设定写策略
        mongo.setWriteConcern(writeConcern);
        return mongo;
    }
    
    /**
     * 初始化mongo实例
     * @return
     * @throws Exception
     */
    private Mongo initMongo() throws Exception {
        // 根据条件创建Mongo实例
        Mongo mongo = null;
        List<ServerAddress> serverList = getServerList();

        if (serverList.size() == 0) {
            mongo = new Mongo();
        }else if(serverList.size() == 1){
            if (mongoOptions != null) {
                mongo = new Mongo(serverList.get(0), mongoOptions);
            }else{
                mongo = new Mongo(serverList.get(0));
            }
        }else{
            if (mongoOptions != null) {
                mongo = new Mongo(serverList, mongoOptions);
            }else{
                mongo = new Mongo(serverList);
            }
        }
        return mongo;
    }
    
    
    /**
     * 根据服务器字符串列表,解析出服务器对象列表
     * <p>
     * 
     * @Title: getServerList
     *         </p>
     * 
     * @return
     * @throws Exception
     */
    private List<ServerAddress> getServerList() throws Exception {
        List<ServerAddress> serverList = new ArrayList<ServerAddress>();
        try {
            for (String serverString : serverStrings) {
                String[] temp = serverString.split(":");
                String host = temp[0];
                if (temp.length > 2) {
                    throw new IllegalArgumentException(
                            "Invalid server address string: " + serverString);
                }
                if (temp.length == 2) {
                    serverList.add(new ServerAddress(host, Integer
                            .parseInt(temp[1])));
                } else {
                    serverList.add(new ServerAddress(host));
                }
            }
            return serverList;
        } catch (Exception e) {
            throw new Exception(
                    "Error while converting serverString to ServerAddressList",
                    e);
        }
    }

    /* ------------------- setters --------------------- */
}

 


其次我们需要一个产生和配置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.  }  
public class MorphiaFactoryBean extends AbstractFactoryBean<Morphia> {
     /**
      * 要扫描并映射的包
      */
     private String[] mapPackages;  
     
     /**
      * 要映射的类
      */
     private String[] mapClasses;  
     
     /**
      * 扫描包时,是否忽略不映射的类
      * 这里按照Morphia的原始定义,默认设为false
      */
     private boolean ignoreInvalidClasses;
     
     @Override
     protected Morphia createInstance() throws Exception {
         Morphia m = new Morphia();
         if (mapPackages != null) {
             for (String packageName : mapPackages) {
                 m.mapPackage(packageName, ignoreInvalidClasses);
             }
         }
         if (mapClasses != null) {  
             for (String entityClass : mapClasses) {
                 m.map(Class.forName(entityClass));
             }
         }
         return m;
     }
 
     @Override
     public Class<?> getObjectType() {
         return Morphia.class;
     }
     
     /*----------------------setters-----------------------*/
 }


最后我们还需要一个产生和配置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.  }  
public class DatastoreFactoryBean extends AbstractFactoryBean<Datastore> {
     
     private Morphia morphia;    //morphia实例,最好是单例
     private Mongo mongo;    //mongo实例,最好是单例
     private String dbName;    //数据库名
     private String username;    //用户名,可为空
     private String password;    //密码,可为空
     private boolean toEnsureIndexes=false;    //是否确认索引存在,默认false
     private boolean toEnsureCaps=false;    //是否确认caps存在,默认false
     
 
     @Override
     protected Datastore createInstance() throws Exception {
         //这里的username和password可以为null,morphia对象会去处理
         Datastore ds = morphia.createDatastore(mongo, dbName, username,
                 password==null?null:password.toCharArray());
         if(toEnsureIndexes){
             ds.ensureIndexes();
         }
         if(toEnsureCaps){
             ds.ensureCaps();
         }
         return ds;
     }
 
     @Override
     public Class<?> getObjectType() {
         return Datastore.class;
     }
 
     @Override
     public void afterPropertiesSet() throws Exception {
         super.afterPropertiesSet();
         if (mongo == null) {
             throw new IllegalStateException("mongo is not set");
         }
         if (morphia == null) {
             throw new IllegalStateException("morphia is not set");
         }
     }
     
     /*----------------------setters-----------------------*/
 }


我们来仿照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.  }  
@Entity
 public class Hotel {
     @Id private ObjectId id;
     
     private String name;
     private int stars;
     
     @Embedded
     private Address address;    
     
     /*-----------gettters & setters----------*/
 }



 

  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. }  
@Embedded
public class Address {
    private String street;
    private String city;
    private String postCode;
    private String country;
    /*-----------gettters & setters----------*/
}

还需要一个为测试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. }  
public class HotelDAO extends BasicDAO<Hotel, ObjectId> {

    protected HotelDAO(Datastore ds) {
        super(ds);
    }
    
    /* ----------------以下是自定义的数据查询方法(finder)----------------- */
}



最后是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>   
<?xml version="1.0" encoding="UTF-8"?>  
<beans xmlns="http://www.springframework.org/schema/beans"  
    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" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">  
    
    <!-- 配置文件 -->
    <context:property-placeholder location="classpath:config.properties" />
    
    <!-- mongoDB的配置对象 -->
    <bean id="mongoOptions" class="com.mongodb.MongoOptions">
        <!-- 服务器是否自动重连,默认为false -->
        <property name="autoConnectRetry" value="false" />
        <!-- 对同一个服务器尝试重连的时间(毫秒),设为0时默认使用15秒 -->
        <property name="maxAutoConnectRetryTime" value="0" />
        <!-- 与每个主机的连接数,默认为10 -->
        <property name="connectionsPerHost" value="10" />
        <!-- 连接超时时间(毫秒),默认为10000 -->
        <property name="connectTimeout" value="10000" />
        <!-- 是否创建一个finalize方法,以便在客户端没有关闭DBCursor的实例时,清理掉它。默认为true -->
        <property name="cursorFinalizerEnabled" value="true" />
        <!-- 线程等待连接可用的最大时间(毫秒),默认为120000 -->
        <property name="maxWaitTime" value="120000" />
        <!-- 可等待线程倍数,默认为5.例如connectionsPerHost最大允许10个连接,则10*5=50个线程可以等待,更多的线程将直接抛异常 -->
        <property name="threadsAllowedToBlockForConnectionMultiplier" value="5" />
        <!-- socket读写时超时时间(毫秒),默认为0,不超时 -->
        <property name="socketTimeout" value="0" />
        <!-- 是socket连接在防火墙上保持活动的特性,默认为false -->
        <property name="socketKeepAlive" value="false" />
        <!-- 对应全局的WriteConcern.SAFE,默认为false -->
        <property name="safe" value="true" />
        <!-- 对应全局的WriteConcern中的w,默认为0 -->
        <property name="w" value="0" />
        <!-- 对应全局的WriteConcern中的wtimeout,默认为0 -->
        <property name="wtimeout" value="0" />
        <!-- 对应全局的WriteConcern.FSYNC_SAFE,如果为真,每次写入要等待写入磁盘,默认为false -->
        <property name="fsync" value="false" />
        <!-- 对应全局的WriteConcern.JOURNAL_SAFE,如果为真,每次写入要等待日志文件写入磁盘,默认为false -->
        <property name="j" value="false" />
    </bean>
    
    <!-- 使用工厂创建mongo实例 -->
    <bean id="mongo" class="me.watchzerg.test.morphia.spring.MongoFactoryBean">
        <!-- mongoDB的配置对象 -->
        <property name="mongoOptions" ref="mongoOptions"/>
        
        <!-- 是否主从分离(读取从库),默认为false,读写都在主库 -->
        <property name="readSecondary" value="false"/>
        
        <!-- 设定写策略,默认为WriteConcern.SAFE,优先级高于mongoOptions中的safe -->
        <property name="writeConcern" value="SAFE"/>
        
        <!-- 设定服务器列表,默认为localhost:27017 -->
        <property name="serverStrings">
            <array>
                <value>${mongoDB.server}</value>
            </array>
        </property>
    </bean>
    
    
    <!-- 使用工厂创建morphia实例,同时完成类映射操作 -->
    <bean id="morphia" class="me.watchzerg.test.morphia.spring.MorphiaFactoryBean" >
        <!-- 指定要扫描的POJO包路径 -->
        <property name="mapPackages">
            <array>
                <value>me.watchzerg.test.morphia.pojo</value>
            </array>
        </property>
        
        <!-- 指定要映射的类 -->
        <!-- <property name="mapClasses">
            <array>
                <value>me.watchzerg.test.morphia.pojo.Hotel</value>
                <value>me.watchzerg.test.morphia.pojo.Address</value>
            </array>
        </property> -->
        
        <!-- 扫描包时是否忽略不可用的类,默认为false -->
        <!-- <property name="ignoreInvalidClasses" value="false"/> -->
    </bean>
    
    <!-- 使用工厂创建datastore,同时完成index和caps的确认操作 -->
    <bean id="datastore" class="me.watchzerg.test.morphia.spring.DatastoreFactoryBean" >
        <property name="morphia" ref="morphia"/>
        <property name="mongo" ref="mongo"/>
        
        <!-- collection的名称 -->
        <property name="dbName" value="${mongoDB.dbName}"/>
        
        <!-- 用户名和密码可以为空 -->
        <!-- <property name="username" value="my_username"/>
        <property name="password" value="my_password"/> -->
        
        <!-- 是否进行index和caps的确认操作,默认为flase -->
        <property name="toEnsureIndexes" value="true"/>
        <property name="toEnsureCaps" value="true"/>
    </bean>
    
    <!-- ===============以下是具体DAO的实现===================== -->
    
    <bean id="hotelDAO" class="me.watchzerg.test.morphia.dao.impl.HotelDAO">
        <constructor-arg ref="datastore"/>
    </bean>
    
</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. }  
public class MorphiaTest {
   private static HotelDAO hotelDAO;

   /**
    * 测试Morphia的DAO层
    * 
    * @param args
    * @throws Exception
    */
   public static void main(String[] args) throws Exception {
       // 初始化DAO
       initDAO();

       // 插入测试
       saveTest();

       // 更新测试
       // updateTest();

       // 删除测试
       // deleteTest();

       // 查询测试
       // queryHotel();

       System.out.println("done!");
   }

   /**
    * 初始化DAO
    * <p>
    * @Title: initDAO
    * </p>
    */
   private static void initDAO() {
       ApplicationContext context = new ClassPathXmlApplicationContext(
               "config.xml");
       hotelDAO = (HotelDAO) context.getBean("hotelDAO");
   }

   /**
    * 生成指定个数的hotelList
    * <p>
    * @Title: getHotelList
    * </p>
    * 
    * @param num
    * @return
    */
   private static List<Hotel> getHotelList(int num) {
       List<Hotel> list = new ArrayList<Hotel>();
       for (int i = 0; i < num; i++) {
           Hotel hotel = new Hotel();
           hotel.setName("编号为[" + i + "]的旅店");
           hotel.setStars(i % 10);
           Address address = new Address();
           address.setCountry("中国");
           address.setCity("北京");
           address.setStreet("上帝南路");
           address.setPostCode("10000" + (i % 10));
           hotel.setAddress(address);
           list.add(hotel);
       }
       return list;
   }

   /**
    * 将hotelList插入数据库
    * <p>
    * @Title: saveHotelList
    * </p>
    * 
    * @param hotelDAO
    * @param hotelList
    */
   private static void saveTest() {
       List<Hotel> hotelList = getHotelList(100);
       for (Hotel hotel : hotelList) {
           // Key<Hotel> key=hotelDAO.save(hotel,WriteConcern.SAFE);
           Key<Hotel> key = hotelDAO.save(hotel);
           System.out.println("id为[" + key.getId() + "]的记录已被插入");
       }
   }

   /**
    * 更新操作测试
    * <p>
    * @Title: updateTest
    * </p>
    * 
    * @throws Exception
    */
   private static void updateTest() throws Exception {
       //生成查询条件
       Query<Hotel> q = hotelDAO.createQuery().field("stars")
               .greaterThanOrEq(9);
       //生成更新操作
       UpdateOperations<Hotel> ops = hotelDAO.createUpdateOperations()
               .set("address.city", "shanghai").inc("stars");
       // UpdateResults<Hotel> ur=hotelDAO.update(q, ops);
       UpdateResults<Hotel> ur = hotelDAO.updateFirst(q, ops);
       if (ur.getHadError()) {
           System.out.println(ur.getError());
           throw new Exception("更新时发生错误");
       }
       if (ur.getUpdatedExisting()) {
           System.out.println("更新成功,更新条数为[" + ur.getUpdatedCount()
                   + "],插入条数为[" + ur.getInsertedCount() + "]");
       } else {
           System.out.println("没有记录符合更新条件");
       }
   }

   /**
    * 删除操作测试
    * <p>
    * @Title: deleteTest
    * </p>
    */
   private static void deleteTest() {
       ObjectId id = hotelDAO.findIds().get(0);
       hotelDAO.deleteById(id);

       Query<Hotel> q = hotelDAO.createQuery().field("stars")
               .greaterThanOrEq(100);
       hotelDAO.deleteByQuery(q);
   }

   /**
    * 查询测试
    * <p>
    * @Title: queryHotel
    * </p>
    */
   private static void queryHotel() {
       // 显示所有记录
       System.out.println("\nhotelDAO.find()=");
       for (Hotel hotel : hotelDAO.find()) {
           System.out.println(hotel);
       }

       // 统计star大于等于9的数目
       System.out
               .println("\nhotelDAO.count(hotelDAO.createQuery().field(\"stars\").greaterThanOrEq(9))="
                       + hotelDAO.count(hotelDAO.createQuery().field("stars")
                               .greaterThanOrEq(9)));

       // 显示符合条件的记录ID
       List<ObjectId> ids = hotelDAO.findIds("stars", 8);
       System.out.println("\nhotelDAO.findIds(\"stars\", 8)=");
       for (ObjectId id : ids) {
           System.out.println(id);
       }
   }

}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值