使用Morphia操作MongoDB

项目环境:SpringBoot + SpringClound + JDK8

1.添加Morphiade的Maven依赖

    <dependency>
      <groupId>org.mongodb.morphiagroupId>
      <artifactId>morphiaartifactId>
      <version>1.1.0version>
    dependency>

2.启动文件bootstrap.profiles中添加mongoDB配置

mongo.uri=mongodb://microschool:microschool@192.168.3.252:27017/micro-school?authSource=micro-school
mongo.dbName=micro-school

3.MongoDB属性读取及配置类

package com.h.mongo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class MongoProperties {
    @Value("${mongo.uri:}")
    protected String uri;
    @Value("${mongo.dbName:}")
    protected String dbName;

    public String getUri() {
        return uri==null?null:uri.trim();
    }
    public void setUri(String uri) {
        this.uri = uri;
    }
    public String getDbName() {
        return dbName==null?null:dbName.trim();
    }
    public void setDbName(String dbName) {
        this.dbName = dbName;
    }
}
package com.h.mongo;

import com.mongodb.MongoClient;
import com.mongodb.MongoClientOptions;
import com.mongodb.MongoClientURI;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import org.mongodb.morphia.annotations.Entity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;

import javax.annotation.PreDestroy;
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Configuration
public class MongoAutoConfiguration {
    protected Logger log = LoggerFactory.getLogger(getClass());  

    @Autowired
    private MongoProperties mongoProperties;

    @Bean(name = "dsForRW")
    public Datastore dsForRW() throws Exception {
        MongoClient mongoClient = createInstance(mongoProperties);
        Datastore dsForRWMdt = morphia().createDatastore(mongoClient, mongoProperties.getDbName());
        afterCreateDs(dsForRWMdt);
        return dsForRWMdt;
    }

    @PreDestroy
    public void close(){
        log.info("mongoClient is destroy");
    }

    private void afterCreateDs(Datastore dsForRW)  throws UnknownHostException {
        try {
            dsForRW.ensureIndexes();
            dsForRW.ensureCaps();
//          BasicDBObject keys = new BasicDBObject();
//          keys.put("link", 1);
//          keys.put("shortLink", 1);

//          DBCollection dbCollection = ds.getCollection(ShortLink.class);
//          dbCollection.createIndex(keys);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private MongoClient createInstance(MongoProperties mongoProperties)  throws UnknownHostException {

        MongoClientOptions.Builder builder = MongoClientOptions.builder();
        builder.socketKeepAlive(true);
        builder.connectTimeout(5000);
        builder.socketTimeout(0);
//      builder.maxWaitTime(60000);
        builder.heartbeatFrequency(2000);// 心跳频率

        MongoClientURI clientURI = new MongoClientURI(mongoProperties.getUri(),builder); 
        MongoClient mongoClient = new MongoClient(clientURI);
        if(StringUtils.isEmpty(mongoProperties.getDbName())){
            mongoProperties.setDbName(clientURI.getDatabase());
        }
        return mongoClient;
    }

    private Morphia morphia() {
        //
        Morphia morphia = new Morphia();
        // 手动加载
        if (0 == morphia.getMapper().getMappedClasses().size()) {
//          morphia.map(com.dachen.shorturl.domains.ShortLink.class);
        }
        SetclazzSet = this.getAllEntity("com.dachen");
        if(clazzSet!=null && clazzSet.size()>0){
            morphia.map(clazzSet);
        }
        morphia.getMapper().getConverters().addConverter(BigDecimalConverter.class);
        return morphia;
    }

    @SuppressWarnings("rawtypes")
    private Set getAllEntity(String packageName){
        List> returnClassList = ClassUtil.getClasses(packageName) ;
        if(returnClassList==null || returnClassList.isEmpty()){
            return null;
        }
        SetclazzSet = new HashSet<>();
        for(Class clazz:returnClassList){
            Entity entity = clazz.getAnnotation(Entity.class);
            if(entity!=null){
                log.info("loading mongo entity:{},table:{}",clazz.getName(),entity.value());
                clazzSet.add(clazz);
            }
        }
        return clazzSet;
    }

}

4.Morphia操作MongoDB的工具类

package com.h.mongo;

import com.mongodb.*;
import org.bson.types.ObjectId;
import org.mongodb.morphia.AdvancedDatastore;
import org.mongodb.morphia.mapping.Mapper;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;
import org.mongodb.morphia.query.UpdateResults;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

@Component
public class MongoCommonDAO {
    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource(name = "dsForRW")
    protected AdvancedDatastore dsForRW;


    public  T getByObjectId(final Class clazz,ObjectId id){
        @SuppressWarnings("unchecked")
        Query query = (Query) dsForRW.createQuery(clazz);
        query.filter(Mapper.ID_KEY,id);
        return query.get();
    }

    public  T getByPK(final Class clazz,String pk){
        Query  query = this.createQuery(clazz, pk);
        return query.get();
    }

    public  T findAndModifyByPK(final Class clazz,String pk,DBObject update){
        Query  query = this.createQuery(clazz, pk);
        UpdateOperations ops = this.createUpdateOperations(clazz, update);
        return dsForRW.findAndModify(query, ops);
    }

    public  T findAndModify(final Class clazz,DBObject filter,DBObject update){
        Query query = this.createQuery(clazz, filter);
        UpdateOperations ops = this.createUpdateOperations(clazz,update);
        return dsForRW.findAndModify(query, ops);
    }

    public  T findAndModifyOrCreate(final Class clazz,DBObject filter,DBObject update){
        Query query = this.createQuery(clazz, filter);
        UpdateOperations ops = this.createUpdateOperations(clazz,update);
        return dsForRW.findAndModify(query, ops,false, true);
    }

    public  UpdateResults update(final Class clazz,DBObject filter,DBObject update)
    {
        Query query = this.createQuery(clazz, filter);
        UpdateOperations ops = this.createUpdateOperations(clazz, update);
        return dsForRW.update(query, ops);
    }

    @SuppressWarnings("unchecked")
    public  UpdateResults addToArray(final Class clazz,DBObject filter,String fieldExpr, List values, boolean addDups)
    {
        Query query = this.createQuery(clazz, filter);
        UpdateOperations ops = (UpdateOperations) dsForRW.createUpdateOperations(clazz);
        ops.addAll(fieldExpr, values,addDups);
        return dsForRW.update(query, ops);
    }

    @SuppressWarnings("unchecked")
    public  UpdateResults removeFromArray(final Class clazz,DBObject filter,String fieldExpr, Object value)
    {
        Query query = this.createQuery(clazz, filter);
        UpdateOperations ops = (UpdateOperations) dsForRW.createUpdateOperations(clazz);
        ops.removeAll(fieldExpr, value);
        return dsForRW.update(query, ops);
    }

    @SuppressWarnings("unchecked")
    public  UpdateResults removeAllFromArray(final Class clazz,DBObject filter,String fieldExpr, List values){
        Query query = this.createQuery(clazz, filter);
        UpdateOperations ops = (UpdateOperations) dsForRW.createUpdateOperations(clazz);
        ops.removeAll(fieldExpr, values);
        return dsForRW.update(query, ops);
    }


    public T insertOrUpdate(T entity)
    {
        if (entity == null) {
            return null;
        }
        if (entity instanceof AbstractBaseInfo) {
            AbstractBaseInfo obj = (AbstractBaseInfo) entity;
            if (obj.getId() == null) {
                obj.setId(MongodbUtil.genMongoId());
                dsForRW.insert(obj);
                return entity;
            }
        }
        dsForRW.save(entity);
        return entity;
    }
//  public T insert(T entity) {
//      if (entity == null) {
//          return null;
//      }
//      Key key = dsForRW.insert(entity);
//      return entity;
//  }
    public void batchInsert(List objList) {
        Object[]arrays = new Object[objList.size()];
        int i=0;
        for(Object obj :objList){
            if(obj instanceof AbstractBaseInfo){
                AbstractBaseInfo entity = (AbstractBaseInfo)obj;
                if(entity.getId()==null)
                {
                    entity.setId(MongodbUtil.genMongoId());
                }
                arrays[i++]=entity;
            }else{
                arrays[i++]=obj;
            }
        }
        dsForRW.insert(arrays);
    }

    public  T get(final Class clazz,String field,Object value)
    {
        Query query = this.createQuery(clazz, new BasicDBObject(field,value));
        return query.get();
    }

    public  T get(final Class clazz,DBObject filter)
    {
        Query query = this.createQuery(clazz, filter);
        return query.get();
    }

    public  List getList(final Class clazz,String field,Object value){
        return this.getList(clazz, new BasicDBObject(field,value));
    }

    public  List getList(final Class clazz,DBObject filter)
    {
        Query query = this.createQuery(clazz, filter);
        return query.asList();
    }

    public  List getList(final Class clazz,DBObject filter,String sort)
    {
        Query query = this.createQuery(clazz, filter);
        if(StringUtils.isNotEmpty(sort)){
            query.order(sort);
        }
        return query.asList();
    }

    public  List getList(final Class clazz,DBObject filter,String sort,int limit)
    {
        Query query = this.createQuery(clazz, filter);
        if(StringUtils.isNotEmpty(sort)){
            query.order(sort);
        }
        if(limit>0){
            query.offset(0).limit(limit);
        }
        return query.asList();
    }
//  /**
//   * 
//   * @param clazz
//   * @param filter 过滤条件
//   * @param sort 排序条件 
  • {@code order("age,-date")} (age ascending, date descending)
  • // * @param pageSize 每页大小 // * @param pageIndex 第几页,从0开始 // * @return // */ // public PageVO getPageData(final Class clazz,DBObject filter,String sort,int pageSize,int pageIndex){ // if(pageSize<=0){ // pageSize = 20; // } // Query query = this.createQuery(clazz, filter); // long totalCount = query.countAll(); // if(StringUtils.isNotEmpty(sort)){ // query.order(sort); // } // query.offset(pageIndex * pageSize).limit(pageSize); // List list= query.asList(); // PageVO result = new PageVO<>(list,totalCount,pageSize); // return result; // } public boolean exists(final Class clazz,DBObject query){ return dsForRW.getCollection(clazz).getCount(query)>0; } public void remove(final Class clazz,DBObject filter){ if(filter==null){ throw new ServiceException("删除条件为空"); } Setkey = filter.keySet(); if(key==null || key.isEmpty()){ throw new ServiceException("删除条件为空"); } Query query = this.createQuery(clazz, filter); dsForRW.delete(query); } @SuppressWarnings("unchecked") public void cleanTable(final Class clazz){ Query query = (Query) dsForRW.createQuery(clazz); dsForRW.delete(query); } /** * field支持多级嵌套 ,比如:order.patient.id */ public List stringFieldList(final Class clazz,DBObject filter,String field){ DBObject projection = new BasicDBObject(); projection.put(field, 1);//1表示返回的数据 只包含这个字段,0表示排除 DBCursor cursor = dsForRW.getCollection(clazz).find(filter, projection); List fieldValueList = new ArrayList(); while (cursor.hasNext()) { DBObject obj = cursor.next(); fieldValueList.add(getFieldValue(obj,field.split("\\."))); } return fieldValueList; } private String getFieldValue(DBObject dbObj,String[]fields){ int length = fields.length; if(length>1){ Object obj = dbObj.get(fields[0]); if(obj instanceof DBObject){ String[]subFields = new String[length-1]; System.arraycopy(fields, 1, subFields, 0, length-1); return getFieldValue((DBObject)obj,subFields); } }else if(length==1){ return MongodbUtil.getString(dbObj, fields[0]); } return null; } @SuppressWarnings("unchecked") private UpdateOperations createUpdateOperations(final Class clazz,DBObject update){ UpdateOperations ops = (UpdateOperations) dsForRW.createUpdateOperations(clazz); for( String field:update.keySet()){ ops.set(field, update.get(field)); } return ops; } @SuppressWarnings("unchecked") private Query createQuery(final Class clazz,DBObject filter) { Query query = (Query) dsForRW.createQuery(clazz); if(filter!=null){ for(String condition:filter.keySet()){ query.filter(condition, filter.get(condition)); } } return query; } @SuppressWarnings("unchecked") private Query createQuery(final Class clazz,String id) { Query query = (Query) dsForRW.createQuery(clazz); query.filter(Mapper.ID_KEY,id); return query; } /** * @see org.mongodb.morphia.query.FieldEndImpl * 模糊查询 :左右模糊 TODO * * DBObject query = new BasicDBObject(); query.put("name", like(userName)); */ private BasicDBObject like(String content) { Pattern pattern = Pattern.compile("^.*" + content + ".*$", Pattern.CASE_INSENSITIVE); return new BasicDBObject("$regex", pattern); } /* * 模糊查询: TODO DBObject query = new BasicDBObject(); query.put("filename", endWith(“.pdf”)); */ private BasicDBObject endWith(String content) { Pattern pattern = Pattern.compile(content + "$", Pattern.MULTILINE); return new BasicDBObject("$regex", pattern); } public DBCollection getCollection(Class clazz) { return dsForRW.getCollection(clazz); } /** * 排除某些属性 */ public T getInfoExcludeField(Class clazz, DBObject filter, String... ignoringFields) { Query query = this.createQuery(clazz, filter); if(ignoringFields!=null && ignoringFields.length>0){ query.retrievedFields(false, ignoringFields); } return query.get(); } public T getInfoIncludeField(Class clazz, DBObject filter,String... includeFields) { Query query = this.createQuery(clazz, filter); if(includeFields!=null && includeFields.length>0){ query.retrievedFields(true, includeFields); } return query.get(); } public List getListExcludeField(Class clazz, DBObject filter,String sort, String... ignoringFields) { Query query = this.createQuery(clazz, filter); if(ignoringFields!=null && ignoringFields.length>0){ query.retrievedFields(false, ignoringFields); } if(StringUtils.isNotEmpty(sort)){ query.order(sort); } return query.asList(); } public List getListIncludeField(Class clazz, DBObject filter,String sort, String... includeFields) { Query query = this.createQuery(clazz, filter); if(StringUtils.isNotEmpty(sort)){ query.order(sort); } if(includeFields!=null && includeFields.length>0){ query.retrievedFields(true, includeFields); } return query.asList(); } /** * { key: { userId: 1 }, cond: { appId: "10001" }, reduce: function( curr, result ) { result.total += curr.money; }, initial: { total : 0 } } == select userId,sum(money) as total from tablename where appId="10001" *

    描述:

    * @param clazz * @param key * @param cond * @param initial * @param reduce */
    @SuppressWarnings("unchecked") public List group(final Class clazz,final DBObject key, final DBObject cond, final DBObject initial, final String reduce){ return (List) dsForRW.getCollection(clazz).group(key, cond, initial, reduce); } /** * select userId,sum(money) as total from tablename where appId="10001" * 条件(pipeline0) :{$match:{"appId":"10001"}} * 分组统计(pipeline1):{$group:{"_id":"$userId","total":{$sum:"$money"}}} * group支持操作:$sum,$avg,$first,$last,$max,$min,$push,$addToSet,$stdDevPop,$stdDevSamp *

    描述:

    * @param clazz * @param pipeline * @return */
    // private Iterable aggregate(final Class clazz,final List pipeline){ // AggregationOutput out = dsForRW.getCollection(clazz).aggregate(pipeline); // if(out!=null){ // return out.results(); // } //// dsForRW.getCollection(clazz).aggregate(pipeline, options) // return null; // } @SuppressWarnings("unchecked") public List distinct(final Class clazz,final String fieldName, final DBObject query){ return dsForRW.getCollection(clazz).distinct(fieldName, query); } public long count(final Class clazz,final DBObject query){ return dsForRW.getCollection(clazz).count(query); } //***************************************************************************// /** * * @param clazz * @param requestList * @param updateOne true表示只更新匹配的一条数据 * @param createIfMissing 如果不存在则插入新的文档[查询部分和更新部分的结合 ] */ public void batchUpdate(final Class clazz,List requestList,boolean updateOne,boolean createIfMissing) { if(requestList==null || requestList.size()<=0){ return; } int PAGE_SIZE =1000; int totalSize = requestList.size(); if(totalSize<=PAGE_SIZE){ this.batchUpdateByPage(clazz, requestList,updateOne,createIfMissing); }else{ int lastPageCount = totalSize % PAGE_SIZE; int count = totalSize / PAGE_SIZE; if(lastPageCount>0) { count++; } ListsubList = null; int toIndex = 0; for(int i=0;i1) * PAGE_SIZE; if(toIndex > totalSize){ toIndex = totalSize; } subList = requestList.subList(i * PAGE_SIZE, toIndex); this.batchUpdateByPage(clazz, subList,updateOne,createIfMissing); } } } private void batchUpdateByPage(final Class clazz,List requestList,boolean updateOne,boolean createIfMissing) { BulkWriteOperation bulk = dsForRW.getCollection(clazz).initializeOrderedBulkOperation(); for(BatchUpdateRequest request : requestList){ if(request.getFilter()==null && request.getPk()!=null){ request.setFilter(new BasicDBObject("_id", request.getPk())); } DBObject update = new BasicDBObject(); if(request.getUpdate()!=null){ update.put("$set", request.getUpdate()); } if(request.getInc()!=null){ update.put("$inc", request.getInc()); } if(update.keySet()==null || update.keySet().isEmpty()){ continue; } if(createIfMissing){ if(updateOne){ bulk.find(request.getFilter()).upsert().updateOne(update); }else{ bulk.find(request.getFilter()).upsert().update(update); } }else{ if(updateOne){ bulk.find(request.getFilter()).updateOne(update); }else{ bulk.find(request.getFilter()).update(update); } } } bulk.execute(); } /** * 暂不支持嵌套对象 * @param clazz * @param objList */ public void batchInsertOrUpdate(final Class clazz,List objList) { if(objList==null || objList.size()<=0){ return; } BulkWriteOperation bulk = dsForRW.getCollection(clazz).initializeOrderedBulkOperation(); DBObject document; for(AbstractBaseInfo obj :objList){ if(obj.getId()==null){ obj.setId(MongodbUtil.genMongoId()); } try { document = bean2DBObject(obj); bulk.find(new BasicDBObject("_id", obj.getId())).upsert().updateOne(new BasicDBObject("$set",document)); } catch (IllegalArgumentException | IllegalAccessException e) { logger.error(e.getMessage()); } } bulk.execute(); } /** * 暂不支持嵌套对象 * @param clazz * @param objList */ public void batchUpdate(final Class clazz,List objList) { BulkWriteOperation bulk = dsForRW.getCollection(clazz).initializeUnorderedBulkOperation(); for(AbstractBaseInfo obj :objList){ if(obj.getId()==null){ continue; } DBObject document; try { document = bean2DBObject(obj); bulk.find(new BasicDBObject("_id", obj.getId())).updateOne(new BasicDBObject("$set",document)); } catch (IllegalArgumentException | IllegalAccessException e) { logger.error(e.getMessage()); } } bulk.execute(); } // public MongoClient mongoClient(){ // return dsForRW.getMongo(); // } private static DBObject bean2DBObject(T bean) throws IllegalArgumentException, IllegalAccessException { if (bean == null) { return null; } DBObject dbObject = new BasicDBObject(); // 获取对象对应类中的所有属性域 Field[] fields = bean.getClass().getDeclaredFields(); for (Field field : fields) { // 获取属性名 String varName = field.getName(); // 修改访问控制权限 boolean accessFlag = field.isAccessible(); if (!accessFlag) { field.setAccessible(true); } Object param = field.get(bean); if (param == null) { continue; } dbObject.put(varName, param); // 恢复访问控制权限 field.setAccessible(accessFlag); } return dbObject; } }

    5.其他辅助类

    package com.h.mongo;
    
    import org.mongodb.morphia.annotations.Id;
    
    /**
     * mongo实体基类
     * @author Administrator
     */
    public abstract class AbstractBaseInfo {
    
        @Id
        private String id;
    
        private String clientAppId;
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((id == null) ? 0 : id.hashCode());
            return result;
        }
    
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            AbstractBaseInfo other = (AbstractBaseInfo) obj;
            if (id == null) {
                if (other.id != null)
                    return false;
            } else if (!id.equals(other.id))
                return false;
            return true;
        }
    
        public String getClientAppId() {
            return clientAppId;
        }
    
        public void setClientAppId(String clientAppId) {
            this.clientAppId = clientAppId;
        }
    }
    
    package com.h.mongo;
    
    import com.mongodb.DBObject;
    
    public class BatchUpdateRequest {
    
        private Object pk;
    
        private DBObject filter;
    
        private DBObject update;
    
        private DBObject inc;
    
        public DBObject getFilter() {
            return filter;
        }
    
        public void setFilter(DBObject filter) {
            this.filter = filter;
        }
    
        public DBObject getUpdate() {
            return update;
        }
    
        public void setUpdate(DBObject update) {
            this.update = update;
        }
    
        public Object getPk() {
            return pk;
        }
    
        public void setPk(Object pk) {
            this.pk = pk;
        }
    
        public DBObject getInc() {
            return inc;
        }
    
        public void setInc(DBObject inc) {
            this.inc = inc;
        }
    }
    
    package com.h.mongo;
    
    import org.mongodb.morphia.converters.SimpleValueConverter;
    import org.mongodb.morphia.converters.TypeConverter;
    import org.mongodb.morphia.mapping.MappedField;
    import org.mongodb.morphia.mapping.MappingException;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    
    import java.math.BigDecimal;
    
    public class BigDecimalConverter extends TypeConverter implements SimpleValueConverter {
        private final Logger logger = LoggerFactory.getLogger(getClass());
        public BigDecimalConverter() {
            super(BigDecimal.class);
        }
        @Override
        protected boolean isSupported(Class c, MappedField optionalExtraInfo) {
            return BigDecimal.class.isAssignableFrom(c);
        }
    
        @Override
        public Object encode(Object value, MappedField optionalExtraInfo) {
            if (value == null) return null;  
    
            return value.toString();
        }
    
        @Override
        public Object decode(Class targetClass, Object fromDBObject, MappedField optionalExtraInfo) throws MappingException {
            if (fromDBObject == null) return null;  
            try{
                if (fromDBObject instanceof String) {
                    return new BigDecimal((String)fromDBObject);
                }else if (fromDBObject instanceof Number) {
                    return new BigDecimal(((Number)fromDBObject).doubleValue());
                }else{
                    logger.warn(fromDBObject.toString());
                }
            }catch(NumberFormatException e){
                logger.warn(fromDBObject.toString());
            }
            return null;
        }
    
    
    }
    
    package com.h.mongo;
    
    import org.mongodb.morphia.annotations.Entity;
    
    import java.io.File;
    import java.io.FileFilter;
    import java.io.IOException;
    import java.net.JarURLConnection;
    import java.net.URL;
    import java.net.URLDecoder;
    import java.util.*;
    import java.util.jar.JarEntry;
    import java.util.jar.JarFile;
    
    public class ClassUtil {
        public static void main(String[] args) {
            Set> classSet = getAllClassByAnnotation("com.h");
            for (Class cls:classSet){
                System.out.println(cls);
            }
        }
        /**
         * 取得某个包下所有实现这个接口的类
         */
        public static Set> getAllClassByAnnotation(String packageName) {
            List> classList =ClassUtil.getClasses(packageName) ;
            Set> returnClassList = new HashSet<>();
            for(Class clazz:classList){
                Entity entity = clazz.getAnnotation(Entity.class);
                if(entity!=null){
                    returnClassList.add(clazz);
                }else{
    //              System.out.println();
                }
            }
            return returnClassList;
        }
        /**
         * 取得某个接口下所有实现这个接口的类
         * */
        @SuppressWarnings("rawtypes")
        public static List getAllClassByInterface(Class c) {
            List returnClassList = null;
    
            if (c.isInterface()) {
                // 获取当前的包名
                String packageName = c.getPackage().getName();
                // 获取当前包下以及子包下所以的类
                List> allClass = getClasses(packageName);
                if (allClass != null) {
                    returnClassList = new ArrayList();
                    for (Classclasses : allClass) {
                        // 判断是否是同一个接口
                        if (c.isAssignableFrom(classes)) {
                            // 本身不加入进去
                            if (!c.equals(classes)) {
                                returnClassList.add(classes);
                            }
                        }
                    }
                }
            }
    
            return returnClassList;
        }
    
        /*
         * 取得某一类所在包的所有类名 不含迭代
         */
        public static String[] getPackageAllClassName(String classLocation,
                String packageName) {
            // 将packageName分解
            String[] packagePathSplit = packageName.split("[.]");
            String realClassLocation = classLocation;
            int packageLength = packagePathSplit.length;
            for (int i = 0; i < packageLength; i++) {
                realClassLocation = realClassLocation + File.separator + packagePathSplit[i];
            }
            File packeageDir = new File(realClassLocation);
            if (packeageDir.isDirectory()) {
                String[] allClassName = packeageDir.list();
                return allClassName;
            }
            return null;
        }
    
        /**
         * 从包package中获取所有的Class
         * 
         * @param pack
         * @return
         */
        public static List> getClasses(String packageName) {
    
            // 第一个class类的集合
            List> classes = new ArrayList>();
            // 是否循环迭代
            boolean recursive = true;
            // 获取包的名字 并进行替换
            String packageDirName = packageName.replace('.', '/');
            // 定义一个枚举的集合 并进行循环来处理这个目录下的things
            Enumeration dirs;
            try {
                dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
                // 循环迭代下去
                while (dirs.hasMoreElements()) {
                    // 获取下一个元素
                    URL url = dirs.nextElement();
                    // 得到协议的名称
                    String protocol = url.getProtocol();
                    // 如果是以文件的形式保存在服务器上
                    if ("file".equals(protocol)) {
                        // 获取包的物理路径
                        String filePath = URLDecoder.decode(url.getFile(), "UTF-8");
                        // 以文件的方式扫描整个包下的文件 并添加到集合中
                        findAndAddClassesInPackageByFile(packageName, filePath,recursive, classes);
                    } else if ("jar".equals(protocol)) {
                        // 如果是jar包文件
                        // 定义一个JarFile
                        JarFile jar;
                        try {
                            // 获取jar
                            jar = ((JarURLConnection) url.openConnection()).getJarFile();
                            // 从此jar包 得到一个枚举类
                            Enumeration entries = jar.entries();
                            // 同样的进行循环迭代
                            while (entries.hasMoreElements()) {
                                // 获取jar里的一个实体 可以是目录 和一些jar包里的其他文件 如META-INF等文件
                                JarEntry entry = entries.nextElement();
                                String name = entry.getName();
                                // 如果是以/开头的
                                if (name.charAt(0) == '/') {
                                    // 获取后面的字符串
                                    name = name.substring(1);
                                }
                                // 如果前半部分和定义的包名相同
                                if (name.startsWith(packageDirName)) {
                                    int idx = name.lastIndexOf('/');
                                    // 如果以"/"结尾 是一个包
                                    if (idx != -1) {
                                        // 获取包名 把"/"替换成"."
                                        packageName = name.substring(0, idx).replace('/', '.');
                                    }
                                    // 如果可以迭代下去 并且是一个包
                                    if ((idx != -1) || recursive) {
                                        // 如果是一个.class文件 而且不是目录
                                        if (name.endsWith(".class") && !entry.isDirectory()) {
                                            // 去掉后面的".class" 获取真正的类名
                                            String className = name.substring(packageName.length() + 1,name.length() - 6);
                                            try {
                                                // 添加到classes
                                                classes.add(Class.forName(packageName + '.'+ className));
                                            } catch (ClassNotFoundException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                    }
                                }
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            return classes;
        }
    
        /**
         * 以文件的形式来获取包下的所有Class
         * 
         * @param packageName
         * @param packagePath
         * @param recursive
         * @param classes
         */
        public static void findAndAddClassesInPackageByFile(String packageName,
                String packagePath, final boolean recursive, List> classes) {
            // 获取此包的目录 建立一个File
            File dir = new File(packagePath);
            // 如果不存在或者 也不是目录就直接返回
            if (!dir.exists() || !dir.isDirectory()) {
                return;
            }
            // 如果存在 就获取包下的所有文件 包括目录
            File[] dirfiles = dir.listFiles(new FileFilter() {
                // 自定义过滤规则 如果可以循环(包含子目录) 或则是以.class结尾的文件(编译好的java类文件)
                public boolean accept(File file) {
                    return (recursive && file.isDirectory()) || (file.getName().endsWith(".class"));
                }
            });
            // 循环所有文件
            for (File file : dirfiles) {
                // 如果是目录 则继续扫描
                if (file.isDirectory()) {
                    findAndAddClassesInPackageByFile(packageName + "." + file.getName(),file.getAbsolutePath(), recursive, classes);
                } else {
                    // 如果是java类文件 去掉后面的.class 只留下类名
                    String className = file.getName().substring(0,file.getName().length() - 6);
                    try {
                        // 添加到集合中去
                        classes.add(Class.forName(packageName + '.' + className));
                    } catch (ClassNotFoundException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    
    package com.h.mongo;
    
    import com.mongodb.DBObject;
    import org.bson.types.ObjectId;
    
    public class MongodbUtil {
        public static String getString(DBObject obj, String key) {
            Object val = obj.get(key);
            return val == null ? "" : val.toString();
        }
    
        public static Integer getInteger(DBObject obj, String key) {
            Object val = obj.get(key);
            if (val != null) {
                if (val instanceof Number) {
                    return ((Number) val).intValue();
                }
                return Integer.parseInt(val.toString());
            }
            return null;
        }
    
        public static int getIntValue(DBObject obj, String key) {
            Integer v = MongodbUtil.getInteger(obj, key);
            return v==null?0:v.intValue();
        }
        public static Long getLong(DBObject obj, String key) {
            Object val = obj.get(key);
            if (val != null) {
                return Long.parseLong(val.toString());
            }
            return null;
        }
        public static long getLongValue(DBObject obj, String key) {
            Long v = MongodbUtil.getLong(obj, key);
            return v==null?0:v.longValue();
        }
        public static Double getDouble(DBObject obj, String key) {
            Object val = obj.get(key);
            return val == null ? null : (Double) val;
        }
    
        public static Boolean getBoolean(DBObject obj, String key) {
            Object val = obj.get(key);
            return val == null ? null : (Boolean) val;
        }
    
        public static String genMongoId() {
            return ObjectId.get().toString();
        }
    
    }
    
    package com.h.mongo;
    
    public class ServiceException extends RuntimeException {
    
        private static final long serialVersionUID = 1L;
    
        private Integer resultCode;
    
        public ServiceException(Integer resultCode, String message) {
            super(message);
    
            this.resultCode = resultCode;
        }
    
        public ServiceException(String message) {
            super(message);
        }
    
    
        public Integer getResultCode() {
            return resultCode;
        }
    
    }
    
    package com.h.mongo;
    
    import java.text.NumberFormat;
    import java.util.Random;
    import java.util.UUID;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    /**
     * @author wanghong
     * @desc
     * @date: 2017/12/5  14:18
     * @Copyright (c) 2017, DaChen All Rights Reserved.
     */
    public final class StringUtils extends org.apache.commons.lang3.StringUtils {
        public static final String CRLF = "\r\n";
        public static final String BASE = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        public static final String BASE_2 = "abcdefghijklmnopqrstuvwxyz0123456789";
        public static final String BASE_3 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        private static final char[] charArray = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
    
        public StringUtils() {
        }
    
        public static String StringFilter(String str) {
            if (str == null) {
                return str;
            } else {
                Pattern p = Pattern.compile("[\u0001\u0002\u0003\u0004\u0006\u0007\u000b\u001c\u001d\u001e\u001f]");
                Matcher m = p.matcher(str);
                return m.find() ? m.replaceAll(" ").trim() : str;
            }
        }
    
        public static boolean isNotEmpty(String str) {
            return !isEmpty(str);
        }
    
        public static boolean isNumber(String str) {
            Pattern pattern = Pattern.compile("[0-9]*");
            return pattern.matcher(str).matches();
        }
    
        public static String IdToUpperCase(String s) {
            if (s == null) {
                s = "";
            }
    
            s = s.trim().toUpperCase();
            s = s.replaceAll(" ", "_");
            s = s.replaceAll("_+", "_");
            return s;
        }
    
        public static void append(StringBuilder buf, byte b, int base) {
            int bi = 255 & b;
            int c = 48 + bi / base % base;
            if (c > 57) {
                c = 97 + (c - 48 - 10);
            }
    
            buf.append((char)c);
            c = 48 + bi % base;
            if (c > 57) {
                c = 97 + (c - 48 - 10);
            }
    
            buf.append((char)c);
        }
    
        public static String getRandomString(int length) {
            return randomString(length, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
        }
    
        private static String randomString(int length, String base) {
            Random random = new Random();
            StringBuffer sb = new StringBuffer();
    
            for(int i = 0; i < length; ++i) {
                int number = random.nextInt(base.length());
                sb.append(base.charAt(number));
            }
    
            return sb.toString();
        }
    
        public static String getRandomString2(int length) {
            return randomString(length, "abcdefghijklmnopqrstuvwxyz0123456789");
        }
    
        public static String randomId() {
            return randomString(10, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
        }
    
        public static String randomUUID() {
            UUID uuid = UUID.randomUUID();
            String uuidStr = uuid.toString().replace("-", "");
            return uuidStr;
        }
    
        public static boolean startsWith(CharSequence str, CharSequence prefix) {
            return org.apache.commons.lang3.StringUtils.startsWith(str, prefix);
        }
    
        public static boolean endsWith(CharSequence str, CharSequence suffix) {
            return org.apache.commons.lang3.StringUtils.endsWith(str, suffix);
        }
    
        public static String[] split(String str, String separatorChars) {
            return org.apache.commons.lang3.StringUtils.split(str, separatorChars);
        }
    
        public static String[] split(String str, String separatorChars, int max) {
            return org.apache.commons.lang3.StringUtils.split(str, separatorChars, max);
        }
    
        public static boolean equals(CharSequence cs1, CharSequence cs2) {
            return org.apache.commons.lang3.StringUtils.equals(cs1, cs2);
        }
    
        public static String join(Object[] array, String separator) {
            return org.apache.commons.lang3.StringUtils.join(array, separator);
        }
    
        public static String getExt(String filename) {
            return filename.substring(filename.lastIndexOf(46));
        }
    
        public static boolean isEmpty(String s) {
            return isNullOrEmpty(s);
        }
    
        public static boolean isNullOrEmpty(String s) {
            return null == s || 0 == s.trim().length();
        }
    
        public static String randomCode() {
            return "" + ((new Random()).nextInt(899999) + 100000);
        }
    
        public static String random4Code() {
            return "" + ((new Random()).nextInt(8999) + 1000);
        }
    
        public static String randomPassword() {
            return randomString(6);
        }
    
        public static String randomString(int length) {
            StringBuffer sb = new StringBuffer();
    
            for(int i = 0; i < length; ++i) {
                int index = (new Random()).nextInt(36);
                sb.append(charArray[index]);
            }
    
            return sb.toString();
        }
    
        public static String getFormatName(String fileName) {
            int index = fileName.lastIndexOf(46);
            return -1 == index ? "jpg" : fileName.substring(index + 1);
        }
    
        public static String format(long number, int length) {
            NumberFormat nf = NumberFormat.getInstance();
            nf.setMaximumIntegerDigits(length);
            nf.setMinimumIntegerDigits(length);
            nf.setGroupingUsed(false);
            return nf.format(number);
        }
    
        public static String atKey(String telephone, Integer userType) {
            return String.format("uk_%1$s_%2$d", telephone, userType);
        }
    
        public static String atValue(String orderRecharegeNo, String refundRrice, String refundReason) {
            return String.format("%1$s^%2$s^%3$s", orderRecharegeNo, refundRrice, refundReason);
        }
    
        public static boolean isMobiPhoneNum(String telNum) {
            String regex = "^((13[0-9])|(15[0-9])|(18[0-9]))\\d{8}$";
            Pattern p = Pattern.compile(regex, 2);
            Matcher m = p.matcher(telNum);
            return m.matches();
        }
    }
    
    
    package com.h.util;
    
    import org.springframework.beans.BeanUtils;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class BeanUtil {
    
         public static  T copy(Object poObj,final Class voClass)
         {
             T voObj =null;
             try {
                 voObj = voClass.newInstance();
                 BeanUtils.copyProperties(poObj, voObj);
                 return voObj;
             } catch (InstantiationException | IllegalAccessException e) {
                 e.printStackTrace();
             }
             return null;
         }
         public static  List  copyList(List  poList ,final Class voClass){
    
            List voList=new ArrayList();
    
            T voObj =null;
            for(Object poObj:poList){
                try {
                    voObj = voClass.newInstance();
                    BeanUtils.copyProperties(poObj, voObj);
                    voList.add(voObj);
                } catch (InstantiationException | IllegalAccessException e) {
                    e.printStackTrace();
                }
    //            System.out.println(voObj);
            }
            return voList;
        }
    }
    

    6.使用示例

     package com.dachen.microschool.model.po;
    
    import com.dachen.support.mongo.base.AbstractBaseInfo;
    import io.swagger.annotations.ApiModelProperty;
    import org.mongodb.morphia.annotations.Entity;
    
    import java.util.List;
    
    /**
     * @author wanghong
     * @desc
     * @date: 2017/11/14  11:33
     * @Copyright (c) 2017, DaChen All Rights Reserved.
     * 课程表
     */
    @Entity(value = "t_course",noClassnameStored = true)
    public class Course extends AbstractBaseInfo {
    
        @ApiModelProperty(value = "讲堂ID")
        private String classId;
    
        @ApiModelProperty(value = "课程所属人[冗余]")
        private String ownerId;
    
        @ApiModelProperty(value = "课程主题")
        private String theme;
    
        @ApiModelProperty(value = "修改时间")
        private Long updateTime;
    
        @ApiModelProperty(value = "创建时间")
        private Long createTime;
    
        @ApiModelProperty(value = "课程开讲时间")
        private Long beginTime;
    
        @ApiModelProperty(value = "课程形式 0-幻灯片形式 1-聊天形式")
        private int form;
    
        @ApiModelProperty(value = "课程类型 0-公开课 1-收费课")
        private int type;
    
        @ApiModelProperty(value = "封面题图")
        private String coverImgUrl;
    
        @ApiModelProperty(value = "课程简介")
        private String introduce;
    
        @ApiModelProperty(value = "课程摘要")
        private String digest;
    
        @ApiModelProperty(value = "课程创建人")
        private String creator;
    
        @ApiModelProperty(value = "课程标签集合")
        private List labels;
    
        @ApiModelProperty(value = "课程状态 0-草稿 1-发布 9-结束")
        private int status;
    
        @ApiModelProperty(value = "课程发布范围类型 0-全员公开 1-指定圈子范围 2-指定科室(课程所属用户所在科室)")
        private Integer publishType;
    
        get/set()....
    }
    
    package com.dachen.microschool.model.request;
    
    import io.swagger.annotations.ApiModelProperty;
    
    import java.util.List;
    
    /**
     * @author wanghong
     * @desc
     * @date: 2017/12/1  15:09
     * @Copyright (c) 2017, DaChen All Rights Reserved.
     */
    public class CourseRequest {
    
        @ApiModelProperty(value = "讲堂ID")
        private String classId;
    
        @ApiModelProperty(value = "课程所属人[冗余]")
        private String ownerId;
    
        @ApiModelProperty(value = "课程主题")
        private String theme;
    
        @ApiModelProperty(value = "课程开讲时间")
        private Long beginTime;
    
        @ApiModelProperty(value = "课程形式 0-幻灯片形式 1-聊天形式")
        private int form;
    
        @ApiModelProperty(value = "课程类型 0-公开课 1-收费课")
        private int type;
    
        @ApiModelProperty(value = "封面题图")
        private String coverImgUrl;
    
        @ApiModelProperty(value = "课程简介")
        private String introduce;
    
        @ApiModelProperty(value = "课程摘要")
        private String digest;
    
        @ApiModelProperty(value = "课程创建人")
        private String creator;
    
        @ApiModelProperty(value = "课程标签集合")
        private List labelNameList;
    
        @ApiModelProperty(value = "课程发布范围类型 0-全员公开 1-指定圈子范围 2-指定科室(课程所属用户所在科室)")
        private Integer publishType;
    
        get/set()
    }
    
    //客户端调用
    @ApiOperation(value="新建课程", httpMethod="POST", response=String.class, notes = "成功返回  \"data\": \"课程id\"")
        @RequestMapping(value="/createCourse", method= RequestMethod.POST)
        public Result createCourse(@RequestBody CourseRequest courseRequest){
            return  Result.build(courseService.createCourse(courseRequest));
        }
    
     //新增
      Course course = BeanUtil.copy(courseRequest, Course.class);
      course.setCreateTime(System.currentTimeMillis()); 
      mongoCommonDAO.insertOrUpdate(course);
    
    //批量更新多条记录
     /**
         * 添加课程课件/素材
         * 每次添加前先逻辑删除原先的该课程下的课件,再保存
         * @param coursewareList
         */
        public void addCourseWare(List coursewareList){
            if (CollectionUtils.isNotEmpty(coursewareList)){
                String courseId =coursewareList.get(0).getCourseId();
    
                DBObject query = new BasicDBObject();
                query.put("courseId",courseId);
                query.put("deleted",0);
                List list = mongoCommonDAO.getList(Courseware.class,query);
                if (CollectionUtils.isNotEmpty(list)){
                    //批量更新删除状态
                    ListupdateList = new ArrayList<>(list.size());
                    BatchUpdateRequest req = null;
                    for (Courseware cw:list){
                        req = new BatchUpdateRequest();
                        req.setPk(cw.getId());
                        DBObject update = new BasicDBObject("deleted",1);
                        req.setUpdate(update);
                        updateList.add(req);
                    }
                    mongoCommonDAO.batchUpdate(Courseware.class, updateList,true,false);
                }
    
                    int size = coursewareList.size();
                    list = new ArrayList<>(size);
                    for (int i=0;inew Courseware();
                        courseware.setCourseId(courseId);
                        courseware.setPageNumber(i);
                        courseware.setDeleted(0);
                        courseware.setType(request.getType());
                        courseware.setName(request.getName());
                        courseware.setUrl(request.getUrl());
    
                        list.add(courseware);
                    }
                    mongoCommonDAO.batchInsert(list);
            }
        }
    
    //聚合查询
    /**
         * 批量获取课程列表
         * @param courseIdList
         * @return
         */
        public List getCourseList(List courseIdList){
            Map map = new HashMap<>();
            map.put("id in", courseIdList);
            DBObject query = new BasicDBObject(map);
            //或者下面的写法
            //DBObject query = new BasicDBObject();
           // query.put("_id",new BasicDBObject("$in",courseIdList));
            List courseList = mongoCommonDAO.getList(Course.class,query);
            return wrapCourse(courseList);
        }

    你可能感兴趣的:(Database)