morphia操作mongodb
1.加入依赖
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>3.9.1</version>
</dependency>
<dependency>
<groupId>org.mongodb.morphia</groupId>
<artifactId>morphia</artifactId>
<version>1.3.2</version>
</dependency>2.配置 MongoClient
class MongoBase {
static MongoClient client;
/**
* MongoClient会自动创建连接池,因此,大部分情况下,整个JVM应用中只需要有一个MongoClient实例就可以。
*/
static {
try {
MongoClientURI clientURI = new MongoClientURI(
"mongodb://user::27017/admin");
client = new MongoClient(clientURI);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Datastore getDatastore() {
morphia = new Morphia();
Datastore datastore = morphia.createDatastore(client, "dbName");
return datastore;
}
static Morphia morphia;
}3. 集合MongDbOperator
import com.google.common.collect.ImmutableMap;
import com.mongodb.MongoClient;
import com.mongodb.MongoClientURI;
import com.ppmoney.g2.DateHelper;
import com.ppmoney.g2.common.PagedResult;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Key;
import org.mongodb.morphia.Morphia;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.Sort;
import org.mongodb.morphia.query.UpdateOperations;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
/**
* Created by zhangjy on 2018/11/28.
*/
public class MongDbOperator<T> {
private Class<T> tClass;
public MongDbOperator(Class<T> classz) {
this.tClass = classz;
}
public T getOne(ObjectId id) {
return getQueryFilter(id).get();
}
public T getOne(String id) {
return getQueryFilter(new ObjectId(id)).get();
}
public T getOne(Map<String, Object> filter) {
Assert.notNull(filter, "过滤条件不能为空");
Query<T> clientDevicesFilter = getQueryFilter(filter);
return clientDevicesFilter.get();
}
public T getOne(Map<String, Object> filter, Sort sort) {
Assert.notNull(filter, "过滤条件不能为空");
Query<T> queryFilter = getQueryFilter(filter);
queryFilter = queryFilter.order(sort);
return queryFilter.get();
}
/**
* 按访问时间倒序排列
*
* @param filter 过滤条件
* @param sort 排序条件
* @param limit 前几个(0:不限制)
*/
public List<T> list(Map<String, Object> filter, Sort sort, int limit) {
Query<T> queryFilter = getQueryFilter(filter);
if (sort != null) {
queryFilter = queryFilter.order(sort);
}
if (limit > 0) {
queryFilter = queryFilter.limit(limit);
}
return queryFilter.<T>asList();
}
/**
* 按访问时间倒序排列
*
* @param filter 过滤条件
* @param sort 排序条件
* @param limit 前几个(0:不限制)
*/
public long count(Map<String, Object> filter) {
Query<T> queryFilter = getQueryFilter(filter);
return count(queryFilter);
}
/**
* 分页查询
*
* @param filter 过滤条件
* @param sort 排序条件
* @param limit 前几个(0:不限制)
*/
public PagedResult<T> pagedList(Map<String, Object> filter, Sort sort, int pageIndex, int pageSize) {
Query<T> queryFilter = getQueryFilter(filter);
long count = count(queryFilter);
List<T> subItems = queryFilter.offset((pageIndex - 1) * pageSize).limit(pageSize).asList();
PagedResult<T> result = new PagedResult<T>(subItems, pageIndex, pageSize, (int) count);
return result;
}
/**
* 按访问时间倒序排列
*
* @param filter 过滤条件
*/
public List<T> list(Map<String, Object> filter) {
return list(filter, null, 0);
}
public ObjectId insert(T obj) {
Datastore datastore = MongoBase.getDatastore();
Key<T> save = datastore.save(obj);
return (ObjectId) (save.getId());
}
public int updateOne(String id, Map<String, Object> filedValues) {
return updateOne(new ObjectId(id), filedValues);
}
public int updateOne(ObjectId id, Map<String, Object> filedValues) {
Query<T> queryFilter = getQueryFilter(id);
return updateImpl(queryFilter, filedValues);
}
public int update(Map<String, Object> filter, Map<String, Object> filedValues) {
Query<T> queryFilter = getQueryFilter(filter);
return updateImpl(queryFilter, filedValues);
}
public boolean exists(Map<String, Object> filter) {
return getOne(filter) != null;
}
/**
* 删除
*
* @param filter 用户Id
*/
public int delete(String id) {
Query<T> queryFilter = getQueryFilter(new ObjectId(id));
return delete(queryFilter);
}
/**
* 删除
*
* @param filter 用户Id
*/
public int delete(ObjectId id) {
Query<T> queryFilter = getQueryFilter(id);
return delete(queryFilter);
}
/**
* 删除
*
* @param filter 用户Id
*/
public int delete(Map<String, Object> filter) {
Query<T> queryFilter = getQueryFilter(filter);
return delete(queryFilter);
}
/**
* 软删除
*
* @param filter 用户Id
*/
public int softDelete(Map<String, Object> filter) {
Query<T> clientDevicesFilter = getQueryFilter(filter);
UpdateOperations<T> updateOperations = getDeleteOperations();
return MongoBase.getDatastore().updateFirst(clientDevicesFilter, updateOperations, false).getUpdatedCount();
}
private long count(Query<T> queryFilter) {
return queryFilter.count();
}
/**
* 删除
*
* @param filter 用户Id
*/
private int delete(Query<T> queryFilter) {
return MongoBase.getDatastore().delete(queryFilter).getN();
}
private int updateImpl(Query<T> queryFilter, Map<String, Object> filedValues) {
Datastore datastore = MongoBase.getDatastore();
UpdateOperations<T> updateOperations = datastore.createUpdateOperations(tClass);
for (Map.Entry<String, Object> entry : filedValues.entrySet()) {
updateOperations.set(entry.getKey(), entry.getValue());
}
return datastore.update(queryFilter, updateOperations, false).getUpdatedCount();
}
private Query<T> getQueryFilter(ObjectId id) {
return getQueryFilter(ImmutableMap.of("_id", id));
}
private Query<T> getQueryFilter(Map<String, Object> filter) {
Query<T> query = MongoBase.getDatastore().createQuery(this.tClass);
if (CollectionUtils.isEmpty(filter)) {
return query;
}
for (Map.Entry<String, Object> entry : filter.entrySet()) {
query = query.filter(entry.getKey(), entry.getValue());
}
return query;
}
private UpdateOperations<T> getUpdateOperations(Map<String, Object> filedValues) {
UpdateOperations<T> updateOperations = MongoBase.getDatastore().createUpdateOperations(this.tClass);
updateOperations.inc("version");
updateOperations.set("lastModifyTime", System.currentTimeMillis());
for (Map.Entry<String, Object> entry : filedValues.entrySet()) {
updateOperations.set(entry.getKey(), entry.getValue());
}
return updateOperations;
}
private UpdateOperations<T> getDeleteOperations() {
return getUpdateOperations(ImmutableMap.of("deleted", true));
}
}4.增加model
import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import lombok.Data;
/**
* Created by zhangjy on 2018/11/30.
*/
@Data
@Entity(noClassnameStored = true)
public abstract class BaseMongDbModel {
/**
* mongDb的 id
*/
@Id
private ObjectId id;
/**
* 是否已(软)删除
*/
private boolean deleted;
/**
* 创建时间
*/
private long createTime;
/**
* 最后修改时间
*/
private long lastModifyTime;
/**
* 版本号
*/
private int version;
}@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class LoginRecord extends BaseMongDbModel {
private Integer userId;
private String phone;
private String loginIp;
private Long loginTime;
private String platform;
private String deviceId;
@Override
public String toString() {
return super.toString()+"LoginRecord{" +
"customerId=" + userId +
", phone=‘" + phone + ‘\‘‘ +
", loginIp=‘" + loginIp + ‘\‘‘ +
", loginTime=" + loginTime +
", platform=‘" + platform + ‘\‘‘ +
", deviceId=‘" + deviceId + ‘\‘‘ +
‘}‘;
}
}5.其他辅助类
public class SimplePagedList {
private static final int DEFALUT_PAGE_SIZE = 10;
private int pageSize;
private int totalCount;
private int firstPageIndex;
public SimplePagedList(int totalCount, int pageSize) {
this(totalCount, pageSize, 1);
}
public SimplePagedList(int totalCount, int pageSize, int firstPageIndex) {
this.pageSize = pageSize <= 0?10:pageSize;
this.totalCount = totalCount;
this.firstPageIndex = firstPageIndex;
}
public int getPageCount() {
return this.totalCount % this.pageSize == 0?this.totalCount / this.pageSize:this.totalCount / this.pageSize + 1;
}
public int getStartIndex(int pageIndex) {
if(pageIndex < this.firstPageIndex) {
throw new IllegalArgumentException("pageIndex不合法");
} else {
return (pageIndex - 1) * this.pageSize + 1;
}
}
public int getEndIndex(int pageIndex) {
if(pageIndex < this.firstPageIndex) {
throw new IllegalArgumentException("pageIndex不合法");
} else {
return pageIndex * this.pageSize;
}
}
}import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import lombok.Data;
@Data
public class PagedResult<T> {
private static final int DEFALUT_PAGE_SIZE = 10;
private boolean hasNextPage;
private boolean hasPreviousPage;
private List<T> items;
private int pageIndex;
private int pageSize;
private int totalCount;
private int totalPages;
public PagedResult() {
}
public PagedResult(List<T> subItems, int pageIndex, int pageSize, int totalCount) {
if(pageSize <= 0) {
throw new IllegalArgumentException("pageSize非法");
} else {
this.init(subItems, pageIndex, pageSize, totalCount);
}
}
public PagedResult(List<T> source, int pageIndex, int pageSize, Predicate<T> function) {
if(pageSize <= 0) {
throw new IllegalArgumentException("pageSize非法");
} else {
List<T> filtedItems = source.stream().filter(function).collect(Collectors.toList());
int count = filtedItems.size();
SimplePagedList simplePagedList = new SimplePagedList(count, pageSize);
List<T> subItems = filtedItems.stream().skip((long)simplePagedList.getStartIndex(pageIndex) - 1L).limit((long)pageSize).collect(Collectors.toList());
this.init(subItems, pageIndex, pageSize, count);
}
}
public PagedResult(List<T> source, int pageIndex, int pageSize) {
this(source, pageIndex, pageSize, (m) -> {
return true;
});
}
private void init(List<T> subItems, int pageIndex, int pageSize, int totalCount) {
if(pageIndex == 0) {
this.hasNextPage = false;
} else {
this.hasNextPage = pageIndex * pageSize < totalCount;
}
this.hasPreviousPage = pageIndex > 1 && totalCount > 0;
this.pageIndex = pageIndex;
this.pageSize = pageSize;
this.totalCount = totalCount;
this.totalPages = totalCount % pageSize == 0?totalCount / pageSize:totalCount / pageSize + 1;
this.items = subItems;
}
@Override
public String toString() {
return "PagedResult(hasNextPage=" + this.isHasNextPage() + ", hasPreviousPage=" + this.isHasPreviousPage() + ", items=" + this.getItems() + ", pageIndex=" + this.getPageIndex() + ", pageSize=" + this.getPageSize() + ", totalCount=" + this.getTotalCount() + ", totalPages=" + this.getTotalPages() + ")";
}
}7.测试代码
public static void main(String[] args) {
MongDbOperator<LoginRecord> operator = new MongDbOperator<>(LoginRecord.class);
LoginRecord model;
List<LoginRecord> models;
int cutomerId = 50000133;
// 1.普通查询(根据id查询)
model = operator.getOne("5e1444b0b58fe60001fcd4eb");
System.out.println(String.format("根据id获取mode,结果为:%s", model.toString()));
// 2.普通查询(根据业务主键查询)
model = operator.getOne(ImmutableMap.of("userId", cutomerId));
System.out.println(String.format("根据业务主键customerId获取mode,结果为:%s", model));
// 3.普通查询(根据业务查询)
models = operator.list(ImmutableMap.of("platform", "app"));
System.out.println(String.format("根据业务platform获取mode集合,结果为:%s", models));
// 4.模糊查询(根据正则匹配)
models = operator.list(ImmutableMap.of("phone", Pattern.compile("^158*")));
System.out.println(String.format("获取186开头的手机号的登陆记录集合,结果为:%s", models));
// 5.区间查询
models = operator.list(ImmutableMap.<String, Object>builder()
.put("loginTime >=", DateHelper.toTimeStamp(LocalDateTime.of(2019, 1, 1, 0, 0, 0)))
.put("loginTime <", DateHelper.toTimeStamp(LocalDateTime.of(2021, 1, 1, 0, 0, 0)))
.build());
System.out.println(String.format("获取2019年所有用户登陆记录集合,结果为:%s", models));
//6.分页查询
PagedResult<LoginRecord> models2 = operator.pagedList(ImmutableMap.of(), Sort.ascending("_id"), 1, 10);
System.out.println(String.format("获取2019年所有用户登陆记录集合,结果为:%s", models2));
//7.新增记录
model = new LoginRecord();
model.setUserId(cutomerId);
model.setDeviceId("Q100000");
model.setLoginIp("186.26.56.25");
model.setPhone("18626562155");
model.setPlatform("app");
long second = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).getEpochSecond();
model.setLoginTime(second);
ObjectId id = operator.insert(model);
System.out.println(String.format("新增记录,新增id为:%s", id));
}