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:password@192.168.1.22: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)); }