簡單的研究原生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開始)