喜歡就點個贊唄!
源碼<--請點擊此處查看
引入
當我看到一些評論時,例如下面的樣子。我挺好奇這個功能是怎么樣做出來的。進過查閱資料,發現這其實是 MySQL 的遞歸操作。下面就讓我操作一下怎么實現 MySQL 的遞歸查詢。
設計數據庫
觀察這種數據庫設計,你會發現他都有一個父節點,一直到根節點,所以我們設計數據庫的時候,應該設置一個 parentid 字段。所以,我們可以得到以下的數據庫。
sql 腳本如下
CREATE TABLE digui(
id INT(11) NOT null auto_increment,
msg VARCHAR(255) not NULL COMMENT '評論的內容',
parentid int(11) not null COMMENT '上一條',
PRIMARY KEY(id)
)ENGINE=INNODB auto_increment = 100 DEFAULT CHARSET=utf8mb4;
INSERT into `digui`(msg, parentid) VALUES ('A', 0);
INSERT into `digui`(msg, parentid) VALUES('B', 1);
INSERT into `digui`(msg, parentid) VALUES('D', 3);
INSERT into `digui`(msg, parentid) VALUES('C', 2);
其實實現 MySQL 的遞歸查詢方法有很多
- 使用 MySQL 存儲過程
- 應用層代碼遞歸
- MyBatis 的 collection 標簽
方案1 應用層代碼遞歸
//應用層遞歸查詢
@Override
public List<Digui> getAll(int parent) {
List<Digui> deptVosList=new ArrayList<>();
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("parentid", parent);
List<Digui> list1 = list(queryWrapper);
for (Digui digui: list1) {
Digui digui1 = new Digui();
digui1.setId(digui.getId());
digui1.setMsg(digui.getMsg());
digui1.setParentid(digui.getParentid());
// 此處遞歸調用賦值
digui1.setDiguiList(getAll(digui.getId()));
deptVosList.add(digui1);
}
return deptVosList;
}
方案2 MyBatis 的 collection 標簽
<resultMap id="RecursiveMap" type="com.example.lsbdigui.entity.Digui">
<result property="id" column="id"/>
<result property="msg" column="msg"/>
<result property="parentid" column="parentid"/>
<collection property="diguiList" ofType="com.example.lsbdigui.entity.Digui"
select="com.example.lsbdigui.mapper.DiguiMapper.getAllBySQL"
column="id"/>
</resultMap>
<select id="getAllBySQL" resultMap="RecursiveMap">
select *
from digui
where parentid = #{parent}
</select>
使用<collection>
、<select>
標簽實現 sql 遞歸查詢。
結果
{
"code": 200,
"msg": "正確返回",
"date": [
{
"id": 100,
"msg": "A",
"parentid": 0,
"diguiList": [
{
"id": 101,
"msg": "B",
"parentid": 100,
"diguiList": [
{
"id": 103,
"msg": "C",
"parentid": 101,
"diguiList": [
{
"id": 102,
"msg": "D",
"parentid": 103,
"diguiList": []
}
]
}
]
}
]
}
]
}
對比
建議
應用層可以一次查詢全部數據,然后再遞歸找出需要的數據,這樣可以減少數據庫查詢,性能更佳。
參考
- https://blog.rxliuli.com/p/5830226b/
- https://juejin.im/entry/59be34fe5188257e8b36a303
- https://blog.csdn.net/u014079773/article/details/53338116