java操作mongodb & springboot整合mongodb
简单的研究原生API操作MongoDB以及封装的工具类操作,最后也会研究整合spring之后作为dao层的完整的操作。
1.原生的API操作
pom.xml
<!-- https://mvnrepository.com/artifact/org.mongodb/mongodb-driver --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver</artifactId> <version>3.10.1</version> </dependency>
测试类:
package mongodb; import java.util.ArrayList; import java.util.List; import org.bson.Document; import com.mongodb.MongoClient; import com.mongodb.client.FindIterable; import com.mongodb.client.ListCollectionsIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; import com.mongodb.client.model.Filters; public class Demo { public static void main(String[] args) { } private static void deleteDoc() { try { // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient("localhost", 27017); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("test"); System.out.println("Connect to database successfully"); MongoCollection<Document> collection = mongoDatabase.getCollection("test"); System.out.println("集合 test 选择成功"); collection.deleteOne(Filters.eq("likes", 200)); // 删除所有符合条件的文档 collection.deleteMany(Filters.eq("likes", 200)); // 检索查看结果 FindIterable<Document> findIterable = collection.find(); MongoCursor<Document> mongoCursor = findIterable.iterator(); while (mongoCursor.hasNext()) { System.out.println(mongoCursor.next()); } } catch (Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); } } private static void updateDocument() { try { // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient("localhost", 27017); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("test"); System.out.println("Connect to database successfully"); MongoCollection<Document> collection = mongoDatabase.getCollection("test"); System.out.println("集合 test 选择成功"); // 更新文档 将文档中likes=100的文档修改为likes=200 collection.updateMany(Filters.eq("likes", 100), new Document("$set", new Document("likes", 200))); // 检索查看结果 FindIterable<Document> findIterable = collection.find(); MongoCursor<Document> mongoCursor = findIterable.iterator(); while (mongoCursor.hasNext()) { System.out.println(mongoCursor.next()); } } catch (Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); } } private static void queryDocument() { try { // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient("localhost", 27017); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("test"); System.out.println("Connect to database successfully"); MongoCollection<Document> collection = mongoDatabase.getCollection("test"); System.out.println("集合 test 选择成功"); // 检索所有文档 /** * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor<Document> 3. * 通过游标遍历检索出的文档集合 */ FindIterable<Document> findIterable = collection.find(); MongoCursor<Document> mongoCursor = findIterable.iterator(); while (mongoCursor.hasNext()) { System.out.println(mongoCursor.next()); } } catch (Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); } } private static void insertDoc() { try { // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient("localhost", 27017); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("test"); System.out.println("Connect to database successfully"); MongoCollection<Document> collection = mongoDatabase.getCollection("test"); System.out.println("集合 test 选择成功"); // 插入文档 /** * 1. 创建文档 org.bson.Document 参数为key-value的格式 2. 创建文档集合List * <Document> 3. 将文档集合插入数据库集合中 mongoCollection.insertMany(List * <Document>) 插入单个文档可以用 mongoCollection.insertOne(Document) */ Document document = new Document("title", "MongoDB").append("description", "database").append("likes", 100) .append("by", "Fly"); List<Document> documents = new ArrayList<Document>(); documents.add(document); collection.insertMany(documents); System.out.println("文档插入成功"); } catch (Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); } } private static void getConnection() { try { // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient("localhost", 27017); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("test"); System.out.println("Connect to database successfully"); // 获取所有的集合 ListCollectionsIterable<Document> listCollections = mongoDatabase.listCollections(); MongoCursor<Document> iterator = listCollections.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } MongoCollection<Document> collection = mongoDatabase.getCollection("test"); System.out.println("集合 test 选择成功"); } catch (Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); } } private static void createCollection() { try { // 连接到 mongodb 服务// 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient("localhost", 27017); // 连接到数据库// 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("test"); System.out.println("Connect to database successfully"); mongoDatabase.createCollection("test"); System.out.println("集合创建成功"); } catch (Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); } } private static void connectNoPassword() { try { // 连接到 mongodb 服务 MongoClient mongoClient = new MongoClient("localhost", 27017); // 连接到数据库 MongoDatabase mongoDatabase = mongoClient.getDatabase("test"); System.out.println("Connect to database successfully"); } catch (Exception e) { System.err.println(e.getClass().getName() + ": " + e.getMessage()); } } }
2.封装成工具类的操作
pom.xml
<dependencies> <!-- https://mvnrepository.com/artifact/org.mongodb/mongodb-driver --> <dependency> <groupId>org.mongodb</groupId> <artifactId>mongodb-driver</artifactId> <version>3.10.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.7</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.7</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.2</version> </dependency> </dependencies>
package Utils; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mongodb.MongoClient; import com.mongodb.client.MongoDatabase; public class MongoHelper { private static final Logger logger = LoggerFactory.getLogger(MongoHelper.class); static final String DBName = "test"; static final String ServerAddress = "127.0.0.1"; static final int PORT = 27017; private MongoHelper() { } private static MongoClient mongoClient = new MongoClient(ServerAddress, PORT); // 模拟连接池(阻塞队列) private static LinkedBlockingQueue<MongoDatabase> mongoDatabases = new LinkedBlockingQueue<MongoDatabase>(5); static { initMongoDatabases(); } private static void initMongoDatabases() { for (int i = 0; i < 5; i++) { MongoDatabase mDatabase = mongoClient.getDatabase(DBName); mongoDatabases.add(mDatabase); } } public static void closeMongoClient(MongoDatabase mongoDatabase) { mongoDatabases.add(mongoDatabase); logger.debug("CloseMongoClient successfully"); } public static MongoDatabase getMongoDataBase() { try { MongoDatabase mDatabase = mongoDatabases.take(); return mDatabase; } catch (InterruptedException e) { e.printStackTrace(); return null; } } }
package Utils; import java.util.List; import java.util.Map; import org.bson.Document; import com.mongodb.BasicDBObject; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoDatabase; /** * MongoDB数据操作接口 * */ public interface MongoDao { /** * 根据id检索文档 * * @param db * @param table * @param id * @return * @throws Exception */ public Map<String, Object> queryByID(MongoDatabase db, String table, Object id) throws Exception; /** * 根据doc检索文档集合,当doc是空的时候检索全部 * * @param db * @param table * @param doc * @return * @throws Exception */ public List<Map<String, Object>> queryByDoc(MongoDatabase db, String table, BasicDBObject doc) throws Exception; /** * 检索全部返回集合 * * @param db * @param table * @return * @throws Exception */ public List<Map<String, Object>> queryAll(MongoDatabase db, String table) throws Exception; /** * 遍历迭代器返回文档集合 * * @param iterable * @return * @throws Exception */ public List<Document> findIterable(FindIterable<Document> iterable) throws Exception; /** * 插入文档 * * @param db * @param table * @param doc * @return * @throws Exception */ public boolean insert(MongoDatabase db, String table, Document doc) throws Exception; /** * 插入多条文档 * * @param db * @param table * @param doc * @return * @throws Exception */ public boolean insertMany(MongoDatabase db, String table, List<Document> doc) throws Exception; /** * 删除文档 * * @param db * @param table * @param doc * @return * @throws Exception */ public boolean delete(MongoDatabase db, String table, BasicDBObject doc) throws Exception; /** * 删除单条文档 * * @param db * @param table * @param doc * @return * @throws Exception */ public boolean deleteOne(MongoDatabase db, String table, BasicDBObject doc) throws Exception; /** * 修改文档 * * @param db * @param table * @param oldDoc * @param newDoc * @return * @throws Exception */ public boolean update(MongoDatabase db, String table, BasicDBObject oldDoc, BasicDBObject newDoc) throws Exception; /** * 修改单条文档 * * @param db * @param table * @param whereDoc * @param updateDoc * @return * @throws Exception */ public boolean updateOne(MongoDatabase db, String table, BasicDBObject whereDoc, BasicDBObject updateDoc) throws Exception; /** * 创建集合 * * @param db * @param table * @throws Exception */ public void createCol(MongoDatabase db, String table) throws Exception; /** * 删除集合 * * @param db * @param table * @throws Exception */ public void dropCol(MongoDatabase db, String table) throws Exception; }
package Utils; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.bson.Document; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.mongodb.BasicDBObject; import com.mongodb.client.FindIterable; import com.mongodb.client.MongoCollection; import com.mongodb.client.MongoCursor; import com.mongodb.client.MongoDatabase; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; /** * MongoDB数据操作实现类 * */ public class MongoDaoImpl implements MongoDao { private static final Logger logger = LoggerFactory.getLogger(MongoDaoImpl.class); public Map<String, Object> queryByID(MongoDatabase db, String table, Object id) throws Exception { MongoCollection<Document> collection = db.getCollection(table); BasicDBObject query = new BasicDBObject("_id", id); // DBObject接口和BasicDBObject对象:表示一个具体的记录,BasicDBObject实现了DBObject,是key-value的数据结构,用起来和HashMap是基本一致的。 FindIterable<Document> iterable = collection.find(query); Map<String, Object> jsonStrToMap = null; MongoCursor<Document> cursor = iterable.iterator(); while (cursor.hasNext()) { Document user = cursor.next(); String jsonString = user.toJson(); jsonStrToMap = JsonStrToMap.jsonStrToMap(jsonString);// 这里用到我自己写的方法,主要是包json字符串转换成map格式,为后面做准备,方法放在后面 } logger.debug("检索ID完毕,db:{},table:{},id:{} ", db.getName(), table, id); return jsonStrToMap; } public List<Map<String, Object>> queryByDoc(MongoDatabase db, String table, BasicDBObject doc) throws Exception { MongoCollection<Document> collection = db.getCollection(table); FindIterable<Document> iterable = collection.find(doc); /** * 1. 获取迭代器FindIterable<Document> 2. 获取游标MongoCursor * <Document> 3.通过游标遍历检索出的文档集合 */ List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); MongoCursor<Document> cursor = iterable.iterator(); while (cursor.hasNext()) { Document user = cursor.next(); String jsonString = user.toJson(); Map<String, Object> jsonStrToMap = JsonStrToMap.jsonStrToMap(jsonString); list.add(jsonStrToMap); } logger.debug("检索doc完毕,db:{},table:{},doc:{} ", db.getName(), table, doc.toJson()); return list; } public List<Map<String, Object>> queryAll(MongoDatabase db, String table) throws Exception { MongoCollection<Document> collection = db.getCollection(table); FindIterable<Document> iterable = collection.find(); List<Map<String, Object>> list = new ArrayList<Map<String, Object>>(); MongoCursor<Document> cursor = iterable.iterator(); while (cursor.hasNext()) { Document user = cursor.next(); String jsonString = user.toJson(); Map<String, Object> jsonStrToMap = JsonStrToMap.jsonStrToMap(jsonString); list.add(jsonStrToMap); } logger.debug("检索全部完毕,db:{},table:{}", db.getName(), table); return list; } public List<Document> findIterable(FindIterable<Document> iterable) throws Exception { List<Document> list = new ArrayList<Document>(); MongoCursor<Document> cursor = iterable.iterator(); while (cursor.hasNext()) { Document doc = cursor.next(); list.add(doc); } cursor.close(); return list; } public boolean insert(MongoDatabase db, String table, Document doc) throws Exception { MongoCollection<Document> collection = db.getCollection(table); collection.insertOne(doc); long count = collection.count(doc); if (count >= 1) { logger.debug("文档插入成功,影响条数:{},db:{},table:{},doc:{} ", count, db.getName(), table, doc.toJson()); return true; } else { logger.debug("文档插入失败,影响条数:{},db:{},table:{},doc:{} ", count, db.getName(), table, doc.toJson()); return false; } } public boolean insertMany(MongoDatabase db, String table, List<Document> doc) throws Exception { MongoCollection<Document> collection = db.getCollection(table); long preCount = collection.count(); collection.insertMany(doc); long nowCount = collection.count(); if ((nowCount - preCount) == doc.size()) { logger.debug("文档插入成功,影响条数:{},db:{},table:{}", doc.size(), db.getName(), table); return true; } else { logger.debug("文档插入失败,影响条数:{},db:{},table:{}", (nowCount - preCount), db.getName(), table); return false; } } public boolean delete(MongoDatabase db, String table, BasicDBObject doc) throws Exception { MongoCollection<Document> collection = db.getCollection(table); DeleteResult deleteManyResult = collection.deleteMany(doc); long deletedCount = deleteManyResult.getDeletedCount(); if (deletedCount > 0) { logger.debug("文档删除成功,影响条数:{},db:{},table:{},doc:{} ", deletedCount, db.getName(), table, doc.toJson()); return true; } else { logger.debug("文档删除失败,影响条数:{},db:{},table:{},doc:{} ", 0, db.getName(), table, doc.toJson()); return false; } } public boolean deleteOne(MongoDatabase db, String table, BasicDBObject doc) throws Exception { MongoCollection<Document> collection = db.getCollection(table); DeleteResult deleteOneResult = collection.deleteOne(doc); long deletedCount = deleteOneResult.getDeletedCount(); System.out.println("删除的数量: " + deletedCount); if (deletedCount == 1) { logger.debug("文档删除成功,影响条数:{},db:{},table:{},doc:{} ", deletedCount, db.getName(), table, doc.toJson()); return true; } else { logger.debug("文档删除失败,影响条数:{},db:{},table:{},doc:{} ", 0, db.getName(), table, doc.toJson()); return false; } } public boolean update(MongoDatabase db, String table, BasicDBObject whereDoc, BasicDBObject updateDoc) throws Exception { MongoCollection<Document> collection = db.getCollection(table); UpdateResult updateManyResult = collection.updateMany(whereDoc, new Document("$set", updateDoc)); long modifiedCount = updateManyResult.getModifiedCount(); System.out.println("修改的数量: " + modifiedCount); if (modifiedCount > 0) { logger.debug("文档更新成功,影响条数:{},db:{},table:{},whereDoc:{},updateDoc:{} ", modifiedCount, db.getName(), table, whereDoc.toJson(), updateDoc.toJson()); return true; } else { logger.debug("文档更新成功,影响条数:{},db:{},table:{},whereDoc:{},updateDoc:{} ", 0, db.getName(), table, whereDoc.toJson(), updateDoc.toJson()); return false; } } public boolean updateOne(MongoDatabase db, String table, BasicDBObject whereDoc, BasicDBObject updateDoc) throws Exception { MongoCollection<Document> collection = db.getCollection(table); UpdateResult updateOneResult = collection.updateOne(whereDoc, new Document("$set", updateDoc)); long modifiedCount = updateOneResult.getModifiedCount(); System.out.println("修改的数量: " + modifiedCount); if (modifiedCount == 1) { logger.debug("文档更新成功,影响条数:{},db:{},table:{},whereDoc:{},updateDoc:{} ", 1, db.getName(), table, whereDoc.toJson(), updateDoc.toJson()); return true; } else { logger.debug("文档更新成功,影响条数:{},db:{},table:{},whereDoc:{},updateDoc:{} ", 0, db.getName(), table, whereDoc.toJson(), updateDoc.toJson()); return false; } } public void createCol(MongoDatabase db, String table) throws Exception { db.createCollection(table); logger.debug("集合创建成功,db:{},table:{}", db.getName(), table); } public void dropCol(MongoDatabase db, String table) throws Exception { db.getCollection(table).drop(); logger.debug("集合删除成功,db:{},table:{}", db.getName(), table); } }
package Utils; import java.util.HashMap; import java.util.Map; import com.mongodb.util.JSON; public class JsonStrToMap { /** * json 字符串转化为map格式 * * @param jsonString * @return */ public static Map<String, Object> jsonStrToMap(String jsonString) { Object parseObj = JSON.parse(jsonString); // 反序列化 把json 转化为对象 Map<String, Object> map = (HashMap<String, Object>) parseObj; // 把对象转化为map return map; } }
测试类:
package mongodb; import java.util.List; import java.util.Map; import org.bson.Document; import com.mongodb.client.MongoDatabase; import Utils.MongoDao; import Utils.MongoDaoImpl; import Utils.MongoHelper; public class UtilsTest { public static void main(String[] args) throws Exception { // 增加文档 MongoDao mongoDao = new MongoDaoImpl(); String table = "test"; for (int i = 0; i < 6; i++) { MongoDatabase db = MongoHelper.getMongoDataBase(); List<Map<String, Object>> queryAll = mongoDao.queryAll(db, "test"); System.out.println(queryAll); } } private static void insertDoc(MongoDatabase db, MongoDao mongoDao, String table) throws Exception { Document document = new Document("title222", "MongoDB222").append("description", "database") .append("likes", 100).append("by", "Fly"); mongoDao.insert(db, table, document); } }
结果会打印五次结果,并且阻塞一次。
上面代码改为下面即可正常打印6次:
for (int i = 0; i < 6; i++) { MongoDatabase db = MongoHelper.getMongoDataBase(); List<Map<String, Object>> queryAll = mongoDao.queryAll(db, "test"); System.out.println(queryAll); MongoHelper.closeMongoClient(db); }
3.springboot整合mongoDB的使用
pom.xml文件引入自动整合的jar包:
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-mongodb --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> <version>2.1.4.RELEASE</version> </dependency>
application.properties文件引入相关的配置
##mongodb相关配置
spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.port=27017
spring.data.mongodb.database=mydb
spring.data.mongodb.username=admin
spring.data.mongodb.password=admin
相关配置的类在 MongoDataAutoConfiguratio 类中。
注意:上面是需要账户和密码的用户的配置方式,其用户和密码是在mongodb的admin数据库中创建的用户(这点有点类似于mysql),语句如下:
> use admin switched to db admin > db.createUser({"user":"root",pwd:"123456",roles:[{role:"root",db:"admin"}]}) Successfully added user: { "user" : "root", "roles" : [ { "role" : "root", "db" : "admin" } ] }
实体类User.java
package cn.qs.bean.user; import org.springframework.data.annotation.Id; import java.util.Date; public class User { @Id private Integer id; private String username; private String password; private String fullname; private String sex; private String phone; private String email; private Date createtime; private Date updatetime; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username == null ? null : username.trim(); } public String getPassword() { return password; } public void setPassword(String password) { this.password = password == null ? null : password.trim(); } public String getFullname() { return fullname; } public void setFullname(String fullname) { this.fullname = fullname == null ? null : fullname.trim(); } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex == null ? null : sex.trim(); } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone == null ? null : phone.trim(); } public String getEmail() { return email; } public void setEmail(String email) { this.email = email == null ? null : email.trim(); } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } public Date getUpdatetime() { return updatetime; } public void setUpdatetime(Date updatetime) { this.updatetime = updatetime; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", fullname='" + fullname + '\'' + ", sex='" + sex + '\'' + ", phone='" + phone + '\'' + ", email='" + email + '\'' + ", createtime=" + createtime + ", updatetime=" + updatetime + '}'; } }
UserDao.java
package cn.qs.dao; import cn.qs.bean.user.User; import cn.qs.bean.user.UserExample; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.List; /** * @Author: qlq * @Description * @Date: 22:06 2019/4/8 */ public interface UserDao { void insert(User record); void deleteByPrimaryKey(Integer id); void updateByPrimaryKeySelective(User record); void updateByPrimaryKey(User record); List<User> selectUsers(); }
UserDaoImpl.java( mongoTemplate 封装了好多方法,其中还包括查询并删除等方法 )
package cn.qs.dao; import cn.qs.bean.user.User; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.query.Update; import org.springframework.stereotype.Component; import java.util.List; /** * @Author: qlq * @Description * @Date: 22:18 2019/4/8 */ @Component public class UserDaoImpl implements UserDao { @Autowired private MongoTemplate mongoTemplate; @Override public void insert(User record) { mongoTemplate.save(record); } @Override public void deleteByPrimaryKey(Integer id) { Query query=new Query(Criteria.where("id").is(id)); mongoTemplate.remove(query,User.class); } @Override public void updateByPrimaryKeySelective(User record) { Query query=new Query(Criteria.where("id").is(record.getId())); Update update= new Update().set("fullname", record.getFullname()).set("username", record.getUsername()); //更新查询返回结果集的第一条 mongoTemplate.updateFirst(query,update,User.class); //更新查询返回结果集的所有 // mongoTemplate.updateMulti(query,update,User.class); } @Override public void updateByPrimaryKey(User record) { } @Override public List<User> selectUsers() { Query query=new Query(Criteria.where("fullname").is("张三")); //查询单个 // User user = mongoTemplate.findOne(query , User.class); List<User> users = mongoTemplate.find(query,User.class); return users; } }
UserMongoDbController.java(这里测试直接注入dao)
package cn.qs.controller.user; import cn.qs.bean.user.User; import cn.qs.dao.UserDao; import cn.qs.service.user.UserService; import cn.qs.utils.DefaultValue; import cn.qs.utils.JSONResultUtil; import cn.qs.utils.MD5Util; import cn.qs.utils.ValidateCheck; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.apache.commons.collections.MapUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; @RestController /** 自动返回的是json格式数据 ***/ @RequestMapping("userMon") public class UserMongoDbController { private static final Logger logger = LoggerFactory.getLogger(UserMongoDbController.class); @Autowired private UserDao userDao; @RequestMapping("/insert") public String insert(User record){ for(int i=0;i<10;i++){ User user = new User(); user.setId(i+1); user.setFullname("张三"); user.setUsername("zhangsan"); userDao.insert(user); } return "s"; } @RequestMapping("/deleteByPrimaryKey") public String deleteByPrimaryKey(Integer id){ return "s"; } @RequestMapping("/updateByPrimaryKeySelective") public String updateByPrimaryKeySelective(User record){ return "s"; } @RequestMapping("/updateByPrimaryKey") public String updateByPrimaryKey(User record){ return "s"; } @RequestMapping("/selectUsers") public List<User> selectUsers(){ return userDao.selectUsers(); } }
启动之后调用增加的方法然后查看mongodb的数据信息:(User的ID做为mongodb的docid)
补充:还有第二种方式是使用继承 MongoRepository 的方式(=========SpringData的用法=========)
这种方式可以实现判断用户是否存在,可以排序查询以及分页查询等,而且这种方式支持自定义方法查询。下面介绍其用法:
例如:编写User的dao层接口,不用写实现
package cn.qs.dao.user; import cn.qs.bean.user.User; import org.springframework.data.mongodb.repository.MongoRepository; /** * @Author: qlq * @Description * @Date: 14:29 2019/4/14 */ public interface UserRepository extends MongoRepository<User, Integer> { }
测试代码:
package tourism; import cn.qs.MySpringBootApplication; import cn.qs.bean.user.User; import cn.qs.dao.user.UserRepository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.domain.Example; import org.springframework.data.domain.ExampleMatcher; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.test.context.junit4.SpringRunner; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * @Author: qlq * @Description * @Date: 15:21 2019/4/14 */ @RunWith(SpringRunner.class) @SpringBootTest(classes = MySpringBootApplication.class) public class MongoDBTest { @Autowired private UserRepository userRepository;
}
(1)测试基本的增删改查:
- 增加:
@Test public void insert() { for(int i=0;i<5;i++){ User user = new User(); user.setId(i+1); user.setFullname("张三"); user.setUsername("zhangsan"); userRepository.insert(user); } }
结果:
- 删除
@Test public void delete() { //删除所有 // userRepository.deleteAll(); //删除单个 userRepository.delete(1); //删除单个 User user = new User(); user.setId(2); userRepository.delete(user); }
结果:
- 修改(比如修改ID为3的用户信息)
@Test public void update(){ User user = userRepository.findOne(3); user.setFullname("修改后的值"); userRepository.save(user); }
结果:
- 查询
@Test public void findAll(){ //不带查询条件 List<User> list = userRepository.findAll(); System.out.println(list); //带查询条件(根据ID集合查询) List<Integer> ids = new ArrayList<>(3); ids.add(3); ids.add(4); ids.add(5); List<User> list2 = (List<User>) userRepository.findAll(ids); System.out.println(list2); } @Test public void findOne(){ //根据ID查询 User user = userRepository.findOne(3); System.out.println(user); }
(2)测试 Example 类的用法:
Example类可以用于条件筛选,可以对查询你单个进行过滤,也可以对批量查询过滤。
查询 fullname 以修改开头的用户信息:(查询单个)
@Test public void exampleUse() { User user = new User(); user.setFullname("修改"); user.setUsername("xxxxxx"); ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("fullname",ExampleMatcher.GenericPropertyMatchers.startsWith())//查询以修改开头 .withIgnorePaths("username");//忽略username属性 Example example = Example.of(user,matcher); User user2 = userRepository.findOne(example); System.out.println("user2"+user2); }
结果:
user2User{id=3, username='zhangsan', password='null', fullname='修改后的值', sex='null', phone='null', email='null', createtime=null, updatetime=null}
查询集合:查询username包含zhang的用户集合:
@Test public void exampleUse() { User user = new User(); user.setFullname("xxx"); user.setUsername("zhang"); ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("username",ExampleMatcher.GenericPropertyMatchers.contains())//查询username包含zhang .withIgnorePaths("fullname");//忽略fullname属性 Example example = Example.of(user,matcher); List<User> users = userRepository.findAll(example); System.out.println(users); }
结果:
[User{id=3, username='zhangsan', password='null', fullname='修改后的值', sex='null', phone='null', email='null', createtime=null, updatetime=null}, User{id=4, username='zhangsan', password='null', fullname='张三', sex='null', phone='null', email='null', createtime=null, updatetime=null}, User{id=5, username='zhangsan', password='null', fullname='张三', sex='null', phone='null', email='null', createtime=null, updatetime=null}]
(3)分页查询(注意页号从0开始,不带条件查询)
PagingAndSortingRepository 接口中的分页方法,也可以进行分页排序,但是不具备条件过滤功能:
@Test public void pageFind() { //构造请求参数,页号从0开始。 PageRequest pageRequest = new PageRequest(0,2); Page<User> page = userRepository.findAll(pageRequest); System.out.println("总数:"+page.getTotalElements()); System.out.println("总页数:"+page.getTotalPages()); System.out.println(page.getContent()); }
结果:
总数:3
总页数:2
[User{id=3, username='zhangsan', password='null', fullname='修改后的值', sex='null', phone='null', email='null', createtime=null, updatetime=null}, User{id=4, username='zhangsan', password='null', fullname='张三', sex='null', phone='null', email='null', createtime=null, updatetime=null}]
增加id逆序查询:
@Test public void pageFind() { //构造排序 List<Sort.Order> orders = new ArrayList<Sort.Order>(); orders.add(new Sort.Order(Sort.Direction.DESC, "id")); Sort sort = new Sort(orders); //构造请求参数,页号从0开始。 PageRequest pageRequest = new PageRequest(0,2,sort); Page<User> page = userRepository.findAll(pageRequest); System.out.println("总数:"+page.getTotalElements()); System.out.println("总页数:"+page.getTotalPages()); System.out.println(page.getContent()); }
结果:
总数:3
总页数:2
[User{id=5, username='zhangsan', password='null', fullname='张三', sex='null', phone='null', email='null', createtime=null, updatetime=null}, User{id=4, username='zhangsan', password='null', fullname='张三', sex='null', phone='null', email='null', createtime=null, updatetime=null}]
(4)分页查询带条件:
QueryByExampleExecutor接口的方法。
@Test public void pageFind() { User user = new User(); user.setFullname("修改"); user.setUsername("xxx"); ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("fullname",ExampleMatcher.GenericPropertyMatchers.contains())//查询fullname包含修改 .withIgnorePaths("username");//忽略username属性 Example example = Example.of(user,matcher); //构造请求参数,页号从0开始。 Pageable pageRequest = new QPageRequest(0,2); Page<User> page = userRepository.findAll(example,pageRequest); System.out.println("总数:"+page.getTotalElements()); System.out.println("总页数:"+page.getTotalPages()); System.out.println(page.getContent()); }
结果:
总数:1
总页数:1
[User{id=3, username='zhangsan', password='null', fullname='修改后的值', sex='null', phone='null', email='null', createtime=null, updatetime=null}]
(5)自定义方法进行查询:
And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd); Or --- 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr); Between --- 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min); LessThan --- 等价于 SQL 中的 "<",比如 findBySalaryLessThan(int max); GreaterThan --- 等价于 SQL 中的">",比如 findBySalaryGreaterThan(int min); IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull(); IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByUsernameIsNotNull(); NotNull --- 与 IsNotNull 等价; Like --- 等价于 SQL 中的 "like",比如 findByUsernameLike(String user); NotLike --- 等价于 SQL 中的 "not like",比如 findByUsernameNotLike(String user); OrderBy --- 等价于 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user); Not --- 等价于 SQL 中的 "! =",比如 findByUsernameNot(String user); In --- 等价于 SQL 中的 "in",比如 findByUsernameIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数; NotIn --- 等价于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
例如:
package cn.qs.dao.user; import cn.qs.bean.user.User; import org.springframework.data.mongodb.repository.MongoRepository; import java.util.List; /** * @Author: qlq * @Description * @Date: 14:29 2019/4/14 */ public interface UserRepository extends MongoRepository<User, Integer> { public User findByUsernameAndFullname(String username,String fullname); public List<User> findByFullnameNot(String fullname); }
测试类:
@Test public void expandMethod(){ User user = userRepository.findByUsernameAndFullname("zhangsan","修改后的值"); System.out.println(user); List<User> users = userRepository.findByFullnameNot("修改后的值"); System.out.println(users); }
结果:
User{id=3, username='zhangsan', password='null', fullname='修改后的值', sex='null', phone='null', email='null', createtime=null, updatetime=null}
[User{id=4, username='zhangsan', password='null', fullname='张三', sex='null', phone='null', email='null', createtime=null, updatetime=null}, User{id=5, username='zhangsan', password='null', fullname='张三', sex='null', phone='null', email='null', createtime=null, updatetime=null}]
解释:
1.Repository 是一个空接口,即是一个标记接口。源码
public interface Repository<T, ID extends Serializable> { }
2.若我们定义的接口实现了 Repository,则该接口会被 IOC 容器识别为一个 Repository Bean,纳入到 IOC 容器中,进而可以在该接口中定义一些符合规范的方法
3.还可以通过 @RepositoryDefinition 注解来替代继承 Repository 接口
4.Repository 接口的实现类:(这都是属于spring data的模块)
1)CrudRepository: 继承 Repository,实现了一组 CRUD 相关的方法
2)PagingAndSortingRepository: 继承 CrudRepository,实现了一组分页排序相关的方法(但是不具备条件筛选功能)
3)自定义的 XxxxRepository 需要继承 PagingAndSortingRepository,这样的 XxxxRepository 接口就具备了通用的数据访问控制层的能力。(一般也会继承QueryByExampleExecutor接口,使分页具备条件查询 )
注: QueryByExampleExecutor: 不属于Repository体系,实现一组 JPA Criteria 查询相关的方法
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.data.repository.query; import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; public interface QueryByExampleExecutor<T> { <S extends T> S findOne(Example<S> var1); <S extends T> Iterable<S> findAll(Example<S> var1); <S extends T> Iterable<S> findAll(Example<S> var1, Sort var2); <S extends T> Page<S> findAll(Example<S> var1, Pageable var2); <S extends T> long count(Example<S> var1); <S extends T> boolean exists(Example<S> var1); }
补充:如果bean的唯一标识是String类型,则insert的时候会自动添加设置id为mongodb的ObjectId
public class User2 { @Id private String id; private String username; private String password; private String fullname; private String sex; private String phone; private String email; private Date createtime; private Date updatetime; ... }
测试插入:
@Test public void insert() { for(int i=0;i<5;i++){ User2 user = new User2(); user.setFullname("张三"); user.setUsername("zhangsan"); userRepository.insert(user); } }
结果:
补充:Page对象封装了分页所需要的全部参数(与普通分页封装类的区别是页号从0开始)