对mongodb不是很了解的可以去看看我的上一篇博客 mongodb入门
mongodb官方对很多编程语言都提供了ORM框架支持,这里按下不表。本篇以spring data for mongo来简单介绍一下mongodb在java中的使用。
Spring Data提供了repository 抽象方式,可以极大的减少数据访问层千篇一律的类似的重复的代码。 基本DAO都会实现,find,findAll, findById, save, delete,update等方法,而且代码逻辑基本一致。Spring Data提供了简化方法,通过接口定义 Spring Data通过Proxy自动提供具体的实现。
1、pom.xml文件中 引入spring-data-mongodb 的jar包
<!-- 配置mongodb --> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>1.9.0.RELEASE</version> </dependency>
2、在spring的ApplicationContext.xml配置mongodb
<?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:context="http://www.springframework.org/schema/context" xmlns:mongo="http://www.springframework.org/schema/data/mongo" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 标注扫描的类 --> <!-- 开启注解 --> <context:annotation-config /> <context:component-scan base-package="com.huatech" /> <!-- 配置数据库的地址和端口 --> <mongo:mongo host="127.0.0.1" port="27017" > <!-- 设定连接属性 --> <mongo:options connections-per-host="8" threads-allowed-to-block-for-connection-multiplier="4" connect-timeout="1000" max-wait-time="1500" auto-connect-retry="true" socket-keep-alive="true" socket-timeout="1500" slave-ok="true" write-number="1" write-timeout="0" write-fsync="true"/> </mongo:mongo> <!-- mongo的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建 --> <!-- 如果没有创建数据库,就会默认创建数据库 username="root" password="root" --> <mongo:db-factory id="mongoDbFactory" host="127.0.0.1" port="27017" dbname="test" mongo-ref="mongo"/> <!-- mongodb的主要操作对象,所有对mongodb的增删改查的操作都是通过它完成 设定我们的 mongoDbFactory 对象 --> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" /> </bean> </beans>
3、建立公共的MongoDao接口
package com.huatech.dao;
import java.util.List;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import com.huatech.common.Page;
import com.huatech.entity.MongoEntity;
/**
* 建立公共的MongoDao接口,所有的Dao都需要继承这个类
* @author lh@erongdu.com
* 2017年4月21日
*
* @param <T>
*/
public interface MongoDao<T extends MongoEntity<T>> {
/**
* 通过条件查询实体(集合)
*
* @param query
*/
List<T> list(Query query) ;
/**
* 获取所有的数据
* @return
*/
List<T> list() ;
/**
* 通过一定的条件查询一个实体
*
* @param query
* @return
*/
T findOne(Query query) ;
/**
* 通过条件查询更新数据
*
* @param query
* @param update
* @return
*/
void update(Query query, Update update) ;
/**
* 通过给定的对象进行更新(只更新非空的属性)
* @param entry
*/
void update(T entry);
/**
* 保存一个对象到mongodb
* 使用的是mongotemplate的insert方法
*
* 添加的时候,会制动增长id
* id 必须是 String id 字段
*
* @param entity
* @return
*/
void insert(T entity) ;
/**
* 批量插入
* @param list
*/
void insertBatch(List<T> list);
/**
* 通过ID获取记录
*
* @param id
* @return
*/
T get(String uuid) ;
/**
* 通过ID获取记录,并且指定了集合名(表的意思)
*
* @param id
* @param collectionName
* 集合名
* @return
*/
T findById(String uuid, String collectionName) ;
/**
* 分页查询
* @param page
* @param query
* @return
*/
Page<T> findPage(Page<T> page, Query query);
/**
* 求数据总和 ,根据给定的 Query查询
* @param query
* @return
*/
long count(Query query);
/**
* 获取所有数据条数
* @return
*/
long count();
/**
* 通过id删除数据
* @param uuid
*/
void delete(String uuid);
/**
* 一次删除多条数据
* @param ids
*/
void deletes(String [] ids);
/**
* 通过传递过来的 对象来删除数据
* @param entry
*/
void delete(T entry);
}
MongoDao实现类
package com.huatech.dao.impl;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.Resource;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import com.huatech.common.Page;
import com.huatech.common.util.ReflectionUtils;
import com.huatech.common.util.StringUtils;
import com.huatech.common.util.UuidUtil;
import com.huatech.dao.MongoDao;
import com.huatech.entity.MongoEntity;
/**
* 这个MongoDaoImpl实现了MongoDb大部分有用的方法
* @author lh@erongdu.com
* 2017年4月21日
*
* @param <T>
*/
public class MongoDaoImpl<T extends MongoEntity<T>> implements MongoDao<T> {
private Class<T> clazz = ReflectionUtils.getClassGenricType(super.getClass());
/**
* spring mongodb 集成操作类
*/
private MongoTemplate mongoTemplate;
@Resource(name = "mongoTemplate")
public void setMongoTemplate(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
// 提供mongoTempldate获取更多的操作
public MongoTemplate getMongoTemplate() {
return mongoTemplate;
}
public List<T> list(Query query) {
return this.mongoTemplate.find(query, clazz);
}
public T findOne(Query query) {
return this.mongoTemplate.findOne(query, clazz);
}
public void update(Query query, Update update) {
mongoTemplate.findAndModify(query, update, clazz);
}
/**
* 添加实体
*/
public void insert(T entity) {
entity.setUuid(UuidUtil.genUuid());
// 获取对象,然后加上id
mongoTemplate.insert(entity);
}
/**
* 批量添加
*/
@Override
public void insertBatch(List<T> list) {
mongoTemplate.insertAll(list);
}
/**
* 通过id来加载数据对象
*/
public T get(String id) {
return mongoTemplate.findById(id, clazz);
}
/**
* 通过id来查找我们的数据对象
*/
public T findById(String id, String collectionName) {
return mongoTemplate.findById(id, clazz, collectionName);
}
/**
* 这个是通过Query查询
*/
public long count(Query query) {
return mongoTemplate.count(query, clazz);
}
/**
* 获取本集合中的条数
*/
public long count() {
return count(new Query(Criteria.where("").is("")));
}
/**
* 删除记录
*/
public void delete(String id) {
mongoTemplate.remove(new Query(Criteria.where("_id").is(id)),
clazz);
}
/**
* 直接删除传递过来的实体对象
*/
public void delete(T entry) {
mongoTemplate.remove(entry);
}
/**
* 更新我们的实体类
*/
public void update(T entry) {
try {
// 获取所有的字段,然后设定到update中
// 将所有获取的数据 放下Update中
Update update = new Update();
List<String> fieldNames = getClassFieldName(clazz);
for (String fieldName : fieldNames) {
if (StringUtils.isNotBlank(fieldName) && !"uuid".equals(fieldName) && !"serialVersionUID".equals(fieldName)) {
Object fieldValue = BeanUtils.getProperty(entry, fieldName);
if(!StringUtils.isBlank(fieldValue)){
update.set(fieldName, fieldValue);
}
}
}
// Iterator<String> it = fields.keySet().iterator();
// while (it.hasNext()) {
// String fieldName = it.next();
// if (StringUtils.isNotBlank(fieldName) && !"uuid".equals(fieldName) && !"serialVersionUID".equals(fieldName)) {
// Object fieldValue = BeanUtils.getProperty(entry, fieldName);
// if(!StringUtils.isBlank(fieldValue)){
// update.set(fieldName, fields.get(fieldName));
// }
// }
//
// }
// @SuppressWarnings("unchecked")
// Map<String, Object> fields = JsonMapper.fromJsonString(JsonMapper.toJsonString(entry), Map.class);
// Iterator<String> it = fields.keySet().iterator();
// while (it.hasNext()) {
// String fieldName = it.next();
// if (StringUtils.isNotBlank(fieldName) && !"uuid".equals(fieldName)) {
// update.set(fieldName, fields.get(fieldName));
// }
// }
// 然后更新我们的对象
this.mongoTemplate.updateFirst(
new Query(Criteria.where("_id").is(entry.getUuid())), update,
clazz);
} catch (Exception e) {
throw new RuntimeException(e.getMessage());
}
}
private static List<String> getClassFieldName(Class<?> clazz) {
Field[] declaredFields = clazz.getDeclaredFields();
List<String> fields = new ArrayList<>();
List<String> superFields = new ArrayList<>();
for (Field field : declaredFields) {
fields.add(field.getName());
}
if (clazz.getSuperclass() != null && clazz.getSuperclass().getClass().equals(MongoEntity.class)) {
superFields = getClassFieldName(clazz.getSuperclass());
}
fields.addAll(superFields);
return fields;
}
/**
* 删除多条数据
*/
public void deletes(String[] ids) {
for (String id : ids) {
delete(id);
}
}
/**
* 获取集合中所有的数据
*/
public List<T> list() {
return this.mongoTemplate.findAll(clazz);
}
public Page<T> findPage(Page<T> page, Query query) {
// 获取页面的大小和 页面
if(page == null) page = new Page<>();
Integer pageSize = page.getPageSize();
Integer pageNow = page.getPage();
String order = page.getOrder();
String sort =page.getSort();
//获取条数,由于不同的条件,所产生的条数是不一样的
int count = Integer.parseInt(this.count(query) + "");
page.setCount(count);
Sort mySort = null;
if(order == null || "".equals(order.trim())){
order = "id";
}
int offset = (pageNow - 1) * pageSize;
// 页面大小是多少
query.limit(pageSize);
// 从多少条开始
query.skip(offset);
//通过Sort这个 类可以完成排序的问题
if(sort != null && sort.equalsIgnoreCase("desc")){
mySort = new Sort(Direction.DESC,order);
}else{
mySort = new Sort(Direction.ASC,order);
}
//设定排序
query.with(mySort);
page.setRows(this.mongoTemplate.find(query, clazz));
return page;
}
}
4、User实现
1> MongoEntity
package com.huatech.entity;
import java.io.Serializable;
import org.springframework.data.annotation.Id;
/**
* Entity 基类
* @author lh
* @version 3.0
* @date 2016年5月9日
*/
public abstract class MongoEntity<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键:UUID
*/
@Id
protected String uuid;
public String getUuid() {
return uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
}
2> User
package com.huatech.entity;
import java.util.Date;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class User extends MongoEntity<User> {
/**
*
*/
private static final long serialVersionUID = -3042174626746305781L;
private String userName;
private Date birthday;
private int sex;
public User() {
}
public User(String userName, Date birthday, int sex) {
super();
this.userName = userName;
this.birthday = birthday;
this.sex = sex;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User [uuid=" + uuid +", userName=" + userName + ", birthday=" + birthday + ", sex=" + sex + "]";
}
}
3> UserDao 接口继承MongoDao
package com.huatech.dao;
import com.huatech.entity.User;
public interface UserDao extends MongoDao<User> {
}
4> UserDao实现类
package com.huatech.dao.impl;
import org.springframework.stereotype.Repository;
import com.huatech.dao.UserDao;
import com.huatech.entity.User;
@Repository("userDao")
public class UserDaoImpl extends MongoDaoImpl<User> implements UserDao {
}
5、编写测试用例
package com.huatech.dao.impl;
import java.util.Date;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.huatech.dao.UserDao;
import com.huatech.entity.User;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:ApplicationContext.xml")
public class UserDaoTest {
@Autowired
private UserDao userDao;
@Test
public void testAddUser(){
Logger.getLogger(SpringJUnit4ClassRunner.class);
User user = new User("张三", new Date(), 0);
userDao.insert(user);
}
@Test
public void testGet(){
User user = userDao.get("9daaa5d958364acf9b6be3edf9660502");
System.out.println(user.toString());
}
@Test
public void testUpdate(){
User user = userDao.get("9daaa5d958364acf9b6be3edf9660502");
user.setBirthday(null);
user.setSex(1);
userDao.update(user);
}
}
附件为整个工程代码,有需要的可以下载。