项目环境:SpringBoot + SpringClound + JDK8
1.添加Morphiade的Maven依赖
<dependency>
<groupId>org.mongodb.morphia</groupId>
<artifactId>morphia</artifactId>
<version>1.1.0</version>
</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);
}
Set<Class>clazzSet = 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<Class> getAllEntity(String packageName){
List<Class<?>> returnClassList = ClassUtil.getClasses(packageName) ;
if(returnClassList==null || returnClassList.isEmpty()){
return null;
}
Set<Class>clazzSet = 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> T getByObjectId(final Class<?> clazz,ObjectId id){
@SuppressWarnings("unchecked")
Query<T> query = (Query<T>) dsForRW.createQuery(clazz);
query.filter(Mapper.ID_KEY,id);
return query.get();
}
public <T> T getByPK(final Class<?> clazz,String pk){
Query <T> query = this.createQuery(clazz, pk);
return query.get();
}
public <T> T findAndModifyByPK(final Class<?> clazz,String pk,DBObject update){
Query <T> query = this.createQuery(clazz, pk);
UpdateOperations<T> ops = this.createUpdateOperations(clazz, update);
return dsForRW.findAndModify(query, ops);
}
public <T> T findAndModify(final Class<?> clazz,DBObject filter,DBObject update){
Query<T> query = this.createQuery(clazz, filter);
UpdateOperations<T> ops = this.createUpdateOperations(clazz,update);
return dsForRW.findAndModify(query, ops);
}
public <T> T findAndModifyOrCreate(final Class<?> clazz,DBObject filter,DBObject update){
Query<T> query = this.createQuery(clazz, filter);
UpdateOperations<T> ops = this.createUpdateOperations(clazz,update);
return dsForRW.findAndModify(query, ops,false, true);
}
public <T> UpdateResults update(final Class<?> clazz,DBObject filter,DBObject update)
{
Query<T> query = this.createQuery(clazz, filter);
UpdateOperations<T> ops = this.createUpdateOperations(clazz, update);
return dsForRW.update(query, ops);
}
@SuppressWarnings("unchecked")
public <T> UpdateResults addToArray(final Class<?> clazz,DBObject filter,String fieldExpr, List<?> values, boolean addDups)
{
Query<T> query = this.createQuery(clazz, filter);
UpdateOperations<T> ops = (UpdateOperations<T>) dsForRW.createUpdateOperations(clazz);
ops.addAll(fieldExpr, values,addDups);
return dsForRW.update(query, ops);
}
@SuppressWarnings("unchecked")
public <T> UpdateResults removeFromArray(final Class<?> clazz,DBObject filter,String fieldExpr, Object value)
{
Query<T> query = this.createQuery(clazz, filter);
UpdateOperations<T> ops = (UpdateOperations<T>) dsForRW.createUpdateOperations(clazz);
ops.removeAll(fieldExpr, value);
return dsForRW.update(query, ops);
}
@SuppressWarnings("unchecked")
public <T> UpdateResults removeAllFromArray(final Class<?> clazz,DBObject filter,String fieldExpr, List<?> values){
Query<T> query = this.createQuery(clazz, filter);
UpdateOperations<T> ops = (UpdateOperations<T>) dsForRW.createUpdateOperations(clazz);
ops.removeAll(fieldExpr, values);
return dsForRW.update(query, ops);
}
public <T>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>T insert(T entity) {
// if (entity == null) {
// return null;
// }
// Key<T> 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> T get(final Class<?> clazz,String field,Object value)
{
Query<T> query = this.createQuery(clazz, new BasicDBObject(field,value));
return query.get();
}
public <T> T get(final Class<?> clazz,DBObject filter)
{
Query<T> query = this.createQuery(clazz, filter);
return query.get();
}
public <T> List<T> getList(final Class<?> clazz,String field,Object value){
return this.getList(clazz, new BasicDBObject(field,value));
}
public <T> List<T> getList(final Class<?> clazz,DBObject filter)
{
Query<T> query = this.createQuery(clazz, filter);
return query.asList();
}
public <T> List<T> getList(final Class<?> clazz,DBObject filter,String sort)
{
Query<T> query = this.createQuery(clazz, filter);
if(StringUtils.isNotEmpty(sort)){
query.order(sort);
}
return query.asList();
}
public <T> List<T> getList(final Class<?> clazz,DBObject filter,String sort,int limit)
{
Query<T> 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 排序条件 <li>{@code order("age,-date")} (age ascending, date descending)</li>
// * @param pageSize 每页大小
// * @param pageIndex 第几页,从0开始
// * @return
// */
// public <T> PageVO<T> getPageData(final Class<?> clazz,DBObject filter,String sort,int pageSize,int pageIndex){
// if(pageSize<=0){
// pageSize = 20;
// }
// Query<T> query = this.createQuery(clazz, filter);
// long totalCount = query.countAll();
// if(StringUtils.isNotEmpty(sort)){
// query.order(sort);
// }
// query.offset(pageIndex * pageSize).limit(pageSize);
// List<T> list= query.asList();
// PageVO<T> result = new PageVO<>(list,totalCount,pageSize);
// return result;
// }
public boolean exists(final Class<?> clazz,DBObject query){
return dsForRW.getCollection(clazz).getCount(query)>0;
}
public <T> void remove(final Class<?> clazz,DBObject filter){
if(filter==null){
throw new ServiceException("删除条件为空");
}
Set<String>key = filter.keySet();
if(key==null || key.isEmpty()){
throw new ServiceException("删除条件为空");
}
Query<T> query = this.createQuery(clazz, filter);
dsForRW.delete(query);
}
@SuppressWarnings("unchecked")
public <T> void cleanTable(final Class<?> clazz){
Query<T> query = (Query<T>) dsForRW.createQuery(clazz);
dsForRW.delete(query);
}
/**
* field支持多级嵌套 ,比如:order.patient.id
*/
public List<String> 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<String> fieldValueList = new ArrayList<String>();
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 <T> UpdateOperations<T> createUpdateOperations(final Class<?> clazz,DBObject update){
UpdateOperations<T> ops = (UpdateOperations<T>) dsForRW.createUpdateOperations(clazz);
for( String field:update.keySet()){
ops.set(field, update.get(field));
}
return ops;
}
@SuppressWarnings("unchecked")
private <T> Query<T> createQuery(final Class<?> clazz,DBObject filter) {
Query<T> query = (Query<T>) dsForRW.createQuery(clazz);
if(filter!=null){
for(String condition:filter.keySet()){
query.filter(condition, filter.get(condition));
}
}
return query;
}
@SuppressWarnings("unchecked")
private <T> Query<T> createQuery(final Class<?> clazz,String id) {
Query<T> query = (Query<T>) 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 <T> DBCollection getCollection(Class<?> clazz) {
return dsForRW.getCollection(clazz);
}
/**
* 排除某些属性
*/
public <T> T getInfoExcludeField(Class<?> clazz, DBObject filter, String... ignoringFields) {
Query<T> query = this.createQuery(clazz, filter);
if(ignoringFields!=null && ignoringFields.length>0){
query.retrievedFields(false, ignoringFields);
}
return query.get();
}
public <T> T getInfoIncludeField(Class<?> clazz, DBObject filter,String... includeFields) {
Query<T> query = this.createQuery(clazz, filter);
if(includeFields!=null && includeFields.length>0){
query.retrievedFields(true, includeFields);
}
return query.get();
}
public <T> List<T> getListExcludeField(Class<?> clazz, DBObject filter,String sort, String... ignoringFields) {
Query<T> 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 <T> List<T> getListIncludeField(Class<?> clazz, DBObject filter,String sort, String... includeFields) {
Query<T> 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"
* <p>描述:</p>
* @param clazz
* @param key
* @param cond
* @param initial
* @param reduce
*/
@SuppressWarnings("unchecked")
public List<DBObject> group(final Class<?> clazz,final DBObject key, final DBObject cond, final DBObject initial, final String reduce){
return (List<DBObject>) 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
* <p>描述:</p>
* @param clazz
* @param pipeline
* @return
*/
// private Iterable<DBObject> aggregate(final Class<?> clazz,final List<? extends DBObject> 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<Object> 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<BatchUpdateRequest> 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++;
}
List<BatchUpdateRequest>subList = null;
int toIndex = 0;
for(int i=0;i<count;i++)
{
toIndex =(i+1) * 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<BatchUpdateRequest> 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<? extends AbstractBaseInfo> 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<? extends AbstractBaseInfo> 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 <T> 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<Class<?>> classSet = getAllClassByAnnotation("com.h");
for (Class cls:classSet){
System.out.println(cls);
}
}
/**
* 取得某个包下所有实现这个接口的类
*/
public static Set<Class<?>> getAllClassByAnnotation(String packageName) {
List<Class<?>> classList =ClassUtil.getClasses(packageName) ;
Set<Class<?>> 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<Class> getAllClassByInterface(Class<?> c) {
List<Class> returnClassList = null;
if (c.isInterface()) {
// 获取当前的包名
String packageName = c.getPackage().getName();
// 获取当前包下以及子包下所以的类
List<Class<?>> allClass = getClasses(packageName);
if (allClass != null) {
returnClassList = new ArrayList<Class>();
for (Class<?>classes : 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<Class<?>> getClasses(String packageName) {
// 第一个class类的集合
List<Class<?>> classes = new ArrayList<Class<?>>();
// 是否循环迭代
boolean recursive = true;
// 获取包的名字 并进行替换
String packageDirName = packageName.replace('.', '/');
// 定义一个枚举的集合 并进行循环来处理这个目录下的things
Enumeration<URL> 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<JarEntry> 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<Class<?>> 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> T copy(Object poObj,final Class <T>voClass)
{
T voObj =null;
try {
voObj = voClass.newInstance();
BeanUtils.copyProperties(poObj, voObj);
return voObj;
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public static <T> List <T> copyList(List <? extends Object> poList ,final Class <T>voClass){
List<T> voList=new ArrayList<T>();
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<String> 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<String> 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<CoursewareRequest> coursewareList){
if (CollectionUtils.isNotEmpty(coursewareList)){
String courseId =coursewareList.get(0).getCourseId();
DBObject query = new BasicDBObject();
query.put("courseId",courseId);
query.put("deleted",0);
List<Courseware> list = mongoCommonDAO.getList(Courseware.class,query);
if (CollectionUtils.isNotEmpty(list)){
//批量更新删除状态
List<BatchUpdateRequest>updateList = 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;i<size;i++){
CoursewareRequest request = coursewareList.get(i);
Courseware courseware = new 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<CourseVO> getCourseList(List<String> courseIdList){
Map<String,Object> 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<Course> courseList = mongoCommonDAO.getList(Course.class,query);
return wrapCourse(courseList);
}