咱們在企業開發中,最經常使用的都是關係型數據庫(oracle、mysql、sqlserver等),這類基於jdbc的數據交互方式,經過在spring中整合mybatis就能實現,本系列文章《Spring系列-實戰篇(4)-你有多瞭解MyBatis 》中就有講解。java
但對於非關係型數據庫,就是常說nosql數據庫,是沒辦法直接用mybatis的,由於它們連sql都沒有,jdbc的本質就是一種用於執行sql語句的java api。本文就是以nosql數據庫中的一員,mongodb爲例。講解mongodb數據庫的特色,以及如何在springboot中實現經常使用的增刪改查。mysql
mongodb是面向文檔的非關係型數據庫,放棄關係模型的主要緣由就是爲了得到更加方便的擴展性,固然優勢不只如此。spring
豐富的數據模型:文檔的鍵(對應關係數據庫中:表的字段)不會事先定義也不會固定不變,開發靈活。字段值的類型豐富,能夠包含其餘文檔,數組及文檔數組,因此用一條記錄就能夠表示很是複雜的層次關係。sql
容易擴展:mongodb從最初設計的時候就考慮到了擴展的問題。它所採用的面向文檔的數據模型使其能夠自動在多臺服務器之間分割數據。它還能夠平衡集羣的數據和負載,自動重排文檔。mongodb
功能豐富:有不少強大的輔助工具,讓mongodb的功能更增強大。(1)能夠不用再在數據庫寫存儲過程了,容許在服務端執行腳本,能夠用Javascript編寫某個函數,直接在服務端執行,也能夠把函數的定義存儲在服務端,下次直接調用便可。(2)大數據應用的支撐也是一大特點,支撐mapreduce和其餘聚合工具。docker
對應第一次接觸mongodb的朋友,我仍是先列出 mysql和mongodb 數據庫的基本概念對比表吧。數據庫
| mysql概念| mongo概念|
| ---- | ---- |
| table (表)| collection (集合)|
| row (記錄行)| document (文檔)|
|column (數據字段)|field (域)|
|index (索引)|index (索引)|
|primary key (主鍵)|自動將_id字段設置爲主鍵|
|table joins (錶鏈接)|不支持|json
上節說到,mongodb是爲分佈式擴展而設計的,在搭建mongo集羣時要考慮不少配置。可是這並不是本文要介紹的內容,本文仍是主要以 springboot+mongodb 的應用爲主。咱們就易於容器環境,最簡單的啓動一個mongodb數據庫。vim
docker run --name domain-mongodb -v /u01/mongo/data/db:/data/db -p 27017:27017 -d mongo
按照上面的命令,就啓動好了一個mongodb,對外映射的端口是 27017。api
就像咱們在用oracle數據庫,習慣用sql/plsql developer客戶端;mysql數據庫,習慣用navicat客戶端;mongodb,我推薦用 robo 3T。robo 3T是免費的,在下載頁面還有個studio 3T 的軟件,那個是商業收費的,固然功能更加豐富。
安裝完成並啓動後,鏈接服務器上的mongodb。就像咱們在mysql數據庫裏面,先建立數據庫,再建立表同樣。咱們先建立集合,再建立文檔,注意,mongodb不須要預設表結構,因此只要填文檔的名字就行。以下圖,建立了 portal集合下的三個文檔,分別是oauth_client、oauth_config、user。
接下來會以在springboot中,實現對用戶信息的操做接口爲例,講解如何實現對mongodb數據最簡單的增刪改查。
pom.xml
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> <version>2.0.3.RELEASE</version> </dependency>
application.yml
spring: data: mongodb: uri: mongodb://ip:port/集合名
先建立一個pojo類,UserEO.java,對應以前mongodb裏面的建立的user文檔,這裏有幾個知識點。
@Document(collection = "user") public class UserEO { private String username; private String password; private String name; /** * 建立時間 */ @JsonFormat(pattern="yyyy.MM.dd HH:mm:ss",timezone = "GMT+8") @Field("creation_date") private Date creationDate; /** * UserBookEO類:name,price,amount */ private List<UserBookEO> bookList; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Date getCreationDate() { return creationDate; } public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } public List<UserBookEO> getBookList() { return bookList; } public void setBookList(List<UserBookEO> bookList) { this.bookList = bookList; } }
dao 層的操做主要依賴於MongoTemplate 的實現,下列代碼中已經列出最經常使用的增刪改爲以及分頁查詢,更多的高級用法,能夠去官網看MongoTemplate的源碼實現。
@Component public class PaasDao { @Autowired private MongoTemplate mongoTemplate; /** * 分頁查詢user * * @param key * @return */ public List<UserEO> queryUsers(String key, int page, int pageSize) { Query query = new Query(); Criteria criteriaUsername = Criteria.where("username").regex(key); Criteria criteriaName = Criteria.where("name").regex(key); query.addCriteria(new Criteria().orOperator(criteriaUsername, criteriaName)); //分頁 Sort sort=new Sort(Sort.Direction.DESC, "creation_date"); Pageable pageable=PageRequest.of(page-1,pageSize,sort); query.with(pageable); return mongoTemplate.find(query, UserEO.class); } /** * 刪除client * * @param username */ public void deleteUser(String username) { Query query = new Query(Criteria.where("username").is(username)); mongoTemplate.remove(query, UserEO.class); } /** * 新增client * * @param user */ public void addUser(UserEO user) { user.setCreationDate(new Date()); mongoTemplate.save(user); } /** * 更新user * * @param user */ public void updateUser(UserEO user) { Query query = new Query(Criteria.where("username").is(user.getUsername())); Update update = new Update().set("password", user.getPassword()) .set("name",user.getName()); mongoTemplate.updateFirst(query, update, UserEO.class); } /** * 查詢存在某username的數量 * * @param username * @return */ public long countUsername(String username) { Query query = new Query(Criteria.where("username").is(username)); return mongoTemplate.count(query, UserEO.class); } }
controller層就沒有太多可展現的了,我就簡單的拿新增和查詢兩個接口來作個測試吧。
@RestController @RequestMapping(value = "/paas") public class PaasController { @Autowired private PaasDao paasDao; /** * 用戶(user)- 查詢用戶 * * @param request * @return */ @RequestMapping(value = "/user/queryUsers", method = RequestMethod.POST) public Response queryUsers(@RequestBody Map<String, Object> request) { Integer page = (Integer) request.get("page"); Integer pageSize = (Integer) request.get("pageSize"); String key = request.get("key") == null ? "" : (String) request.get("key"); List<UserEO> userEOList=paasDao.queryUsers(key,page,pageSize); long userCount=paasDao.countUsers(key); PageQueryResult<UserEO> pageQueryResult = new PageQueryResult<>(userCount,userEOList); return Response.ok().data(pageQueryResult); } /** * 用戶(user)- 新增用戶 * * @param userEO * @return */ @RequestMapping(value = "/user/addUser", method = RequestMethod.POST) public Response addUser(@RequestBody UserEO userEO) { paasDao.addUser(userEO); return Response.ok(); }
經過新增接口,咱們分別傳入兩組數據:
//第一組數據 { "username":"kerry", "password":"kerry", "name":"吳晨瑞" } //第二組數據 { "username":"tony", "password":"tony", "name":"託尼", "bookList":[ { "name":"紅樓夢", "price":20, "amount":1 }, { "name":"三個火槍手", "price":10, "amount":2 } ] }
插入成功後,咱們經過robo 3T 查詢一下數據庫,驗證數據確實插入成功。
接下來再調用查詢接口,返回結果以下:
{ "code":"ok", "data":{ "count":2, "result":[ { "username":"tony", "password":"tony", "name":"託尼", "creationDate":"2019.11.17 16:29:34", "bookList":[ { "name":"紅樓夢", "price":20, "amount":1 }, { "name":"三個火槍手", "price":10, "amount":2 } ] }, { "username":"kerry", "password":"kerry", "name":"吳晨瑞", "creationDate":"2019.10.30 10:53:55" } ] }, "requestid":"e80b71d50c9e45e9bffa3bd0b2abf446" }
OK,在springboot框架下,基於mongodb的接口開發,看上去並不困難。