本文实现一个通用泛型封装实现类,需要给定一个集合对象,类似mysql中与java对应的表;思想就是把给定的对象解析出所有非空字段,保存到一个BasicDBObject中,这里一定要保证java对象与mongodb中的文档字段名字一样,因为代码为了实现通用,是默认以java对象的字段为BasicDBObject的查询字段。
核心代码1:这是将java对象转换为查询条件。
/**
* 通过反射获取非空字段信息
* @param record
* @param <Q>
* @return
*/
private <Q> BasicDBObject getCondition(Q record) {
BasicDBObject cond = new BasicDBObject();
Class clazz = record.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
Object value = field.get(record);
if (value != null)
cond.put(field.getName(), value);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return cond;
}核心代码2:这是将查询到的文档转换为java对象,这里也是默认java对象的字段和数据库文档字段一样,也是利用java的反射动态获取用户自定义对象的所有字段,然后进行赋值,我在赋值过程中单独判断了int和long型,因为插入mongodb的时候一般是以double存的,这样就会造成转型错误。
/**
* 将结果转化为自定义对象
* @param document
* @param target
* @param <Q>
* @return
*/
private <Q> Q parseToObject(Document document, Class<Q> target) {
try {
Q result = target.newInstance();
Field[] fields = target.getDeclaredFields();
for (Field f : fields) {
f.setAccessible(true);
Object value = document.get(f.getName());
if (value == null)
continue;
else if (f.getType() == Integer.class)
f.set(result, ((Number) value).intValue());
else if (f.getType() == Long.class)
f.set(result, ((Number) value).longValue());
else
f.set(result, document.get(f.getName(), f.getType()));
}
return result;
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
} catch (InstantiationException e) {
e.printStackTrace();
return null;
}
}调用方法:先转换查询参数,查询的时候是以id来判断正序倒序,所以默认数据库中一定要有id的标识字段。
public <Q> List<Q> queryByCondition(BaseQuery<Q> query,boolean up) {
Q record = query.getQuery();
BasicDBObject cond = getCondition(record);
FindIterable<Document> findIterable;
if (query.getStart() != null && query.getRows() != null)
findIterable = thisCollection().find(cond)
.sort(new BasicDBObject("id", up ? 1 : -1))
.skip((query.getStart() - 1) * query.getRows())
.limit(query.getRows());
else
findIterable = thisCollection().find(cond)
.sort(new BasicDBObject("id", up ? 1 : -1));
MongoCursor<Document> iterator = findIterable.iterator();
List<Q> result = new ArrayList<>();
while (iterator.hasNext()) {
Document document = iterator.next();
result.add((Q) parseToObject(document, record.getClass()));
}
iterator.close();
return result;
}这里传入的BaseQuery如下:里面的query就是个需要查询的java对象,start&rows是为了用来分页的。这里是用到了lombok的插件,这样简化很多的gettter&setter等代码。
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Data
@Accessors(chain = true)
public class BaseQuery<Q> {
private Integer start;
private Integer rows;
private Q query;
public BaseQuery(Class clazz) {
try {
this.query = (Q) clazz.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}测试条件查询方法:这里用到的实体如下:
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class User_info {
private Integer id;
private String name;
private Integer age;
private Integer role;
}public static void main(String[] args) {
User_info record = new User_info();
BaseQuery<User_info> query = new BaseQuery<>();
query.setQuery(record);
BaseMongoDao dao = new BaseMongoDao("test");
List<User_info> result = dao.queryByCondition(query, true);
for (User_info user : result) {
System.out.println(user);
}
}因为这里用到的查询条件为空,所有会匹配数据库的所有项:

现在测试一下设置权限为1的数据:
public static void main(String[] args) {
User_info record = new User_info();
record.setRole(1);
BaseQuery<User_info> query = new BaseQuery<>();
query.setQuery(record);
BaseMongoDao dao = new BaseMongoDao("test");
List<User_info> result = dao.queryByCondition(query, true);
for (User_info user : result) {
System.out.println(user);
}
}输出:

这个条件查询方法是一个例子,其他的删除,增加,修改都是这个原理,下面带有:
1.public <Q> List<Q> queryByCondition(BaseQuery<Q> query,boolean up)
2.public <Q> Integer queryCoditionCount(BaseQuery<Q> query)
3.public <Q> boolean insertOne(Q record)
4.public <Q> boolean insertList(List<Q> records)
5.public boolean deleteById(Integer id)
6.public boolean deleteByIds(List<Integer> ids)
7.public <Q> void updateById(Q record)
放上所有代码:
package cn.wzy.dao;
import com.mongodb.*;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import org.bson.Document;
import org.cn.wzy.query.BaseQuery;
import org.cn.wzy.util.PropertiesUtil;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
/**
* Create by Wzy
* on 2018/7/28 18:15
* 不短不长八字刚好
*/
public class BaseMongoDao {
private static final MongoClient mongoClient;
private static final MongoDatabase mongo;
static {
MongoClientOptions options = MongoClientOptions.builder()
.connectionsPerHost(150)
.maxWaitTime(2000)
.socketTimeout(2000)
.maxConnectionLifeTime(5000)
.connectTimeout(5000).build();
ServerAddress serverAddress = new ServerAddress(PropertiesUtil.StringValue("mongo.host"),
PropertiesUtil.IntegerValue("mongo.port"));
List<ServerAddress> addrs = new ArrayList<>();
addrs.add(serverAddress);
MongoCredential credential = MongoCredential.createScramSha1Credential(
PropertiesUtil.StringValue("mongo.user")
, PropertiesUtil.StringValue("mongo.db")
, PropertiesUtil.StringValue("mongo.pwd").toCharArray());
mongoClient = new MongoClient(addrs, credential, options);
mongo = mongoClient.getDatabase(PropertiesUtil.StringValue("mongo.db"));
}
public BaseMongoDao(String colName) {
this.colName = colName;
}
private String colName;
private MongoCollection<Document> thisCollection() {
return mongo.getCollection(colName);
}
public <Q> List<Q> queryByCondition(BaseQuery<Q> query,boolean up) {
Q record = query.getQuery();
BasicDBObject cond = getCondition(record);
FindIterable<Document> findIterable;
if (query.getStart() != null && query.getRows() != null)
findIterable = thisCollection().find(cond)
.sort(new BasicDBObject("id", up ? 1 : -1))
.skip((query.getStart() - 1) * query.getRows())
.limit(query.getRows());
else
findIterable = thisCollection().find(cond)
.sort(new BasicDBObject("id", up ? 1 : -1));
MongoCursor<Document> iterator = findIterable.iterator();
List<Q> result = new ArrayList<>();
while (iterator.hasNext()) {
Document document = iterator.next();
result.add((Q) parseToObject(document, record.getClass()));
}
iterator.close();
return result;
}
public <Q> Integer queryCoditionCount(BaseQuery<Q> query) {
Q record = query.getQuery();
BasicDBObject cond = getCondition(record);
return (int) thisCollection().countDocuments(cond);
}
public <Q> boolean insertOne(Q record) {
BasicDBObject cond = getCondition(record);
try {
int top = getTop();
cond.put("id",++top);
thisCollection().insertOne(new Document(cond));
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public <Q> boolean insertList(List<Q> records) {
try {
List<Document> list = new ArrayList<>(records.size());
if (!changeIds(records))
return false;
for (Q record : records) {
list.add(new Document(getCondition(record)));
}
thisCollection().insertMany(list);
return true;
}catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean deleteById(Integer id) {
try {
if (id == null)
return false;
thisCollection().deleteOne(new BasicDBObject("id",id));
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
public boolean deleteByIds(List<Integer> ids) {
BasicDBObject cond = new BasicDBObject("id",new BasicDBObject("$in",ids.toArray()));
try {
thisCollection().deleteMany(cond);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 只通过id更改,查询就只是搜索id
* @param record
* @param <Q>
*/
public <Q> void updateById(Q record) {
BasicDBObject cond = getCondition(record);
BasicDBObject update = new BasicDBObject("$set",cond);
BasicDBObject query = new BasicDBObject("id",cond.get("id"));
thisCollection().updateOne(query,update);
}
/**
* 通过反射获取非空字段信息
* @param record
* @param <Q>
* @return
*/
private <Q> BasicDBObject getCondition(Q record) {
BasicDBObject cond = new BasicDBObject();
Class clazz = record.getClass();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
Object value = field.get(record);
if (value != null)
cond.put(field.getName(), value);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return cond;
}
/**
* 将结果转化为自定义对象
* @param document
* @param target
* @param <Q>
* @return
*/
private <Q> Q parseToObject(Document document, Class<Q> target) {
try {
Q result = target.newInstance();
Field[] fields = target.getDeclaredFields();
for (Field f : fields) {
f.setAccessible(true);
Object value = document.get(f.getName());
if (value == null)
continue;
else if (f.getType() == Integer.class)
f.set(result, ((Number) value).intValue());
else if (f.getType() == Long.class)
f.set(result, ((Number) value).longValue());
else
f.set(result, document.get(f.getName(), f.getType()));
}
return result;
} catch (IllegalAccessException e) {
e.printStackTrace();
return null;
} catch (InstantiationException e) {
e.printStackTrace();
return null;
}
}
/**
* 使id自增
* @param records
* @param <Q>
* @return
*/
private <Q> boolean changeIds(List<Q> records) {
if (records == null || records.size() == 0)
return false;
Class clazz = records.get(0).getClass();
try {
Field id = clazz.getDeclaredField("id");
id.setAccessible(true);
int top = getTop();
for (Q record: records) {
id.set(record,++top);
}
} catch (NoSuchFieldException e) {
e.printStackTrace();
return false;
} catch (IllegalAccessException e) {
e.printStackTrace();
return false;
}
return true;
}
/**
* 查找顶针
* @return
*/
private int getTop() {
return ((Number) thisCollection().find().sort(new BasicDBObject("id",-1)).first().get("id")).intValue();
}
}相关文章:
相关视频:
立即学习“Java免费学习笔记(深入)”;
以上就是java实现对mongodb,泛型封装增删查改、条件查询等操作的详细内容,更多请关注php中文网其它相关文章!
java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号