又得吐槽一下,最近開發項目,技術leader強調數據庫使用mongodb作爲主數據庫,技術leader認爲mongo完全可以代替mysql(不知道怎麼想的,他mongo都沒用過就下如此結論,苦逼的還是我們這些開發,至於這個leader的水分現在已經無力吐槽)
整了這麼多天mongo,終於知道它不支持多表查詢以及子查詢。網上大多數都是迂迴的一些方法,而且業務稍微複雜之後,幾乎沒人再用mongo做查詢了,畢竟它是非關係型數據庫,雖然有點關係型數據庫的意思,但是術業有專攻,這不是它的強項。
好了下面說一下,基於spring data mongo這個開發,這裏直接上代碼以及說明,mongo的查詢語句就不寫了。
下面兩個實體類
角色實體類
public class Role {
private String id;
private String roleName;
}
用戶實體類
public class User {
private String id;
private String userName;
@DBRef
private Role role;
}
大家應該看到@DBRef這個註解了吧,就是這個,下面是重點,請仔細看:
首先user和role這兩個集合必須存在於mongo數據庫中,你在保存user的時候只需要設置roleid就可以了
public User contextLoads() {
User user = new User();
Role role = new Role();
role.setId("5e0416c0ac8edc3a59d9e58c");
user.setRole(role);
User entity = commonService.saveOrUpdateEntity(user);
return entity;
}
role其他字段不需要set,因爲存到表裏的是這樣的:
它是通過id做了關聯。
role集合數據是這樣的,如果數據庫沒有role這個集合或者role集合中沒有id所在的數據,那麼user集合中的role字段則爲空,所以如果role是內部類的話就會出現set進去爲空的情況。(大家好好理解一下這句話)
接下來需要我們查詢了,我們通過userId查出來的數據會自動講role裏面的數據帶出來,如圖:
我們知道之前設置的時候只設置了role id 但是查詢的時候我們查出了其他字段,這個註解就是這個作用,這樣我們就不用專門設置冗餘字段了,但是問題來了,如果我們想通過roleName這個字段查出user,可以嗎?
答案是不可以,因爲這是單表查詢,數據庫只保存roleid 其他字段不存在user集合表裏,因此是查不出來的,如果想要查,只能將roleName做成冗餘字段,在保存的時候保存進去。
如果有這樣的需求,通過角色roleid查詢用戶user,而且我們用戶表裏面已經有了roleid
我們就可以直接查詢了,基於org.springframework.data.mongodb.core.MongoTemplate;的api實現查詢,java代碼如下:
Query query = new org.springframework.data.mongodb.core.query.Query();
query.addCriteria(Criteria.where("role.$id").is(new ObjectId("5e0416c0ac8edc3a59d9e58c")));
大家注意一下,字段名加點$符號加id,而且id的值需要new ObjectId()包裹,否則查不出來,查出來的結果和上述結果是一樣的。
所以所謂的聯表查詢真的不適合mongo,子查詢同樣也是。大家就不要在折騰了,能換關係數據庫就換吧。