mongodb与spring mvc结合


以前只听过非关系型数据库(nosql),最近公司的新项目要用到,才知道Mongodb。用的框架是spring mvc,这个比较熟没问题。但是mongodb可是第一次听说啊,没人教,只能自己边学边做。下面是自己的一点学习小心得,希望更多像我一样的入门新手看了能有点感受

一:mongodb的实体类建立:

例如:

@Document(collection="SYS_USER")  //指定表名,第一次自动创建
public class User {
 
 public User(){
  this.id = ObjectId.get();
 }
 
 @Id
 private ObjectId  id;
 
 private String firstName;
 private String lastName;
 
 private String username;
 private String password;
 
 @DBRef                         //引用式关系,数据库中存储的是role的id
 @CascadeSave             //级联保存
 private Role role;

 public ObjectId  getId() {
  return id;
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 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 Role getRole() {
  return role;
 }

 public void setRole(Role role) {
  this.role = role;
 }
 @Override
 public String toString() {
  return ToStringBuilder.reflectionToString(this);
 }
}

如果是内嵌式:就是@Embedded。若有些字段不需要存储进数据库表中,则使用@Tranisent


二:dao层

这个是网上copy的,没办法新手啊,只能引用下前辈的东西了。重要的是要懂其中的意思

public class MongoDbBaseDao<T> {

 /**
  * 日志对象
  */
 protected Logger log = LoggerFactory.getLogger(getClass());
 
 @Autowired
 MongoOperations mongoOperation;
 
 /**
  * 实体类类型(由构造方法自动赋值)
  */
 private Class<?> entityClass;
 
 /**
  * 构造方法,根据实例类自动获取实体类类型
  */
 public MongoDbBaseDao() {
  entityClass = Reflections.getClassGenricType(getClass());
 }
 
 /**
  * 保存一个对象
  * @param t
  */
 public void save(T t){
        log.info("[Mongo Dao ]save:" + t);
        this.mongoOperation.save(t);
    }
 
 /**
  * 根据Id从Collection中查询对象
  * @param id
  * @return
  */
 @SuppressWarnings("unchecked")
 public T queryById(String id) {
        Query query = new Query();
        Criteria criteria = Criteria.where("_id").is(id);
        query.addCriteria(criteria);
        log.info("[Mongo Dao ]queryById:" + query);
        return (T)this.mongoOperation.findOne(query, this.entityClass);
    }
 
 /**
  * 根据条件查询集合
  * @param query 查询条件
  * @return
  */
 @SuppressWarnings("unchecked")
 public List<T> queryList(Query query){
        log.info("[Mongo Dao ]queryList:" + query);
        return (List<T>) this.mongoOperation.find(query, this.entityClass);
    }
 
 
 /**
  * 通过条件查询单个实体
  * @param query 查询条件
  * @return
  */
 @SuppressWarnings("unchecked")
    public T queryOne(Query query){
        log.info("[Mongo Dao ]queryOne:" + query);
        return (T)this.mongoOperation.findOne(query, this.entityClass);
    }
 
 
 /**
  * 根据条件查询库中符合记录的总数,为分页查询服务
  * @param query
  * @return
  */
 public Long count(Query query){
        log.info("[Mongo Dao ]queryPageCount:" + query);
        return this.mongoOperation.count(query, this.entityClass);
    }

 /**
  * 分页
  * @param page
  * @param query
  * @return
  */
 @SuppressWarnings("unchecked")
 public Page<T> findPage(Page<T> page,Query query){
  // get count
  if (!page.isDisabled() && !page.isNotCount()){
   page.setCount(count(query));
   if (page.getCount() < 1) {
    return page;
   }
  }
  // set page
  if (!page.isDisabled()){
   query.skip(page.getFirstResult());
         query.limit(page.getMaxResults());
  }
  
  // order by
  if (StringUtils.isNotBlank(page.getOrderBy())){
   for (String order : StringUtils.split(page.getOrderBy(), ",")){
    String[] o = StringUtils.split(order, " ");
    if (o.length==1){
     query.with(new Sort(Sort.Direction.DESC, o[0]));
    }else if (o.length==2){
     if ("DESC".equals(o[1].toUpperCase())){
      query.with(new Sort(Sort.Direction.DESC, o[0]));
     }else{
      query.with(new Sort(Sort.Direction.ASC, o[0]));
     }
    }
   }
  }
  List<T> list = (List<T>) this.mongoOperation.find(query, this.entityClass);
  page.setList(list);
  return page;
 }
 
 /**
  * 根据Id删除用户
  * @param id
  */
 public void deleteById(String id) {
  Criteria criteria = Criteria.where("_id").in(id);
  if (null != criteria) {
   Query query = new Query(criteria);
   log.info("[Mongo Dao ]deleteById:" + query);
   if (null != query && this.queryOne(query) != null) {
    this.delete(query);
   }
  }
 }
 
 public void delete(T t) {
  log.info("[Mongo Dao ]delete:" + t);
  this.mongoOperation.remove(t);
 }
 
 public void delete(Query query) {
  log.info("[Mongo Dao ]delete query:" + query);
  this.mongoOperation.remove(query);
 }
 
 /**
  * 更新满足条件的第一个记录
  * @param query
  * @param update
  */
 public void updateFirst(Query query, Update update) {
  log.info("[Mongo Dao ]updateFirst:query(" + query + "),update(" + update + ")");
  this.mongoOperation.updateFirst(query, update, this.entityClass);
 }
 
 /**
  * 更新满足条件的所有记录
  * @param query
  * @param update
  */
 public void updateMulti(Query query, Update update){
        log.info("[Mongo Dao ]updateMulti:query(" + query + "),update(" + update + ")");
        this.mongoOperation.updateMulti(query, update, this.entityClass);
    }
 
 /**
  * 查找更新,如果没有找到符合的记录,则将更新的记录插入库中
  * @param query
  * @param update
  */
 public void updateInser(Query query, Update update){
        log.info("[Mongo Dao ]updateInser:query(" + query + "),update(" + update + ")");
        this.mongoOperation.upsert(query, update, this.entityClass);
    }
 
 /**
  * delete
  * @param <T>
  * @param entityids
  * @return
  */
 public int delete(String... entityids) {
  this.mongoOperation.remove(Query.query(Criteria.where("_id").in(Arrays.asList(entityids))), this.entityClass);
  return entityids.length;
 }
 
 public int update( String[] fields, Object[] fieldValues, String id) {
  WriteResult result = this.mongoOperation.updateFirst(new Query(where("_id").is(id)), setFieldValue(fields, fieldValues), this.entityClass);
  CommandResult commandResult = result.getLastError();
  if(commandResult.ok()){
   return 1;
  }
  throw new RuntimeException(commandResult.getErrorMessage());
 }
 
 public static Update setFieldValue( String[] fields, Object[] fieldValues){
  Update update = new Update();
  for (int i = 0; i < fieldValues.length; i++) {
   update.set(fields[i], fieldValues[i]);
  }
  return update;
 }
 
 
 /**
  * 更新
  * @param id
  * @param values
  */
    public void update(String id, Map<String, Object> values) {
        Query query = Query.query(Criteria.where("_id").is(id));
        Update update = new Update();
        MongoGenericDaoUtil.bindUpdateFieldValue(update, values);
        this.mongoOperation.updateFirst(query, update, entityClass);
    }

   
 /**
  * 根据ID查询
  * @param id
  * @param fields
  * @return
  */
 @SuppressWarnings("unchecked")
    public T get(String id, Set<String> fields) {
        Query query = Query.query(Criteria.where("_id").is(id));
        MongoGenericDaoUtil.bindFields(query, fields);
        return (T) this.mongoOperation.findOne(query, entityClass);
    }

}

三:service层:

写一个实现类userRepository实现上面的dao,service中引用实现类userRepository。

书写实现功能要用到的方法即可。

例如:

 /**
  * id查询
  * @return
  */
 public User  findById(String id){
  return userRepository.queryById(id);
 }

/**
  * 首页查询所有
  * @return
  */
 public List<User>  findAllList(){
  Query query = new Query();
  return userRepository.queryList(query);
 }

重点的是条件查询:

所有的查询条件都汇聚到query对象中:

1——如果是实体User中的基本属性:

query.addCriteria(Criteria.where("name").regex(user,getName(),"i"));

2——如果是实体中的引用对象(role或者role的list集合):

query.addCriteria(Criteria.where("role.$id").regex(uid,"i"));//DBRef查询,只能通过引用对象的ID查询,其它字段则无效。注意$符号

3——如果是实体中的内嵌对象(适用于单个实体和list集合):

query.addCriteria(Criteria.where("role.name").regex(role.getName(),"i"));//直接对象变量名.对象属性即可


分页查询

例如:

 public Page<Module> findPage(Page<Module> page,Module module){
  Query  query = new Query();
   
   query.addCriteria(Criteria.where("delFlag").is("0"));
   //时间查询
   if(module.getOdate1()!=null&&module.getOdate2()!=null){
    query.addCriteria(Criteria.where("onlinedate").gte(module.getOdate1()).lte(module.getOdate2()));//日期区间
   }
   if(module.getMdate1()!=null&&module.getMdate2()!=null){
    query.addCriteria(Criteria.where("maintenancedate").gte(module.getMdate1()).lte(module.getMdate2()));//与该交维日期
   }
  page.setOrderBy("modulecode");//排序
  return moduleRepository.findPage(page, query);
 }

其中的Page对象

package com.aspire.ops.common.persistence;

import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;

import com.aspire.ops.common.config.Global;
import com.aspire.ops.common.utils.CookieUtils;
import com.fasterxml.jackson.annotation.JsonIgnore;

/**
 * 分页类
 * @author ThinkGem
 * @version 2013-7-2
 * @param <T>
 */
public class Page<T> {
 
 private int pageNo = 1; // 当前页码
 private int pageSize = Integer.valueOf(Global.getConfig("page.pageSize")); // 页面大小,设置为“-1”表示不进行分页(分页无效)
 
 private long count;// 总记录数,设置为“-1”表示不查询总数
 
 private int first;// 首页索引
 private int last;// 尾页索引
 private int prev;// 上一页索引
 private int next;// 下一页索引
 
 private boolean firstPage;//是否是第一页
 private boolean lastPage;//是否是最后一页

 private int length = 8;// 显示页面长度
 private int slider = 1;// 前后显示页面长度
 
 private List<T> list = new ArrayList<T>();
 
 private String orderBy = ""; // 标准查询有效, 实例: updatedate desc, name asc
 
 private String funcName = "page"; // 设置点击页码调用的js函数名称,默认为page,在一页有多个分页对象时使用。
 
 private String message = ""; // 设置提示消息,显示在“共n条”之后

 public Page() {
  this.pageSize = -1;
 }
 
 /**
  * 构造方法
  * @param request 传递 repage 参数,来记住页码
  * @param response 用于设置 Cookie,记住页码
  */
 public Page(HttpServletRequest request, HttpServletResponse response){
  this(request, response, -2);
 }

 /**
  * 构造方法
  * @param request 传递 repage 参数,来记住页码
  * @param response 用于设置 Cookie,记住页码
  * @param defaultPageSize 默认分页大小,如果传递 -1 则为不分页,返回所有数据
  */
 public Page(HttpServletRequest request, HttpServletResponse response, int defaultPageSize){
  // 设置页码参数(传递repage参数,来记住页码)
  String no = request.getParameter("pageNo");
  if (StringUtils.isNumeric(no)){
   CookieUtils.setCookie(response, "pageNo", no);
   this.setPageNo(Integer.parseInt(no));
  }else if (request.getParameter("repage")!=null){
   no = CookieUtils.getCookie(request, "pageNo");
   if (StringUtils.isNumeric(no)){
    this.setPageNo(Integer.parseInt(no));
   }
  }
  // 设置页面大小参数(传递repage参数,来记住页码大小)
  String size = request.getParameter("pageSize");
  if (StringUtils.isNumeric(size)){
   CookieUtils.setCookie(response, "pageSize", size);
   this.setPageSize(Integer.parseInt(size));
  }else if (request.getParameter("repage")!=null){
   no = CookieUtils.getCookie(request, "pageSize");
   if (StringUtils.isNumeric(size)){
    this.setPageSize(Integer.parseInt(size));
   }
  }else if (defaultPageSize != -2){
   this.pageSize = defaultPageSize;
  }
  // 设置排序参数
  String orderBy = request.getParameter("orderBy");
  if (StringUtils.isNotBlank(orderBy)){
   this.setOrderBy(orderBy);
  }
 }
 
 /**
  * 构造方法
  * @param pageNo 当前页码
  * @param pageSize 分页大小
  */
 public Page(int pageNo, int pageSize) {
  this(pageNo, pageSize, 0);
 }
 
 /**
  * 构造方法
  * @param pageNo 当前页码
  * @param pageSize 分页大小
  * @param count 数据条数
  */
 public Page(int pageNo, int pageSize, long count) {
  this(pageNo, pageSize, count, new ArrayList<T>());
 }
 
 /**
  * 构造方法
  * @param pageNo 当前页码
  * @param pageSize 分页大小
  * @param count 数据条数
  * @param list 本页数据对象列表
  */
 public Page(int pageNo, int pageSize, long count, List<T> list) {
  this.setCount(count);
  this.setPageNo(pageNo);
  this.pageSize = pageSize;
  this.setList(list);
 }
 
 /**
  * 初始化参数
  */
 public void initialize(){
    
  //1
  this.first = 1;
  
  this.last = (int)(count / (this.pageSize < 1 ? 20 : this.pageSize) + first - 1);
  
  if (this.count % this.pageSize != 0 || this.last == 0) {
   this.last++;
  }

  if (this.last < this.first) {
   this.last = this.first;
  }
  
  if (this.pageNo <= 1) {
   this.pageNo = this.first;
   this.firstPage=true;
  }

  if (this.pageNo >= this.last) {
   this.pageNo = this.last;
   this.lastPage=true;
  }

  if (this.pageNo < this.last - 1) {
   this.next = this.pageNo + 1;
  } else {
   this.next = this.last;
  }

  if (this.pageNo > 1) {
   this.prev = this.pageNo - 1;
  } else {
   this.prev = this.first;
  }
  
  //2
  if (this.pageNo < this.first) {// 如果当前页小于首页
   this.pageNo = this.first;
  }

  if (this.pageNo > this.last) {// 如果当前页大于尾页
   this.pageNo = this.last;
  }
  
 }
 
 /**
  * 默认输出当前分页标签
  * <div class="page">${page}</div>
  */
 @Override
 public String toString() {

  initialize();
  
  StringBuilder sb = new StringBuilder();
  
  if (pageNo == first) {// 如果是首页
   sb.append("<li class=\"disabled\"><a href=\"javascript:\">&#171; 上一页</a></li>\n");
  } else {
   sb.append("<li><a href=\"javascript:\" οnclick=\""+funcName+"("+prev+","+pageSize+");\">&#171; 上一页</a></li>\n");
  }

  int begin = pageNo - (length / 2);

  if (begin < first) {
   begin = first;
  }

  int end = begin + length - 1;

  if (end >= last) {
   end = last;
   begin = end - length + 1;
   if (begin < first) {
    begin = first;
   }
  }

  if (begin > first) {
   int i = 0;
   for (i = first; i < first + slider && i < begin; i++) {
    sb.append("<li><a href=\"javascript:\" οnclick=\""+funcName+"("+i+","+pageSize+");\">"
      + (i + 1 - first) + "</a></li>\n");
   }
   if (i < begin) {
    sb.append("<li class=\"disabled\"><a href=\"javascript:\">...</a></li>\n");
   }
  }

  for (int i = begin; i <= end; i++) {
   if (i == pageNo) {
    sb.append("<li class=\"active\"><a href=\"javascript:\">" + (i + 1 - first)
      + "</a></li>\n");
   } else {
    sb.append("<li><a href=\"javascript:\" οnclick=\""+funcName+"("+i+","+pageSize+");\">"
      + (i + 1 - first) + "</a></li>\n");
   }
  }

  if (last - end > slider) {
   sb.append("<li class=\"disabled\"><a href=\"javascript:\">...</a></li>\n");
   end = last - slider;
  }

  for (int i = end + 1; i <= last; i++) {
   sb.append("<li><a href=\"javascript:\" οnclick=\""+funcName+"("+i+","+pageSize+");\">"
     + (i + 1 - first) + "</a></li>\n");
  }

  if (pageNo == last) {
   sb.append("<li class=\"disabled\"><a href=\"javascript:\">下一页 &#187;</a></li>\n");
  } else {
   sb.append("<li><a href=\"javascript:\" οnclick=\""+funcName+"("+next+","+pageSize+");\">"
     + "下一页 &#187;</a></li>\n");
  }

  sb.append("<li class=\"disabled controls\"><a href=\"javascript:\">当前 ");
  sb.append("<input type=\"text\" value=\""+pageNo+"\" οnkeypress=\"var e=window.event||this;var c=e.keyCode||e.which;if(c==13)");
  sb.append(funcName+"(this.value,"+pageSize+");\" οnclick=\"this.select();\"/> / ");
  sb.append("<input type=\"text\" value=\""+pageSize+"\" οnkeypress=\"var e=window.event||this;var c=e.keyCode||e.which;if(c==13)");
  sb.append(funcName+"("+pageNo+",this.value);\" οnclick=\"this.select();\"/> 条,");
  sb.append("共 " + count + " 条"+(message!=null?message:"")+"</a><li>\n");

  sb.insert(0,"<ul>\n").append("</ul>\n");
  
  sb.append("<div style=\"clear:both;\"></div>");

//  sb.insert(0,"<div class=\"page\">\n").append("</div>\n");
  
  return sb.toString();
 }
 
 /**
  * 获取分页HTML代码
  * @return
  */
 public String getHtml(){
  return toString();
 }
 
// public static void main(String[] args) {
//  Page<String> p = new Page<String>(3, 3);
//  System.out.println(p);
//  System.out.println("首页:"+p.getFirst());
//  System.out.println("尾页:"+p.getLast());
//  System.out.println("上页:"+p.getPrev());
//  System.out.println("下页:"+p.getNext());
// }

 /**
  * 获取设置总数
  * @return
  */
 public long getCount() {
  return count;
 }

 /**
  * 设置数据总数
  * @param count
  */
 public void setCount(long count) {
  this.count = count;
  if (pageSize >= count){
   pageNo = 1;
  }
 }
 
 /**
  * 获取当前页码
  * @return
  */
 public int getPageNo() {
  return pageNo;
 }
 
 /**
  * 设置当前页码
  * @param pageNo
  */
 public void setPageNo(int pageNo) {
  this.pageNo = pageNo;
 }
 
 /**
  * 获取页面大小
  * @return
  */
 public int getPageSize() {
  return pageSize;
 }

 /**
  * 设置页面大小(最大500)
  * @param pageSize
  */
 public void setPageSize(int pageSize) {
  this.pageSize = pageSize <= 0 ? 10 : pageSize;// > 500 ? 500 : pageSize;
 }

 /**
  * 首页索引
  * @return
  */
 @JsonIgnore
 public int getFirst() {
  return first;
 }

 /**
  * 尾页索引
  * @return
  */
 @JsonIgnore
 public int getLast() {
  return last;
 }
 
 /**
  * 获取页面总数
  * @return getLast();
  */
 @JsonIgnore
 public int getTotalPage() {
  return getLast();
 }

 /**
  * 是否为第一页
  * @return
  */
 @JsonIgnore
 public boolean isFirstPage() {
  return firstPage;
 }

 /**
  * 是否为最后一页
  * @return
  */
 @JsonIgnore
 public boolean isLastPage() {
  return lastPage;
 }
 
 /**
  * 上一页索引值
  * @return
  */
 @JsonIgnore
 public int getPrev() {
  if (isFirstPage()) {
   return pageNo;
  } else {
   return pageNo - 1;
  }
 }

 /**
  * 下一页索引值
  * @return
  */
 @JsonIgnore
 public int getNext() {
  if (isLastPage()) {
   return pageNo;
  } else {
   return pageNo + 1;
  }
 }
 
 /**
  * 获取本页数据对象列表
  * @return List<T>
  */
 public List<T> getList() {
  return list;
 }

 /**
  * 设置本页数据对象列表
  * @param list
  */
 public Page<T> setList(List<T> list) {
  this.list = list;
  return this;
 }

 /**
  * 获取查询排序字符串
  * @return
  */
 @JsonIgnore
 public String getOrderBy() {
  return orderBy;
 }

 /**
  * 设置查询排序,标准查询有效, 实例: updatedate desc, name asc
  */
 public void setOrderBy(String orderBy) {
  this.orderBy = orderBy;
 }

 /**
  * 获取点击页码调用的js函数名称
  * function ${page.funcName}(pageNo){location="${ctx}/list-${category.id}${urlSuffix}?pageNo="+i;}
  * @return
  */
 @JsonIgnore
 public String getFuncName() {
  return funcName;
 }

 /**
  * 设置点击页码调用的js函数名称,默认为page,在一页有多个分页对象时使用。
  * @param funcName 默认为page
  */
 public void setFuncName(String funcName) {
  this.funcName = funcName;
 }

 /**
  * 设置提示消息,显示在“共n条”之后
  * @param message
  */
 public void setMessage(String message) {
  this.message = message;
 }
 
 /**
  * 分页是否有效
  * @return this.pageSize==-1
  */
 @JsonIgnore
 public boolean isDisabled() {
  return this.pageSize==-1;
 }
 
 /**
  * 是否进行总数统计
  * @return this.count==-1
  */
 @JsonIgnore
 public boolean isNotCount() {
  return this.count==-1;
 }
 
 /**
  * 获取 Hibernate FirstResult
  */
 public int getFirstResult(){
  int firstResult = (getPageNo() - 1) * getPageSize();
  if (firstResult >= getCount()) {
   firstResult = 0;
  }
  return firstResult;
 }
 
 public int getLastResult(){
  int lastResult = getFirstResult()+getMaxResults();
  if(lastResult>getCount()) {
   lastResult =(int) getCount();
  }
  return lastResult;
 }
 /**
  * 获取 Hibernate MaxResults
  */
 public int getMaxResults(){
  return getPageSize();
 }
 
}

四:controller层:

例如:

@RequestMapping
 public String listModule(Module module,HttpServletRequest request,HttpServletResponse  response,Model model){
  Page<Module>  page = moduleService.findPage(new Page<Module>(request, response), module);
  model.addAttribute("page", page);
  model.addAttribute("modulequery", module);
  return "mongodb/module/moduleQueryList";
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值