輸出部分將實現壹個按條件查詢,從MongoDB中得到的查詢結果將通過控制臺輸出。這樣就能模擬Web應用服務端響應請求,將數據推送到客戶端頁面的場景了。
(特別註意:本文中設計到的所有源代碼都是UTF-8格式編碼的)
先實現壹個連接屬性的配置
MongoDBConnConfig.java
package net.csdn.blog.chaijunkun;
public class MongoDBConnConfig {
//MongoDB主機名稱或IP
public static final String SERVER= "localhost";
//MongoDB端口
public static final int PORT= 27017;
//使用的數據庫名稱
public static final String ORDERS_DATABASE= "orders";
}
再實現壹個Morphia框架與MongoDB的集成方法
MongoDBDataStore.java
package net.csdn.blog.chaijunkun;
import java.net.UnknownHostException;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.Morphia;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
/**
* MongoDB聯合Morphia框架生成DataStore的類
* @author chaijunkun
*
*/
public class MongoDBDataStore {
/**
* 生成Orders數據庫Datastore對象
* @return 返回Datastore對象 發生異常返回為null
*/
public static Datastore getOrdersInstance(){
Mongo connection = null;
try {
connection = new Mongo(MongoDBConnConfig.SERVER, MongoDBConnConfig.PORT);
} catch (UnknownHostException e) {
return null;
} catch (MongoException e) {
return null;
}
Morphia morphia= new Morphia();
return morphia.createDatastore(connection, MongoDBConnConfig.ORDERS_DATABASE);
}
}
我們還需要壹個Java對象到MongoDB文檔和Java對象到輸出JSON對象的POJO實體:
OrderInfo.java
package net.csdn.blog.chaijunkun.entities;
import java.util.Date;
import org.bson.types.ObjectId;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.map.annotate.JsonDeserialize;
import org.codehaus.jackson.map.annotate.JsonSerialize;
import com.google.code.morphia.annotations.Entity;
import com.google.code.morphia.annotations.Id;
import com.google.code.morphia.annotations.PostPersist;
import com.google.code.morphia.annotations.PrePersist;
//morphia中的註解 標明該對象存入orderInfo集合中 並且不存儲類名
@Entity(value="orderInfo", noClassnameStored= true)
public class OrderInfo {
//morphia中的註解 標明該key為標識字段(MongoDB中特殊的ObjectId字段)
@Id
//Jackson中的註解 標明在序列化與反序列化過程中不使用該key
@JsonIgnore(value= true)
private ObjectId id;
private Long orderId;
private String productName;
private Integer quantity;
private Float unitPrice;
//Jackson中的註解 標明該字段使用自定義的DateSerializer類實現序列化
@JsonSerialize(using= DateSerializer.class)
//Jackson中的註解 標明該字段使用自定義的DateDeserializer類實現反序列化
@JsonDeserialize(using= DateDeserializer.class)
private Date orderDate;
private String contactName;
private String address;
private String phone;
@SuppressWarnings("unused")
//morphia中的註解 指示在存入MongoDB之前的操作
@PrePersist
private void beforeSaving(){
System.out.println("即將保存對象:"+ this.toString());
}
@SuppressWarnings("unused")
//morphia中的註解 指示在存入MongoDB之後的操作
@PostPersist
private void afterSaving(){
System.out.println("對象保存完畢:"+ this.toString());
}
//以下就是Getters和Setters了
public ObjectId getId() {
return id;
}
public void setId(ObjectId id) {
this.id = id;
}
public Long getOrderId() {
return orderId;
}
public void setOrderId(Long orderId) {
this.orderId = orderId;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public Integer getQuantity() {
return quantity;
}
public void setQuantity(Integer quantity) {
this.quantity = quantity;
}
public Float getUnitPrice() {
return unitPrice;
}
public void setUnitPrice(Float unitPrice) {
this.unitPrice = unitPrice;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
public String getContactName() {
return contactName;
}
public void setContactName(String contactName) {
this.contactName = contactName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
我們註意到上面的POJO實體中包含Date(日期)類型的數據。這類數據特別指定了它的序列化與反序列化方法,下面我們來具體看壹下:
序列化方法:DateSerializer.java
package net.csdn.blog.chaijunkun.entities;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.JsonSerializer;
import org.codehaus.jackson.map.SerializerProvider;
public class DateSerializer extends JsonSerializer<Date>{
@Override
public void serialize(Date date, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
throws IOException, JsonProcessingException {
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String formatedDate= sdf.format(date);
jsonGenerator.writeString(formatedDate);
}
}
這其實是Jackson中的壹個很實用的功能,通過自定義序列化器,可以實現Java對象到JSON的數據格式自定義。例如Date的格式我們可以任意改寫。上面的泛型類被具象為Date類型。重寫了serialize方法。輸入的date參數就是將要被序列化的數據,jsonGenerator就是序列化的上下文。當數據內容被整理好後將內容寫入序列化的上下文中就完成了自定義過程。
類似地,我們來看壹下反序列化方法DateDeserializer.java
package net.csdn.blog.chaijunkun.entities;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.JsonDeserializer;
public class DateDeserializer extends JsonDeserializer<Date>{
@Override
public Date deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException, JsonProcessingException {
String unformatedDate= jsonParser.getText();
SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date retVal;
try {
retVal = sdf.parse(unformatedDate);
} catch (ParseException e) {
return null;
}
return retVal;
}
}
泛型的JSON反序列化類被我們具象成了Date類型的,並且重寫了deserialize方法。傳入的jsonParser是反序列化過程中的上下文,通過它我們可以找到當前處理的JSON字段內容。然後將內容按照特定的要求來生成對應的數據類型(Date),然後作為返回值將其返回。此時POJO中相應的字段就順利完成了反序列化。另外這樣做還能保證類型安全。