和关系型数据库类似,在使用MongoDB的时候最主要还是CRUD,而Spring-data-mongodb封装了MongoTemplate类,可以方便的进行相应的操作。
首先,配置spring
<?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:mongo="http://www.springframework.org/schema/data/mongo" xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo-1.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- Default bean name is 'mongo' --> <mongo:mongo host="127.0.0.1" port="27017" /> <mongo:db-factory dbname="database" mongo-ref="mongo" /> <!-- 扫描注解Bean --> <context:component-scan base-package="com.study.mongodb.**.*"> <context:exclude-filter type="annotation" <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" /> </bean> </beans>
在关系型数据应用程序中,一般都会用到ORM框架,而Spring-data-mongodb本身就已经实现对象到数据的映射。而封装的Query和Update类用来做查询和更新已经非常方便了。但是我们还是需要把实体Bean转换成Query实例。本着将懒惰进行到底的原则,这点也最好不要。
对于查询,一般根据实体bean的某些属性进行查询,最主要的查询有等于,like和in类型。创建一个注解QueryField,代表要查询的字段
/** * <p> * 用于实体Bean的属性上的注解,注解有两个属性可以设置,type表示查询类似,默认为equals<br/> * attribute表示要查询的属性,默认为空串,在使用时如果为空串,则默认为实体Bean字段的名称 * </p> * * @author: <a href="mailto:chuanli@sohu-inc.com">chuanli</a> */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface QueryField { QueryType type() default QueryType.EQUALS; String attribute() default ""; }
默认使用相等。
QueryType是个枚举类型,表示查询类型
/** * <p> * 查询类型的媒介类<br/> * 目前有支持三种类型:<br/> * 1. equals:相等 * 2. like:mongodb的like查询 * 3. in:用于列表的in类型查询 * </p> * * @author: <a href="mailto:chuanli@sohu-inc.com">chuanli</a> */ public enum QueryType { EQUALS { @Override public Criteria buildCriteria(QueryField queryFieldAnnotation, Field field, Object value) { if (check(queryFieldAnnotation, field, value)) { String queryField = getQueryFieldName(queryFieldAnnotation, field); return Criteria.where(queryField).is(value.toString()); } return new Criteria(); } }, LIKE { @Override public Criteria buildCriteria(QueryField queryFieldAnnotation, Field field, Object value) { if (check(queryFieldAnnotation, field, value)) { String queryField = getQueryFieldName(queryFieldAnnotation, field); return Criteria.where(queryField).regex(value.toString()); } return new Criteria(); } }, IN { @Override public Criteria buildCriteria(QueryField queryFieldAnnotation, Field field, Object value) { if (check(queryFieldAnnotation, field, value)) { if (value instanceof List) { String queryField = getQueryFieldName(queryFieldAnnotation, field); // 此处必须转型为List,否则会在in外面多一层[] return Criteria.where(queryField).in((List<?>)value); } } return new Criteria(); } }; private static boolean check(QueryField queryField, Field field, Object value) { return !(queryField == null || field == null || value == null); } public abstract Criteria buildCriteria(QueryField queryFieldAnnotation, Field field, Object value); /** * 如果实体bean的字段上QueryField注解没有设置attribute属性时,默认为该字段的名称 * * @param queryFieldAnnotation * @param field * @return */ private static String getQueryFieldName(QueryField queryField, Field field) { String queryFieldValue = queryField.attribute(); if (!StringUtils.hasText(queryFieldValue)) { queryFieldValue = field.getName(); } return queryFieldValue; } }
这样当创建一个实体类时,可以为相应的字段添加注解即可,比如Article类:
public class Article { @QueryField private String id; @QueryField private String title; @QueryField(type = QueryType.LIKE, attribute = "content") private String content; @QueryField(type = QueryType.IN, attribute = "title") private List<String> queryTitles; }
这样一个实例可通过下面方法转换成一个Query实例
private Query buildBaseQuery(T t) { Query query = new Query(); Field[] fields = t.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); try { Object value = field.get(t); if (value != null) { QueryField queryField = field.getAnnotation(QueryField.class); if (queryField != null) { query.addCriteria(queryField.type().buildCriteria(queryField, field, value)); } } } catch (Exception e) { // should not happend } return query; }
增删改查的基本DAO如下:
public abstract class MongodbBaseDao<T>{ @Autowired @Qualifier("mongoTemplate") protected MongoTemplate mongoTemplate; //保存一个对象到mongodb public T save(T bean) { mongoTemplate.save(bean); return bean; } // 根据id删除对象 public void deleteById(T t) { mongoTemplate.remove(t); } // 根据对象的属性删除 public void deleteByCondition(T t) { Query query = buildBaseQuery(t); mongoTemplate.remove(query, getEntityClass()); } // 通过条件查询更新数据 public void update(Query query, Update update) { mongoTemplate.updateMulti(query, update, this.getEntityClass()); } // 根据id进行更新 public void updateById(String id, T t) { Query query = new Query(); query.addCriteria(Criteria.where("id").is(id)); Update update = buildBaseUpdate(t); update(query, update); } // 通过条件查询实体(集合) public List<T> find(Query query) { return mongoTemplate.find(query, this.getEntityClass()); } public List<T> findByCondition(T t) { Query query = buildBaseQuery(t); return mongoTemplate.find(query, getEntityClass()); } // 通过一定的条件查询一个实体 public T findOne(Query query) { return mongoTemplate.findOne(query, this.getEntityClass()); } // 通过ID获取记录 public T get(String id) { return mongoTemplate.findById(id, this.getEntityClass()); } // 通过ID获取记录,并且指定了集合名(表的意思) public T get(String id, String collectionName) { return mongoTemplate.findById(id, this.getEntityClass(), collectionName); } // 根据vo构建查询条件Query private Query buildBaseQuery(T t) { Query query = new Query(); Field[] fields = t.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); try { Object value = field.get(t); if (value != null) { QueryField queryField = field.getAnnotation(QueryField.class); if (queryField != null) { query.addCriteria(queryField.type().buildCriteria(queryField, field, value)); } } } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return query; } private Update buildBaseUpdate(T t) { Update update = new Update(); Field[] fields = t.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); try { Object value = field.get(t); if (value != null) { update.set(field.getName(), value); } } catch (Exception e) { e.printStackTrace(); } } return update; } // 获取需要操作的实体类class @SuppressWarnings("unchecked") protected Class<T> getEntityClass() { return ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]); } public MongoTemplate getMongoTemplate() { return mongoTemplate; } }
这样基本的CRUD就写好了,虽然一些复杂的查询和更新还得自己构造Query和Update,但是大部分情况足以应付了。
相关推荐
- **Repository抽象**:Spring-data-mongodb通过Repository接口提供了一套强大的CRUD操作,开发者无需编写繁琐的DAO代码。 - **Querydsl支持**:支持Querydsl,提供类型安全的查询方式,增强了查询的可读性和维护...
7. **Repository接口**: Spring Data MongoDB的Repository接口允许开发者定义特定于领域的查询方法,而无需编写实际的DAO层代码。例如,`findAll()`、`findById()`等。 8. **查询方法命名规则**: Spring Data ...
这个压缩包`spring-date-mongodb1.4.2.zip`包含了两个核心的JAR文件:`spring-data-mongodb-1.4.2.RELEASE.jar`和`spring-data-commons-1.7.2.RELEASE.jar`,它们是Spring Data MongoDB项目的关键组成部分。...
SpringBoot 是一个由 Pivotal 团队开发的框架,它简化了在 Spring 框架上构建应用程序的过程。这个项目旨在使初始搭建以及开发新 Spring 应用程序变得更加简单,通过内嵌的 Tomcat 容器,可以快速运行一个 Java 项目...
MongoDB与Spring Data的集成允许开发者使用熟悉的Spring编程模型,无需编写大量的DAO(数据访问对象)层代码,就能方便地操作MongoDB数据库。这个框架提供了诸如CRUD操作、聚合、索引管理等常见的数据库功能,同时...
压缩包中的“SpringData”可能就是包含了这些依赖的文件夹,里面可能有`.jar`文件或者`.pom.xml`文件,用于构建工具导入。 集成Spring Data到Spring应用中,还需要配置相关的Bean,如DataSource、...
Spring Data Document模块使得与MongoDB的交互变得更为简单,它提供了强大的Repository抽象,允许开发者通过简单的接口定义来执行CRUD操作,无需编写繁琐的DAO层代码。 1. **Repository抽象**: Spring Data ...
Spring Data Commons是Spring框架的一个重要组成部分,它为Spring Data项目提供了一套通用的基础设施,简化了与各种数据存储进行交互的过程。这个1.13.0.RELEASE版本是该模块的一个稳定版本,包含了对多种数据访问...
在本实例中,我们将探讨如何使用Spring MVC、Spring Data以及MongoDB来构建一个实际的应用程序。Spring MVC是Spring框架的一部分,用于构建Web应用程序,而Spring Data则是Spring项目下的一个模块,它简化了与各种...
综上所述,"spring-mongodb-jars"这个主题涵盖了大量的技术细节,包括Spring Data MongoDB的使用、对象映射、Repository接口、查询构造、事务管理、索引创建、聚合操作,以及数据库连接配置等。了解和掌握这些知识点...
通过使用Spring Data JPA,开发者可以很容易地创建CRUD(创建、读取、更新、删除)操作,而无需编写大量的DAO(Data Access Object)代码。它支持自动查询构造,包括基于方法名的简单查询和通过JPA Repository接口...
- `@Repository`:在 Dao 类上使用,表明这是一个数据访问对象,Spring Data JPA 会自动处理其中的方法,如 CRUD 操作。 - `@RepositoryDefinition`:用于自定义 Dao 层的通用方法,例如分页和动态查询。 - `@...
Spring Data MongoDB 是一个项目,它将 Spring 框架的核心概念应用于使用 MongoDB 文档样式数据存储的解决方案开发中。该项目提供了一个“模板”作为存储和查询文档的高级抽象层,其设计思想与 Spring Framework 中...
《Spring Data Commons 1.3.1:构建高效数据访问层的基石》 Spring Data Commons是Spring Data项目的核心模块,它的版本1.3.1.RELEASE是该项目在2014年发布的一个稳定版本,旨在提供一套通用的、可扩展的数据访问...
Spring Data MongoDB 提供了Repository接口,可以直接使用`MongoRepository`,自动生成CRUD操作。创建一个接口`UserRepository`,继承`MongoRepository, Long>`: ```java public interface UserRepository ...
Spring-Data MongoDB 提供了与 MongoDB 集成的接口,使得开发者可以方便地在 Spring 应用中使用 MongoDB。 3. **Bean Validation**: Bean Validation 是 Java EE 规范的一部分,用于校验 Java 对象的属性值。...
Spring-Data-MongoDB 我们的这个是关于Spring Data MongoDB 的学习和配置,其中我实现了分页和BaseDao的接口和方法,可以供大家学习和参考 ##BaseDao接口 package com.yellowcong.dao; import java.util.List; ...
使用Spring Data MongoDB,开发者可以轻松地实现如下功能: - **数据访问对象(DAO)抽象**:通过MongoRepository接口,可以快速实现数据访问逻辑,减少重复代码。 - **动态查询**:MongoTemplate的`query()`方法...
【标题】"Workshop-spring-boot-mongodb" 是一个基于Java技术栈的工作坊项目,它主要探讨了如何在Spring Boot框架下集成与使用MongoDB数据库。这个项目旨在帮助开发者掌握如何构建现代Web应用程序,利用Spring Boot...
8. **聚合框架**:Spring Data MongoDB提供了聚合操作的支持,允许开发者构建复杂的查询管道,以分析和转换数据。 9. **索引管理**:可以通过MongoTemplate或Repository接口创建和管理MongoDB的索引,以优化查询...