引言
在开发中经常使用到MongoDB,每个项目使用各不相同,既繁琐又好不管理。这里封装了一套MongoDB类似于Mybatis的ORM增强版工具,和Spring无缝结合,只需要简单的配置就可以实现强大的功能。同时扩展了MongoDB的Datastore功能,加了一些自定义方法。其原理离不开之前所说的FactoryBean。
源码放在了我的GitHub上:https://github.com/mx-go/mongo-spring-support
源码中有详细使用注释,其原理就是实现FactoryBean生成代理对象并对原本的Datastore进行增强。
在这里记录下使用方法。
MongoDB数据库及集合
以下测试在MongoDB的TEST库中,其中有两个集合student、student_1。student_1可以用来测试同库中,根据后缀来切换集合,相当与分表。
引入Maven坐标
1 2 3 4 5
| <dependency> <groupId>com.github.mx-go</groupId> <artifactId>mongo-spring-support</artifactId> <version>1.0.0</version> </dependency>
|
配置管理
在Spring中配置MongoDB的server地址、dbName等信息,可以配置更多参数,见MongoConfiguration类中属性。jar包中已包含mongo-java-driver和morphia。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <context:component-scan base-package="com.rainbowhorse.demo"/>
<bean id="datastoreExt" class="com.github.mongo.support.mongo.MongoDataStoreFactoryBean"> <property name="configuration" ref="configuration"/> </bean> <bean id="configuration" class="com.github.mongo.support.mongo.MongoConfiguration"> <property name="servers" value="mongodb://root:root@localhost:27017/TEST"/> <property name="dbName" value="TEST"/> <property name="mapPackage" value="com.rainbowhorse.demo.mongo"/> </bean>
|
简单使用范例
简单模式
1 2 3 4 5 6 7 8 9
| @Service class UserService { @Autowired DatastoreExt datastoreExt;
public void save(User user) { datastore.save(user); } }
|
单实例多库
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Service class UserService { @Autowired DatastoreExt datastoreExt;
public void save(User user) { datastore.use("user_db").save(user); } }
@Service class BlogService { @Autowired DatastoreExt datastoreExt;
public void save(Blog blog) { datastore.use("blog_db").save(blog); } }
|
表名添加前缀或者后缀
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Service class UserService { @Autowired DatastoreExt datastoreExt;
public void save(User user) { datastore.getDatastoreByPrefix("db01", "2017").save(user); } }
@Service class BlogService { @Autowired DatastoreExt datastoreExt;
public void save(Blog blog) { datastore.getDatastoreBySuffix("db02", "2017").save(blog); } }
|
集合实体类StudentDO
MongoDB是文档型数据库,借助morphia可以把集合映射到到Java中的Bean。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| import lombok.Data; import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Id; import java.io.Serializable;
@Data @Entity(value = "student", noClassnameStored = true) public class StudentDO implements Serializable {
private static final long serialVersionUID = 2997596487756179430L;
@Id private String id; private Integer age; private String name; private Integer score; private String sex; }
|
接口及实现类
接口StudentDAO
接口继承mongo-support中的**BaseDao**,可以实现更多方法的调用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public interface StudentDAO extends BaseDao<StudentDO> {
List<StudentDO> getByScore(Integer score);
int updateAge(String id, Integer age);
int incrScoreByName(StudentDO tenantQuotaDO);
List<StudentDO> getScoreAndPage(StudentDO studentDO, Pager<StudentDO> pager); int getStudentCounts(StudentDO tenantQuotaDO); }
|
接口实现类StudentDAOImpl
继承**BaseDaoImpl**,其中实现基础方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| @Repository public class StudentDAOImpl extends BaseDaoImpl<StudentDO> implements StudentDAO {
@Autowired public StudentDAOImpl(DatastoreExt datastoreExt) { super(datastoreExt, StudentDO.class); }
@Override public List<StudentDO> getByScore(Integer score) { Query<StudentDO> query = createQuery(); query.criteria("score").equal(score); return query.asList(); }
@Override public int updateAge(String id, Integer age) {
Query<StudentDO> query = createQuery(); query.field("_id").equal(new ObjectId(id));
final UpdateOperations<StudentDO> update = createUpdateOperations(); update.set("age", age);
return getDatastore().update(query, update).getUpdatedCount(); }
@Override public List<StudentDO> getScoreAndPage(StudentDO studentDO, Pager<StudentDO> pager) { return queryList(studentDO, pager.offset(), pager.getPageSize()); }
@Override public int getStudentCounts(StudentDO studentDO) { return (int) queryCount(studentDO); }
@Override public int incrScoreByName(StudentDO studentDO) { Query<StudentDO> query = createQuery(studentDO); UpdateOperations<StudentDO> updateOperation = createUpdateOperations().inc("score", 1); return getDatastore().update(query, updateOperation).getUpdatedCount(); } }
|
单元测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| @Autowired private StudentDAO studentDAO;
@Test public void test() {
List<StudentDO> name1 = studentDAO.getByScore(88); System.out.println(name1.size());
StudentDO studentDO = new StudentDO(); studentDO.setName("max10"); System.out.println(studentDAO.incrScoreByName(studentDO));
StudentDO studentDO1 = new StudentDO(); studentDO1.setScore(88); Pager<StudentDO> pager = new Pager<>(); pager.setPageSize(2); pager.setCurrentPage(2); List<StudentDO> scoreAndPage = studentDAO.getScoreAndPage(studentDO1, pager); System.out.println(scoreAndPage);
System.out.println(studentDAO.getStudentCounts(new StudentDO()));
int age = studentDAO.updateAge("5ca6b118a03b9e0e7f5bb33c", 20); System.out.println(age); }
@Test public void TestDatastore() { DatastoreExt datastore = datastoreExt.getDatastoreBySuffix("TEST", "1");
studentDAO = new StudentDAOImpl(datastore);
List<StudentDO> name1 = studentDAO.getByScore(66); System.out.println(name1); }
|