首先我们需要一个生成和配置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 }
相关推荐
内容概要:本文详细介绍了基于TMS320F系列芯片的C2000串口读写方案及其编程器——FlashPro2000的功能特点和支持的接口模式。文中不仅涵盖了硬件连接的具体步骤,还提供了代码实例来展示Flash擦除操作,并对比了JTAG和SCI-BOOT两种模式的优缺点。此外,针对不同型号的C2000系列芯片,给出了详细的适配指导以及避免烧录过程中可能出现的问题的方法。 适合人群:从事DSP开发的技术人员,尤其是对TI公司C2000系列芯片有一定了解并希望深入了解其编程和烧录细节的人群。 使用场景及目标:适用于实验室环境下的程序调试阶段,以及生产线上的批量烧录任务。主要目的是帮助开发者选择合适的编程工具和技术手段,提高工作效率,减少因误操作导致设备损坏的风险。 其他说明:文中提供的代码片段和命令行指令可以直接用于实际项目中,同时附带了一些实用技巧,如防止芯片变砖的小贴士和自动化重试脚本,有助于解决常见的烧录难题。
汉字字库存储芯片扩展实验 # 汉字字库存储芯片扩展实验 ## 实验目的 1. 了解汉字字库的存储原理和结构 2. 掌握存储芯片扩展技术 3. 学习如何通过硬件扩展实现大容量汉字字库存储 ## 实验原理 ### 汉字字库存储基础 - 汉字通常采用点阵方式存储(如16×16、24×24、32×32点阵) - 每个汉字需要占用32字节(16×16)到128字节(32×32)不等的存储空间 - 国标GB2312-80包含6763个汉字,需要较大存储容量 ### 存储芯片扩展方法 1. **位扩展**:增加数据总线宽度 2. **字扩展**:增加存储单元数量 3. **混合扩展**:同时进行位扩展和字扩展 ## 实验设备 - 单片机开发板(如STC89C52) - 存储芯片(如27C256、29C040等) - 逻辑门电路芯片(如74HC138、74HC373等) - 示波器、万用表等测试设备 - 连接线若干 ## 实验步骤 ### 1. 单芯片汉字存储实验 1. 连接27C256 EPROM芯片到单片机系统 2. 将16×16点阵汉字字库写入芯片 3. 编写程序读取并显示汉字 ### 2. 存储芯片字扩展实验 1. 使用地址译码器(如74HC138)扩展多片27C256 2. 将完整GB2312字库分布到各芯片中 3. 编写程序实现跨芯片汉字读取 ### 3. 存储芯片位扩展实验 1. 连接两片27C256实现16位数据总线扩展 2. 优化字库存储结构,提高读取速度 3. 测试并比较扩展前后的性能差异 ## 实验代码示例(单片机部分) ```c #include <reg52.h> #include <intrins.h> // 定义存储芯片控制引脚 sbit CE = P2^7; // 片选 sbit OE = P2^6; // 输出使能 sbit
测控装备干扰源快速侦测系统设计研究.pdf
嵌入式八股文面试题库资料知识宝典-【开发】嵌入式开源项目&库&资料.zip
嵌入式八股文面试题库资料知识宝典-百度2022年嵌入式面试题.zip
少儿编程scratch项目源代码文件案例素材-空间站.zip
基于关联规则的商业银行个性化产品推荐.pdf
嵌入式八股文面试题库资料知识宝典-Linux基础使用.zip
内容概要:本文详细介绍了利用MATLAB进行轴棱锥生成贝塞尔高斯光束及环形光束光强图像的仿真研究。首先阐述了实验的背景与目标,强调了MATLAB在光学和计算科学领域的广泛应用。接着,具体描述了实验的方法与步骤,包括材料准备、仿真过程中的参数设定和光束生成代码编写。最后,对实验结果进行了深入分析,展示了贝塞尔高斯光束和环形光束的光强分布特点,验证了其光学性能的预期表现。文章还对未来的研究方向和技术改进提出了展望。 适合人群:从事光学、物理学及相关领域研究的专业人士,特别是对光束生成和光学性能分析感兴趣的科研工作者。 使用场景及目标:适用于需要进行光束生成和性能分析的实验室环境,旨在帮助研究人员更好地理解和优化光束特性和传播行为。 其他说明:本文不仅提供了详细的实验方法和步骤,还附有丰富的实验结果和数据分析,为后续研究提供了宝贵的参考资料。
内容概要:本文探讨了三电平NPC型有源电力滤波器(APF)的模型预测控制(MPC)中存在的开关频率过高问题及其解决方案。传统MPC方法会导致极高的开关频率,增加了系统的能耗和热量。通过引入滞环控制模块,可以在不大幅牺牲性能的情况下有效降低开关频率。具体来说,滞环控制通过在价值函数计算后增加一个判断条件,对状态切换进行惩罚,从而减少不必要的开关动作。实验结果显示,开关频率从4392Hz降至3242Hz,降幅达26.2%,虽然电流总谐波畸变率(THD)略有上升,但仍符合国家标准。此外,文中还提出了动态调整滞环宽度的方法,以进一步优化不同负载条件下的表现。 适合人群:从事电力电子、电力系统控制领域的研究人员和技术人员,特别是关注APF和MPC技术的人群。 使用场景及目标:适用于需要优化APF系统开关频率的研究和工程项目,旨在提高系统效率并降低成本。目标是在不影响系统性能的前提下,显著降低开关频率,减少能量损失和热管理难度。 其他说明:文章不仅提供了理论分析,还包括具体的实现代码片段,有助于读者理解和实践。同时,强调了在实际应用中需要注意的问题,如中点电位漂移等。
内容概要:本文介绍了三维POD DMD程序在处理原网格数据方面的独特优势和技术细节。首先阐述了该程序能读取结构化和非结构化网格数据及其拓扑关系,在生成模态数据过程中保持原始网格形态而不需要进行网格插值操作。接着展示了简化版本的Python代码片段,揭示了读取网格数据和生成模态数据的核心逻辑。最后提到提供的辅助学习资料如代码、视频教程、Word教程和实例数据,帮助用户深入理解并掌握该程序的应用。 适合人群:从事计算流体力学领域的研究人员和技术爱好者,尤其是那些希望提高数据处理效率的人群。 使用场景及目标:适用于需要处理复杂网格数据的研究项目,旨在简化数据处理流程,提升工作效率,同时保持数据的原始特性。 其他说明:文中不仅提供了理论性的讲解,还有具体的代码示例和丰富的学习资源,使读者可以边学边练,快速上手。
融合双向路由注意力的多尺度X光违禁品检测.pdf
嵌入式八股文面试题库资料知识宝典-Linux_Shell基础使用.zip
嵌入式八股文面试题库资料知识宝典-联发科2021武汉嵌入式软件开发.zip
基于有限体积法Godunov格式的管道泄漏检测模型研究.pdf
嵌入式八股文面试题库资料知识宝典-ARM常见面试题目.zip
基于LWR问题的无证书全同态加密方案.pdf
嵌入式八股文面试题库资料知识宝典-符坤面试经验.zip
内容概要:本文详细探讨了三电平逆变器在带不平衡负载条件下的仿真研究。主要内容包括仿真环境的搭建、不同拓扑结构的选择(如T型、I型NPC和ANPC)、延时相消法(DSC)和双二阶广义积分器(DSOGI)的正负序分离控制策略、SVPWM或SPWM调制技术的应用、双闭环PI控制以及直流均压控制。文中通过具体的参数设置(交流电压220V,直流侧电压750V)进行了详细的仿真实验,并展示了各个控制策略的效果。最终,通过仿真实验验证了所提出方法的有效性,确保了交流侧三相电压波形的对称性和电流波形的自适应调节。 适合人群:从事电力电子、电机驱动、新能源发电等领域研究的技术人员和研究人员。 使用场景及目标:适用于需要理解和掌握三电平逆变器在复杂负载条件下控制策略的研究人员和技术人员。目标是提高对三电平逆变器及其控制策略的理解,优化实际应用中的性能。 其他说明:本文不仅提供了理论分析,还包含了具体的仿真步骤和代码实现,有助于读者更好地理解和应用相关技术。
内容概要:本文介绍了如何使用Matlab/Simulink软件构建一个14自由度的四轮驱动-四轮转向(4WID-4WIS)整车动力学模型。该模型涵盖了整车纵向、横向、横摆、车身俯仰、侧倾、垂向跳动及四轮旋转和垂向自由度等多个方面,旨在全面反映车辆在不同工况下的动态行为。文中详细描述了各子系统的建模方法,包括转向系统、整车系统、悬架系统、魔术轮胎pac2002、车轮系统和PI驾驶员模块。同时,提供了Simulink源码文件、建模说明文档及相关参考资料,便于用户理解和应用。 适用人群:主要面向汽车工程师、研究人员以及对汽车动力学和Simulink建模感兴趣的学习者。 使用场景及目标:①帮助用户深入了解车辆在各种工况下的动态行为;②为车辆控制策略的制定提供理论支持和技术手段;③作为学习和研究整车动力学建模的有效工具。 其他说明:该模型采用模块化建模方法,提高了模型的清晰度和可维护性,同时也提升了建模效率。