MySQL快速入门使用

概念:

SQL 是用于访问和处理数据库的标准的计算机语言。全称为Structured Query Language,即结构化查询语言。

准备工作:

可以按照MySQL 安装教程安装MySQL数据库。

数据库连接工具可以使用HeidiSql

在window cmd下的常用操作:

net start mysql   # 启动服务
net stop mysql    # 停止服务
mysql -u root -p  # 在命令行中连接到数据库
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的新密码';  #修改MySQL密码

语法:

SQL 对大小写不敏感!

可以把 SQL 分为两个部分:数据操作语言 (DML) 和 数据定义语言 (DDL)。

查询和更新指令构成了 SQL 的 DML 部分:

  • SELECT - 从数据库表中获取数据

  • UPDATE - 更新数据库表中的数据

  • DELETE - 从数据库表中删除数据

  • INSERT INTO - 向数据库表中插入数据

SQL 的数据定义语言 (DDL) 部分使我们有能力创建或删除表格。我们也可以定义索引(键),规定表之间的链接,以及施加表间的约束。

SQL 中最重要的 DDL 语句:

  • CREATE DATABASE - 创建新数据库
  • ALTER DATABASE - 修改数据库
  • CREATE TABLE - 创建新表
  • ALTER TABLE - 变更(改变)数据库表
  • DROP TABLE - 删除表
  • CREATE INDEX - 创建索引(搜索键)
  • DROP INDEX - 删除索引

常用语句参考:MySQL 基本语法

C++ API:

使用 MySQL提供的接口时,只需要包含mysql.h这个文件,该文件还包含了其他的头文件,所以项目还需要将其他文件添加进来。

以下是高频使用的C++ API:

mysql_init
mysql_real_connect
mysql_close

mysql_query
mysql_real_query
mysql_store_result
mysql_free_result

mysql_fetch_row


mysql_error

其他的一些接口:

mysql_select_db
mysql_num_rows

示例:

main:

int main(int argc, char **argv)
{
    MySQLDB &db = MySQLDB::getInstance();

    DBInfo dbInfo;
    dbInfo.setDBName("test");
    dbInfo.setHost("localhost");
    dbInfo.setPassword("admin123");
    dbInfo.setPort(3306);
    dbInfo.setUserName("root");
    db.connect(dbInfo);

    db.createDataBase("test");

    db.ROLE(StudentsTable).createTable();
    db.isTableExist("students");

    db.ROLE(StudentsTable).add(Student(11, 1, "daniel", 'M', 90));

    db.ROLE(StudentsTable).modify(Student(11, 1, "daniel", 'M', 95));


    list<Student> students;
    db.ROLE(StudentsTable).getAll(students);
    for (auto &student : students)
    {
        printf("##########");
        student.dump();
        printf("##########");
    }

    db.ROLE(StudentsTable).remove(Student(11, 1, "daniel", 'M', 95));

    db.ROLE(StudentsTable).destoryTable();

    db.disconnect();

    system("pause");
    return 0;
}

MySQLDB:

struct MySQLDB: private StudentsTable
{
    static MySQLDB& getInstance();
    void disconnect();
    bool connect(const DBInfo &dbInfo);
    bool createDataBase(const char *name);
    bool isTableExist(const char *name);
    IMPL_ROLE(StudentsTable)
private:
    MYSQL *getHandle() override;
private:
    MySQLDB();
    MySQLDB(const MySQLDB&);
    MySQLDB& operator=(const MySQLDB&);
private:
    MYSQL *handle;
    DBInfo dbInfo;
};
MySQLDB::MySQLDB() :handle(NULL)
{
 
}

MySQLDB& MySQLDB::getInstance()
{
    static MySQLDB db;
    return db;
}

MYSQL *MySQLDB::getHandle()
{
    return handle;
}

void MySQLDB::disconnect()
{
    mysql_close(handle);
}

bool MySQLDB::connect(const DBInfo &dbInfo)
{
    this->dbInfo = dbInfo;

    handle = new MYSQL();
    if (handle == NULL)
        return false;

    mysql_init(handle);

    bool failed = (mysql_real_connect(handle, dbInfo.host, dbInfo.userName, dbInfo.passWord, NULL, dbInfo.port, NULL, 0) == NULL);
    if (failed)
    {
        printf("connected database failed, error :%s", mysql_error(handle));
        return false;
    }
    //防止乱码。设置和数据库的编码一致就不会乱码
    mysql_query(handle, "set names gbk");
    return true;
}

bool MySQLDB::createDataBase(const char *name)
{
    S8 sql[1024] = { 0 };
    sprintf(sql, "CREATE DATABASE IF NOT EXISTS %s;", name);
    bool succ = (mysql_real_query(handle, sql, strlen(sql) + 1) == 0);
    if (!succ)
    {
        printf("create database failed, %s\n", mysql_error(handle));
        return false;
    }

    sprintf(sql, "USE %s;", name);  //后面操作都在这个数据库里面操作;
    succ = (mysql_real_query(handle, sql, strlen(sql) + 1) == 0);
    if (!succ)
    {
        printf("use database failed, %s\n", mysql_error(handle));
        return false;
    }
    return true;
}

bool MySQLDB::isTableExist(const char *name)
{
    S8 sql[1024] = { 0 };
    sprintf(sql, "SELECT 1 FROM %s.%s", dbInfo.dBName, name);
    bool exist = (mysql_real_query(handle, sql, strlen(sql) + 1) == 0);

    // 以释放目前mysql数据库query返回所占用的内存
    MYSQL_RES* results = mysql_store_result(handle);
    mysql_free_result(results);
    return exist;
}

StudentsTable:

struct Student
{
    Student(int id, int classId, const char* name, char gender, int score)
    {
        this->id = id;
        this->classId = classId;
        strcpy(this->name,name);
        this->gender = gender;
        this->score = score;
    }

    void dump() const
    {
        printf("\nid: %u\n",id);
        printf("class id: %u\n", classId);
        printf("name: %s\n", name);
        printf("gender: %c\n", gender);
        printf("score: %u\n", score);
    }

    void setValue(const MYSQL_ROW& row)
    {
        S32 nIndex = 0;
        this->id = strtoul(row[nIndex++], 0, 10);
        this->classId = strtoul(row[nIndex++], 0, 10);
        strcpy(this->name, row[nIndex++]);
        this->gender = *row[nIndex++];
        this->score = strtoul(row[nIndex], 0, 10);
    }

    Student(){}
    int id;
    int classId;
    char name[100];
    char gender;
    int score;
};

struct StudentsTable
{
    bool createTable();
    bool destoryTable();

    bool add(const Student& s);
    bool remove(const Student& s);
    bool modify(const Student& s);
    bool clear();
    bool getAll(list<Student> &students);
private:
    virtual  MYSQL *getHandle() = 0;
private:
    bool query(const char* sql);
};
bool StudentsTable::query(const char* sql)
{
    MYSQL *handle = getHandle();
    if (handle == NULL)
        return false;

    bool succ = (mysql_query(handle, sql) == 0);
    if (!succ)
    {
        cout << mysql_error(handle) << endl;
    }
    return succ;
}

bool StudentsTable::createTable()
{
    S8 sql[1024] = { 0 };
    sprintf(sql, "CREATE TABLE IF NOT EXISTS students(id BIGINT NOT NULL AUTO_INCREMENT,\
                  class_id BIGINT NOT NULL,\
                  name VARCHAR(100) NOT NULL,\
                  gender VARCHAR(1) NOT NULL,\
                  score INT NOT NULL,\
                  PRIMARY KEY(id));");
    return query(sql);
}

bool StudentsTable::destoryTable()
{
    S8 sql[1024] = { 0 };
    sprintf(sql, "DROP TABLE students");
    return query(sql);
}

bool StudentsTable::add(const Student& s)
{
    S8 sql[1024] = { 0 };
    sprintf(sql, "INSERT INTO students(id, class_id, name, gender, score) VALUES (\
                 %u, %u, '%s', '%c', %u);",\
                 s.id, s.classId, s.name, s.gender, s.score);
    return query(sql);
}

bool StudentsTable::remove(const Student& s)
{
    S8 sql[1024] = { 0 };
    sprintf(sql, "DELETE FROM students WHERE id=%d", s.id);
    return query(sql);
}

bool StudentsTable::modify(const Student& s)
{
    S8 sql[1024] = { 0 };
    sprintf(sql, "UPDATE students SET class_id=%u, name='%s', gender='%c', score=%u WHERE id=%u;",\
            s.classId, s.name, s.gender, s.score, s.id);
    return query(sql);
}

bool StudentsTable::clear()
{
    S8 sql[1024] = { 0 };
    sprintf(sql, "DELETE FROM students;");
    return query(sql);
}


bool StudentsTable::getAll(list<Student> &students)
{
    S8 sql[1024] = { 0 };
    sprintf(sql, "SELECT * FROM students;");

    MYSQL *handle = getHandle();
    if (handle == NULL)
        return false;

    bool succ = (mysql_query(handle, sql) == 0);
    if (!succ)
    {
        cout << mysql_error(handle) << endl;
        return false;
    }

    MYSQL_RES* res = mysql_store_result(handle);
    if (!res)
    {
        return false;
    }

    MYSQL_ROW row;
    Student info;
    while (row = mysql_fetch_row(res))
    {
        info.setValue(row);
        students.push_back(info);
    }
    mysql_free_result(res);
    return true;
}

demo代码链接:https://github.com/yanxicheung/daydayup/tree/main/MySQL/demo

参考文献:

  1. MySQL修改密码
  2. 数据库连接工具介绍
  3. 卸载MySQL数据库
  4. VS中MFC连接MySQL由于系统不同位(32/64)引起的错误:无法解析的外部符号 _mysql_init@4,_mysql_query,_mysql_error
  5. C++连接并使用MySQL数据库
  6. C++操作MYSQL数据库
  7. MySQL 基本语法
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容