【基于Qt5仿音乐播放器(五)】——数据持久化

发布时间:2026/10/25 1:44:06
【基于Qt5仿音乐播放器(五)】——数据持久化

【基于Qt5仿音乐播放器(五)】——数据持久化

  • 1. 数据库初始化
  • 2. 歌曲信息写入数据库
  • 3. 从数据库中读取

支持播放相关功能之后,每次在验证功能时都需要从磁盘中加载歌曲文件,非常的麻烦。而且之前收藏的喜欢歌曲以及播放记录在程序关闭之后就没有了。因此需要将每次在播放器上进行的操作保留下来,比如:所加载的歌曲、以及歌曲信息;收藏歌曲信息;历史播放等信息保存起来,当下次程序启动时,将保存的信息加载到播放器即可,这样就能将在播放器上的操作记录保留下来了。要永久性保存,最简单的方式就是直接保存到文件,但是保存文件不安全,而且需要自己操作文件比较麻烦,所以我们数据库完成信息的持久保存。

我们采用到了Qt中内置的数据库SQLit——点击转入文章

1. 数据库初始化

// widget.h中新增voidinitSql();private:QSqlDatabase sqlite;// widget.cpp中新增voidWidget::initSql(){sqlite=QSqlDatabase::addDatabase("QSQLITE");sqlite.setDatabaseName("QQMusic.db");// 打开数据库if(!sqlite.open()){QMessageBox::critical(this,"打开数据库失败",sqlite.lastError().text());qDebug()<<"打开数据库失败";return;}qDebug()<<"创建数据库成功";// 创建表QStringsql("CREATE TABLE IF NOT EXISTS musicInfo(\ id INTEGER PRIMARY KEY AUTOINCREMENT,\ musicId varchar(200) UNIQUE,\ musicName varchar(50),\ musicSinger varchar(50),\ albumName varchar(50),\ duration BIGINT,\ musicUrl varchar(256),\ isLike INTEGER,\ isHistory INTEGER)");QSqlQuery query;if(!query.exec(sql)){QMessageBox::critical(this,"打开数据库失败",query.lastError().text());return;}qDebug()<<"创建musicInfo表成功";}

2. 歌曲信息写入数据库

// musiclist.h 中新增// 所有歌曲信息更新到数据库voidwriteToDB();// musiclist.cpp 中新增voidMusicList::writeToDB(){for(automusic:musicList){// 让music对象将⾃⼰写⼊数据库music.insertMusicToDB();}}// music.h 中新增// 将当前Music对象更新到数据库voidinsertMusicToDB();// music.cpp 中新增voidMusic::insertMusicToDB(){QSqlQuery query;// 查看数据库中是否有该音乐query.prepare("select exists (select 1 from musicInfo where musicId = ?)");query.addBindValue(musicId);if(!query.exec()){qDebug()<<"查询失败"<<query.lastError().text();return;}// 获取查询结果if(query.next()){boolisExit=query.value(0).toBool();if(isExit){// 存在,只需要更新isLike和isHistoryquery.prepare("update musicInfo set isLike = ?, isHistory = ? where musicId = ?");query.addBindValue(isLike?1:0);query.addBindValue(isHistory?1:0);query.addBindValue(musicId);if(!query.exec()){qDebug()<<"更新失败"<<query.lastError().text();return;}qDebug()<<"更新music信息: "<<musicName<<" "<<musicId;}else{// 不存在query.prepare("INSERT INTO MusicInfo(musicId, musicName, \ musicSinger, albumName, musicUrl,\ duration, isLike, isHistory)\ VALUES(?,?,?,?,?,?,?,?)");query.addBindValue(musicId);query.addBindValue(musicName);query.addBindValue(musicSinger);query.addBindValue(musicAlbum);query.addBindValue(musicUrl.toLocalFile());query.addBindValue(duration);query.addBindValue(isLike?1:0);query.addBindValue(isHistory?1:0);if(!query.exec()){qDebug()<<"插⼊失败: "<<query.lastError().text();return;}qDebug()<<"插⼊music信息: "<<musicName<<" "<<musicId;}}}//widget.cpp中新增voidWidget::on_quit_clicked(){// 写入数据musicList.writeToDB();// 关闭数据库sqlite.close();// 退出this->close();}

3. 从数据库中读取

在程序启动时,从数据库中读取到歌曲的信息,将歌曲信息设置到musicList中,然后让likePage、localPage、recentPage将musicList中个歌曲更新到各自页面中。从数据库读取歌曲数据的操作,应该让MusicList类完成,因为该类管理所有的Music对象。

// musiclist.h 中新增voidreadFromDB();// musiclist.cpp 中新增voidMusicList::readFromDB(){QStringsql("SELECT musicId, musicName, musicSinger, albumName,\ duration, musicUrl, isLike, isHistory \ FROM musicInfo");QSqlQuery query;if(!query.exec(sql)){qDebug()<<"数据库查询失败";return;}// 获取结果while(query.next()){Music music;music.setMusicId(query.value(0).toString());music.setMusicName(query.value(1).toString());music.setMusicSinger(query.value(2).toString());music.setMusicAlbum(query.value(3).toString());music.setMusicDuration(query.value(4).toLongLong());music.setMusicUrl("file:///"+query.value(5).toString());music.setIsLike(query.value(6).toBool());music.setIsHistory(query.value(7).toBool());musicList.push_back(music);musicPaths.insert(music.getMusicUrl().toLocalFile());}}// widget.h中新增voidinitMusicList();// widget.cpp中新增voidWidget::initMusicList(){musicList.readFromDB();// 这里将原来在initUI中的设置页面类型移至此处ui->likePage->setPageType(PageType::LIKE_PAGE);ui->likePage->reFresh(musicList);ui->localPabe->setPageType(PageType::LOCAL_PAGE);ui->localPabe->reFresh(musicList);ui->recentPage->setPageType(PageType::HISTORY_PAGE);ui->recentPage->reFresh(musicList);}