spring集成mongodb封装的简单的CRUD
来源:互联网 发布:网络信息都可信吗 编辑:程序博客网 时间:2024/06/06 01:17
1、什么是mongodb
MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。
MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。mongoDB
2、和spring集成
最近公司的项目有用到mongodb,主要用于存储日志记录,所以研究了下它和spring的集成,并且做了个简单的CRUD的封装,首先用到的包是:
spring-3.1.x以上的相关包(必须是3.1.x以上,否则集成之后运行会报错)
spring-data-mongodb-1.3.0.M1.jar
先看配置文件(spring-mongodb.xml)
<?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/context http://www.springframework.org/schema/context/spring-context-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/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <mongo:db-factory id="mongoDbFactory" host="${mongo.host}" port="${mongo.port}" dbname="${mongo.dbname}" username="${mongo.username}" password="${database.password}"/> <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate"> <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/> </bean> </beans>
其中:host为mongodb服务器地址,port为端口号,dbname为数据库名,username为mongodb用户名,password为mongodb密码,好了,全部配置就在这里。
接下来就是CRUD封装类
package cn.sunsharp.alibaba.core.mongo;import java.util.List;import org.springframework.data.mongodb.core.query.Query;import org.springframework.data.mongodb.core.query.Update;import cn.sunsharp.alibaba.core.Page;public interface BaseMongoDAO<T> {/** * 通过条件查询实体(集合) * * @param query */public List<T> find(Query query) ;/** * 通过一定的条件查询一个实体 * * @param query * @return */public T findOne(Query query) ;/** * 通过条件查询更新数据 * * @param query * @param update * @return */public void update(Query query, Update update) ;/** * 保存一个对象到mongodb * * @param entity * @return */public T save(T entity) ;/** * 通过ID获取记录 * * @param id * @return */public T findById(String id) ;/** * 通过ID获取记录,并且指定了集合名(表的意思) * * @param id * @param collectionName * 集合名 * @return */public T findById(String id, String collectionName) ;/** * 分页查询 * @param page * @param query * @return */public Page<T> findPage(Page<T> page,Query query);/** * 求数据总和 * @param query * @return */public long count(Query query);}
实现:
package cn.sunsharp.alibaba.core.mongo.impl;import java.util.List;import org.springframework.data.mongodb.core.MongoTemplate;import org.springframework.data.mongodb.core.query.Query;import org.springframework.data.mongodb.core.query.Update;import cn.sunsharp.alibaba.core.Page;import cn.sunsharp.alibaba.core.ReflectionUtils;import cn.sunsharp.alibaba.core.mongo.BaseMongoDAO;public abstract class BaseMongoDAOImpl<T> implements BaseMongoDAO<T>{private static final int DEFAULT_SKIP = 0;private static final int DEFAULT_LIMIT = 200;/** * spring mongodb 集成操作类 */protected MongoTemplate mongoTemplate;@Overridepublic List<T> find(Query query) {return mongoTemplate.find(query, this.getEntityClass());}@Overridepublic T findOne(Query query) {return mongoTemplate.findOne(query, this.getEntityClass());}@Overridepublic void update(Query query, Update update) {mongoTemplate.findAndModify(query, update, this.getEntityClass());}@Overridepublic T save(T entity) {mongoTemplate.insert(entity);return entity;}@Overridepublic T findById(String id) {return mongoTemplate.findById(id, this.getEntityClass());}@Overridepublic T findById(String id, String collectionName) {return mongoTemplate.findById(id, this.getEntityClass(), collectionName);}@Overridepublic Page<T> findPage(Page<T> page,Query query){long count = this.count(query);page.setTotal(count);int pageNumber = page.getPageNumber();int pageSize = page.getPageSize();query.skip((pageNumber - 1) * pageSize).limit(pageSize);List<T> rows = this.find(query);page.setRows(rows);return page;}@Overridepublic long count(Query query){return mongoTemplate.count(query, this.getEntityClass());}/** * 获取需要操作的实体类class * * @return */private Class<T> getEntityClass(){return ReflectionUtils.getSuperClassGenricType(getClass());}/** * 注入mongodbTemplate * * @param mongoTemplate */protected abstract void setMongoTemplate(MongoTemplate mongoTemplate);}
介于很多童鞋都在问ReflectionUtils类,这里附上
package com.yingchao.kgou.core;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.lang.reflect.ParameterizedType;import java.lang.reflect.Type;import org.apache.commons.lang.StringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.util.Assert;/** * 反射工具类. * * 提供访问私有变量,获取泛型类型Class, 提取集合中元素的属性, 转换字符串到对象等Util函数. * */public class ReflectionUtils {private static Logger logger = LoggerFactory.getLogger(ReflectionUtils.class);/** * 调用Getter方法. */public static Object invokeGetterMethod(Object obj, String propertyName) {String getterMethodName = "get" + StringUtils.capitalize(propertyName);return invokeMethod(obj, getterMethodName, new Class[] {}, new Object[] {});}/** * 调用Setter方法.使用value的Class来查找Setter方法. */public static void invokeSetterMethod(Object obj, String propertyName, Object value) {invokeSetterMethod(obj, propertyName, value, null);}/** * 调用Setter方法. * * @param propertyType 用于查找Setter方法,为空时使用value的Class替代. */public static void invokeSetterMethod(Object obj, String propertyName, Object value, Class<?> propertyType) {Class<?> type = propertyType != null ? propertyType : value.getClass();String setterMethodName = "set" + StringUtils.capitalize(propertyName);invokeMethod(obj, setterMethodName, new Class[] { type }, new Object[] { value });}/** * 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数. */public static Object getFieldValue(final Object obj, final String fieldName) {Field field = getAccessibleField(obj, fieldName);if (field == null) {throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");}Object result = null;try {result = field.get(obj);} catch (IllegalAccessException e) {logger.error("不可能抛出的异常{}", e.getMessage());}return result;}/** * 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数. */public static void setFieldValue(final Object obj, final String fieldName, final Object value) {Field field = getAccessibleField(obj, fieldName);if (field == null) {throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + obj + "]");}try {field.set(obj, value);} catch (IllegalAccessException e) {logger.error("不可能抛出的异常:{}", e.getMessage());}}/** * 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问. * * 如向上转型到Object仍无法找到, 返回null. */public static Field getAccessibleField(final Object obj, final String fieldName) {Assert.notNull(obj, "object不能为空");Assert.hasText(fieldName, "fieldName");for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {try {Field field = superClass.getDeclaredField(fieldName);field.setAccessible(true);return field;} catch (NoSuchFieldException e) {//NOSONAR// Field不在当前类定义,继续向上转型}}return null;}/** * 直接调用对象方法, 无视private/protected修饰符. * 用于一次性调用的情况. */public static Object invokeMethod(final Object obj, final String methodName, final Class<?>[] parameterTypes,final Object[] args) {Method method = getAccessibleMethod(obj, methodName, parameterTypes);if (method == null) {throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + obj + "]");}try {return method.invoke(obj, args);} catch (Exception e) {throw convertReflectionExceptionToUnchecked(e);}}/** * 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问. * 如向上转型到Object仍无法找到, 返回null. * * 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args) */public static Method getAccessibleMethod(final Object obj, final String methodName,final Class<?>... parameterTypes) {Assert.notNull(obj, "object不能为空");for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {try {Method method = superClass.getDeclaredMethod(methodName, parameterTypes);method.setAccessible(true);return method;} catch (NoSuchMethodException e) {//NOSONAR// Method不在当前类定义,继续向上转型}}return null;}/** * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. * 如无法找到, 返回Object.class. * eg. * public UserDao extends HibernateDao<User> * * @param clazz The class to introspect * @return the first generic declaration, or Object.class if cannot be determined */@SuppressWarnings({ "unchecked", "rawtypes" })public static <T> Class<T> getSuperClassGenricType(final Class clazz) {return getSuperClassGenricType(clazz, 0);}/** * 通过反射, 获得Class定义中声明的父类的泛型参数的类型. * 如无法找到, 返回Object.class. * * 如public UserDao extends HibernateDao<User,Long> * * @param clazz clazz The class to introspect * @param index the Index of the generic ddeclaration,start from 0. * @return the index generic declaration, or Object.class if cannot be determined */@SuppressWarnings("rawtypes")public static Class getSuperClassGenricType(final Class clazz, final int index) {Type genType = clazz.getGenericSuperclass();if (!(genType instanceof ParameterizedType)) {logger.warn(clazz.getSimpleName() + "'s superclass not ParameterizedType");return Object.class;}Type[] params = ((ParameterizedType) genType).getActualTypeArguments();if (index >= params.length || index < 0) {logger.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: "+ params.length);return Object.class;}if (!(params[index] instanceof Class)) {logger.warn(clazz.getSimpleName() + " not set the actual class on superclass generic parameter");return Object.class;}return (Class) params[index];}/** * 将反射时的checked exception转换为unchecked exception. */public static RuntimeException convertReflectionExceptionToUnchecked(Exception e) {if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException|| e instanceof NoSuchMethodException) {return new IllegalArgumentException("Reflection Exception.", e);} else if (e instanceof InvocationTargetException) {return new RuntimeException("Reflection Exception.", ((InvocationTargetException) e).getTargetException());} else if (e instanceof RuntimeException) {return (RuntimeException) e;}return new RuntimeException("Unexpected Checked Exception.", e);}}
这样,就完成了spring和mongodb的集成,其实很简单的。测试话就直接调用相关方法就可以了。。。
- spring集成mongodb封装的简单的CRUD
- spring集成mongodb封装的简单的CRUD
- SpringData集成Mongodb封装简单的CRUD
- spring MongoDB 集成crud操作(简单封装)
- spring MongoDB 集成crud操作(简单封装)
- 简单的spring-data集成mongoDB项目,实现crud的功能
- Spring mongodb 之简单CRUD
- mongodb学习4-简单的CRUD
- MongoDB的一些简单CRUD操作
- jpa+spring对实体的crud和实现分页功能的简单实用的封装
- Spring对MongoDB的简单集成及数据操作
- Spring Data MongoDB 一:入门篇(环境搭建、简单的CRUD操作)
- Spring Data MongoDB 一:入门篇(环境搭建、简单的CRUD操作)
- Spring Data MongoDB 一:入门篇(环境搭建、简单的CRUD操作)
- Spring Data MongoDB 一:入门篇(环境搭建、简单的CRUD操作)
- jersey+spring+mybatis+maven框架集成和实现简单的crud
- Spring Data 与MongoDB 集成一:入门篇(开发环境搭建和简单CRUD)
- Spring Data 与MongoDB 集成一:入门篇(开发环境搭建和简单CRUD)
- 2013年各大小IT公司待遇,绝对真实,一线数据!
- 通过shell sqlite3工具创建数据库
- 一个百度程序员的创业故事
- Android小项目之十一 应用程序的主界面
- 深入浅出CChart 每日一课——第九课 实时数据显示,期中考试
- spring集成mongodb封装的简单的CRUD
- CATransition炫一点的动画
- Excel插入时间(精确到秒)
- 现在输入法如果没这个设置就OUT了
- android一些有用的库
- reinterpret_cast說明
- 如何与各种自以为是的技术人员打交道?
- 信道编码
- oracle创建表之前判断表是否存在,如果存在则删除已有表