在这个博客的制作中,决定使用mongodb来对文章和图片进行存储,如果纯粹使用mongodb的api来进行crud操作的话,非常麻烦,
所以在这里采用Morphia,mongodb的一个orm框架,十分好用,具体dependcy如下:
org.mongodb
mongo-java-driver
${mongodb.version}
org.mongodb.morphia
morphia
${morphia.version}
在整合Morphia之前,我还参考了一下别人的博文的编写,其中采用许多那篇博文的代码:
具体分为如下:
MongoFactoryBean:
package cn.com.morphia;
import com.mongodb.*;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Administrator on 2016/1/17.
*/
public class MongoFactoryBean extends AbstractFactoryBean {
/**
* 表示服务器列表
*/
private String[] serverStrings;
/**
* mongo配置对象
*/
private MongoOptions mongoOptions;
/**
* 是否主从分离,默认为false
*/
private boolean readSecondary = false;
public String[] getServerStrings() {
return serverStrings;
}
public void setServerStrings(String[] serverStrings) {
this.serverStrings = serverStrings;
}
public MongoOptions getMongoOptions() {
return mongoOptions;
}
public void setMongoOptions(MongoOptions mongoOptions) {
this.mongoOptions = mongoOptions;
}
public WriteConcern getWriteConcern() {
return writeConcern;
}
public void setWriteConcern(WriteConcern writeConcern) {
this.writeConcern = writeConcern;
}
public boolean isReadSecondary() {
return readSecondary;
}
public void setReadSecondary(boolean readSecondary) {
this.readSecondary = readSecondary;
}
/**
* 设定写策略,默认采用SAFE模式(需要抛异常)
*/
private WriteConcern writeConcern = WriteConcern.SAFE;
@Override
public Class> getObjectType() {
return MongoClient.class;
}
@Override
protected MongoClient createInstance() throws Exception {
MongoClient mongo = initMongo();
//设定主从分离
if (readSecondary) {
mongo.setReadPreference(ReadPreference.secondaryPreferred());
}
//设定写策略
mongo.setWriteConcern(writeConcern);
return mongo;
}
/**
* 初始化mongo
* @return
* @throws Exception
*/
private MongoClient initMongo() throws Exception {
//根据条件创建mongo实例
MongoClient mongo = null;
List serverList = getServerList();
mongo = new MongoClient(serverList.get(0));
return mongo;
}
/**
* 获取mongo地址
* @return
*/
private List getServerList() throws Exception {
List serverList = new ArrayList<>();
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) {
e.printStackTrace();
throw new Exception(
"Error while converting serverString to ServerAddressList", e
);
}
}
}
原博文中采用的泛型是mongo,但是现在的api基本不支持这么做了,所以我统一换成了MongoClient。
MorphiaFactory:
package cn.com.morphia;
import org.mongodb.morphia.Morphia;
import org.springframework.beans.factory.config.AbstractFactoryBean;
/**
* Created by Administrator on 2016/1/17.
*/
public class MorphiaFactoryBean extends AbstractFactoryBean {
/**
* 要扫描的包
* @return
*/
private String[] mapPackages;
/**
* 要映射的类
*/
private String[] mapClasses;
/**
* 扫描包时,是否忽略不映射的类
* 这里按照Morphia的原始定义,默认设为false
*/
private boolean ignoreInvalidClasses;
public String[] getMapPackages() {
return mapPackages;
}
public void setMapPackages(String[] mapPackages) {
this.mapPackages = mapPackages;
}
public String[] getMapClasses() {
return mapClasses;
}
public void setMapClasses(String[] mapClasses) {
this.mapClasses = mapClasses;
}
public boolean isIgnoreInvalidClasses() {
return ignoreInvalidClasses;
}
public void setIgnoreInvalidClasses(boolean ignoreInvalidClasses) {
this.ignoreInvalidClasses = ignoreInvalidClasses;
}
@Override
public Class> getObjectType() {
return Morphia.class;
}
@Override
protected Morphia createInstance() throws Exception {
Morphia morphia = new Morphia();
if (mapPackages != null) {
for (String packageName: mapPackages) {
morphia.mapPackage(packageName, ignoreInvalidClasses);
}
}
if (mapClasses != null) {
for (String entityClass: mapClasses) {
morphia.map(Class.forName(entityClass));
}
}
return morphia;
}
}
DatastoreFactoryBean:
package cn.com.morphia;
import com.mongodb.Mongo;
import com.mongodb.MongoClient;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import org.springframework.beans.factory.config.AbstractFactoryBean;
/**
* Created by Administrator on 2016/1/17.
*/
public class DatastoreFactoryBean extends AbstractFactoryBean {
/**
* morphia实例,最好是单例
*/
private Morphia morphia;
/**
* mongo实例,最好是单例
*/
private MongoClient mongo;
/**
* 数据库名
*/
private String dbName;
/**
* 用户名,可为空
*/
private String username;
/**
* 密码,可为空
*/
private String password;
public Morphia getMorphia() {
return morphia;
}
public void setMorphia(Morphia morphia) {
this.morphia = morphia;
}
public MongoClient getMongo() {
return mongo;
}
public void setMongo(MongoClient mongo) {
this.mongo = mongo;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isToEnsureIndexes() {
return toEnsureIndexes;
}
public void setToEnsureIndexes(boolean toEnsureIndexes) {
this.toEnsureIndexes = toEnsureIndexes;
}
public boolean isToEnsureCaps() {
return isToEnsureCaps;
}
public void setIsToEnsureCaps(boolean isToEnsureCaps) {
this.isToEnsureCaps = isToEnsureCaps;
}
/**
* 是否确认索引存在,默认false
*/
private boolean toEnsureIndexes = false;
/**
* 是否确认caps存在,默认为false
*/
private boolean isToEnsureCaps = false;
@Override
public Class> getObjectType() {
return Datastore.class;
}
@Override
protected Datastore createInstance() throws Exception {
//这里的username和password可以为null,morphia对象会去处理
Datastore ds = morphia.createDatastore(mongo, dbName);
if (toEnsureIndexes) {
ds.ensureIndexes();
}
if (isToEnsureCaps) {
ds.ensureCaps();
}
return ds;
}
}
具体代码大概就是如上,但是还有spring中配置文件的配置还没有编写,具体如下:
localhost:27017
cn.com.domain
这里我没有再写另外一个mongodb.properties配置文件,直接将相应的参数写到了spring的配置文件中,因为这里只需要这几个参数,可以说不需要
另外再写一个配置文件配置相应的参数。
同时在datastore这个bean的编写中,我直接让这个bean扫描domain下面的所有pojo类,这样便不需要再进行相应的一个个的将相应的pojo类添加进来。
同时在mongooptions的配置中,我去掉了几个参数,在新版本中,不需要这几个参数。
现在进行测试:
package morphia;
import cn.com.domain.User;
import org.junit.Before;
import org.junit.Test;
import org.mongodb.morphia.Datastore;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Created by Administrator on 2016/1/19.
*/
public class TestMorphia {
public ApplicationContext context;
@Before
public void init(){
context = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
}
@Test
public void test() {
Datastore datastore = (Datastore) context.getBean("datastore");
User u = new User();
u.setUsername("xx");
u.setPassword("xx");
datastore.save(u);
System.out.println(datastore);
}
}
获得datastore后,进行insert操作。
执行成功后,进mongo中查询相应的表:
如此,spring与Morphia的整合便是成功的。